@adia-ai/adia-ui-forge 0.8.59 → 0.8.61
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/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/CHANGELOG.md +68 -0
- package/package.json +1 -1
- package/plugin.yaml +1 -1
- package/references/contracts/a2ui-mcp-surface.md +1 -1
- package/scripts/lint-rules.generated.mjs +2418 -359
- package/skills/a2ui-maintenance/references/eval-diagnostics.md +2 -2
- package/skills/a2ui-maintenance/references/pipeline-overview.md +26 -0
- package/skills/a2ui-maintenance/references/strategy-engines.md +12 -0
- package/skills/demo-audit/references/admin-shell-anatomy.md +18 -12
- package/skills/gen-ui-review/scripts/gen-review-decompose.mjs +27 -34
- package/skills/gen-ui-review/scripts/overflow-detect.generated.mjs +101 -0
- package/skills/package-release/references/cut-procedure.md +49 -5
- package/skills/package-release/references/recovery-paths.md +20 -0
- package/skills/package-release/scripts/bump.mjs +36 -6
- package/skills/package-release/scripts/dispatch-publish.mjs +8 -0
- package/skills/package-release/scripts/gate-roster.mjs +4 -4
- package/skills/package-release/scripts/release-pack.mjs +485 -68
- package/skills/package-release/scripts/stale-copy-warning.mjs +215 -0
- package/skills/package-release/scripts/tag-lockstep.mjs +8 -0
- package/skills/primitive-authoring/references/INDEX.md +1 -0
- package/skills/primitive-authoring/references/examples-structure.md +52 -0
- package/skills/primitive-authoring/references/shell-patterns.md +12 -11
- package/skills/primitive-authoring/references/token-contract.md +2 -2
- package/skills/primitive-authoring/references/yaml-contract.md +106 -9
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// GENERATED
|
|
2
|
-
// scripts/lint/engine/primitives.mjs, scripts/lint/engine/run.mjs
|
|
1
|
+
// GENERATED, do not hand-edit. Sources:
|
|
2
|
+
// scripts/lint/engine/primitives.mjs, scripts/lint/engine/run.mjs, scripts/lint/engine/baseline.mjs
|
|
3
3
|
// scripts/lint/rules/consumer/genui-doc.mjs
|
|
4
4
|
// scripts/lint/rules/consumer/hardcoded-open.mjs
|
|
5
5
|
// scripts/lint/rules/consumer/llm-key-in-client.mjs
|
|
@@ -13,11 +13,16 @@
|
|
|
13
13
|
// scripts/lint/rules/generated/composition/action-list.mjs
|
|
14
14
|
// scripts/lint/rules/generated/composition/admin-command.mjs
|
|
15
15
|
// scripts/lint/rules/generated/composition/admin-content.mjs
|
|
16
|
-
// scripts/lint/rules/generated/composition/admin-
|
|
16
|
+
// scripts/lint/rules/generated/composition/admin-entity-item.mjs
|
|
17
|
+
// scripts/lint/rules/generated/composition/admin-roster.mjs
|
|
18
|
+
// scripts/lint/rules/generated/composition/admin-settings.mjs
|
|
17
19
|
// scripts/lint/rules/generated/composition/admin-shell.mjs
|
|
18
20
|
// scripts/lint/rules/generated/composition/admin-sidebar.mjs
|
|
19
21
|
// scripts/lint/rules/generated/composition/admin-statusbar.mjs
|
|
20
22
|
// scripts/lint/rules/generated/composition/admin-topbar.mjs
|
|
23
|
+
// scripts/lint/rules/generated/composition/agent-admin.mjs
|
|
24
|
+
// scripts/lint/rules/generated/composition/avatar-group.mjs
|
|
25
|
+
// scripts/lint/rules/generated/composition/chat-composer.mjs
|
|
21
26
|
// scripts/lint/rules/generated/composition/chat-empty.mjs
|
|
22
27
|
// scripts/lint/rules/generated/composition/chat-header.mjs
|
|
23
28
|
// scripts/lint/rules/generated/composition/chat-shell.mjs
|
|
@@ -34,18 +39,30 @@
|
|
|
34
39
|
// scripts/lint/rules/generated/composition/editor-sidebar.mjs
|
|
35
40
|
// scripts/lint/rules/generated/composition/editor-statusbar.mjs
|
|
36
41
|
// scripts/lint/rules/generated/composition/editor-toolbar.mjs
|
|
42
|
+
// scripts/lint/rules/generated/composition/embed-shell.mjs
|
|
37
43
|
// scripts/lint/rules/generated/composition/feed-item.mjs
|
|
38
44
|
// scripts/lint/rules/generated/composition/feed.mjs
|
|
45
|
+
// scripts/lint/rules/generated/composition/fields.mjs
|
|
46
|
+
// scripts/lint/rules/generated/composition/footer.mjs
|
|
47
|
+
// scripts/lint/rules/generated/composition/form-popover.mjs
|
|
48
|
+
// scripts/lint/rules/generated/composition/header.mjs
|
|
39
49
|
// scripts/lint/rules/generated/composition/list-item.mjs
|
|
40
50
|
// scripts/lint/rules/generated/composition/menu-divider.mjs
|
|
41
51
|
// scripts/lint/rules/generated/composition/menu-item.mjs
|
|
42
52
|
// scripts/lint/rules/generated/composition/menu-label.mjs
|
|
53
|
+
// scripts/lint/rules/generated/composition/menu.mjs
|
|
54
|
+
// scripts/lint/rules/generated/composition/nav-group.mjs
|
|
55
|
+
// scripts/lint/rules/generated/composition/nav-item.mjs
|
|
43
56
|
// scripts/lint/rules/generated/composition/page-scroll.mjs
|
|
57
|
+
// scripts/lint/rules/generated/composition/radio-group.mjs
|
|
58
|
+
// scripts/lint/rules/generated/composition/search.mjs
|
|
59
|
+
// scripts/lint/rules/generated/composition/section.mjs
|
|
44
60
|
// scripts/lint/rules/generated/composition/segment.mjs
|
|
45
61
|
// scripts/lint/rules/generated/composition/segmented.mjs
|
|
46
62
|
// scripts/lint/rules/generated/composition/simple-content.mjs
|
|
47
63
|
// scripts/lint/rules/generated/composition/simple-hero.mjs
|
|
48
64
|
// scripts/lint/rules/generated/composition/simple-shell.mjs
|
|
65
|
+
// scripts/lint/rules/generated/composition/skip-nav.mjs
|
|
49
66
|
// scripts/lint/rules/generated/composition/stepper-item.mjs
|
|
50
67
|
// scripts/lint/rules/generated/composition/stepper.mjs
|
|
51
68
|
// scripts/lint/rules/generated/composition/tab.mjs
|
|
@@ -61,6 +78,7 @@
|
|
|
61
78
|
// scripts/lint/rules/generated/lab-posture/internal-tier.mjs
|
|
62
79
|
// scripts/lint/rules/generated/lab-posture/required-attr.mjs
|
|
63
80
|
// scripts/lint/rules/generated/lab-posture/unknown-attr.mjs
|
|
81
|
+
// scripts/lint/rules/generated/lab-posture/unknown-slot.mjs
|
|
64
82
|
// scripts/lint/rules/generated/lab-posture/unknown-tag.mjs
|
|
65
83
|
// scripts/lint/rules/genui-output/anti-patterns.mjs
|
|
66
84
|
// scripts/lint/rules/shared/attr-typo.mjs
|
|
@@ -69,8 +87,10 @@
|
|
|
69
87
|
// scripts/lint/rules/shared/dead-font-token.mjs
|
|
70
88
|
// scripts/lint/rules/shared/example-id-grammar.mjs
|
|
71
89
|
// scripts/lint/rules/shared/example-prop-contract.mjs
|
|
90
|
+
// scripts/lint/rules/shared/img-dimension-reserve.mjs
|
|
72
91
|
// scripts/lint/rules/shared/legacy-shell.mjs
|
|
73
92
|
// scripts/lint/rules/shared/native-primitive.mjs
|
|
93
|
+
// scripts/lint/rules/shared/no-local-escape-html.mjs
|
|
74
94
|
// scripts/lint/rules/shared/raw-color.mjs
|
|
75
95
|
// scripts/lint/rules/shared/raw-px.mjs
|
|
76
96
|
// scripts/lint/rules/shared/scope-extent.mjs
|
|
@@ -198,8 +218,24 @@ function lineOf(text, offset) {
|
|
|
198
218
|
return n;
|
|
199
219
|
}
|
|
200
220
|
|
|
201
|
-
/**
|
|
202
|
-
|
|
221
|
+
/**
|
|
222
|
+
* Suppression comment recognized on the line itself or the line before a finding.
|
|
223
|
+
*
|
|
224
|
+
* gh#3715: the reason separator accepts an em dash, a colon, or a
|
|
225
|
+
* space-padded hyphen. It used to accept ONLY the em dash, which collided
|
|
226
|
+
* head-on with `check:em-dash-added-lines` (gh#3767): that gate forbids an
|
|
227
|
+
* em dash on any added line, so obeying it made a reasoned suppression
|
|
228
|
+
* impossible to write. Worse, the failure was silent rather than loud. A
|
|
229
|
+
* hyphen did not merely lose the reason, it made the WHOLE directive fail
|
|
230
|
+
* to match, so the suppression quietly did nothing and the finding stayed
|
|
231
|
+
* live with no diagnostic anywhere.
|
|
232
|
+
*
|
|
233
|
+
* The hyphen form requires whitespace on both sides. Rule ids contain
|
|
234
|
+
* hyphens themselves (SHELL-RESIZE), and the id class is greedy, so a bare
|
|
235
|
+
* `-` with no padding would be ambiguous with the id it follows.
|
|
236
|
+
*/
|
|
237
|
+
const SUPPRESS_RE =
|
|
238
|
+
/\/\*\s*adia-lint-disable\s+([A-Z0-9-]+)(?:(?:\s*[\u2014:]\s*|\s+-\s+)(.*?))?\s*\*\//;
|
|
203
239
|
|
|
204
240
|
/** Given all raw lines and a finding's line number, is it suppressed, and was a reason given? */
|
|
205
241
|
function suppressionFor(rawLines, lineNo, ruleId) {
|
|
@@ -230,6 +266,47 @@ function allSuppressions(rawLines) {
|
|
|
230
266
|
return out;
|
|
231
267
|
}
|
|
232
268
|
|
|
269
|
+
/**
|
|
270
|
+
* Loose match for anything that READS as a suppression-directive comment:
|
|
271
|
+
* opens `/* adia-lint-disable`, closes on the same line, regardless of
|
|
272
|
+
* whether its body satisfies SUPPRESS_RE's own strict grammar. Deliberately
|
|
273
|
+
* permissive: the only anchor is the shared prefix both regexes start on,
|
|
274
|
+
* so any separator/id/reason shape SUPPRESS_RE would refuse still gets
|
|
275
|
+
* caught here.
|
|
276
|
+
*/
|
|
277
|
+
const LOOSE_SUPPRESS_RE = /\/\*\s*adia-lint-disable\b.*?\*\//g;
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* gh#4161: SUPPRESS_RE is both matcher and detector, so a directive it
|
|
281
|
+
* refuses produces no suppression, no SUPPRESS-NO-REASON, and no
|
|
282
|
+
* diagnostic anywhere, silently invisible. gh#3868 fixed the hyphen-
|
|
283
|
+
* separator case and gh#3871 swept existing inert directives; neither
|
|
284
|
+
* closed the general class. This is the loose scan that closes it: every
|
|
285
|
+
* candidate suppression-directive comment (per LOOSE_SUPPRESS_RE above)
|
|
286
|
+
* that the STRICT regex refuses to parse, one entry per hit, naming the
|
|
287
|
+
* line and a trimmed snippet, so the engine (run.mjs) can turn each into a
|
|
288
|
+
* SUPPRESS-MALFORMED (warn) finding.
|
|
289
|
+
*
|
|
290
|
+
* `strictRe` is injectable (defaults to the live SUPPRESS_RE) so a test can
|
|
291
|
+
* prove this scan against a narrower, superseded grammar too, e.g.
|
|
292
|
+
* gh#3868's own pre-fix, em-dash-only regex, not only today's.
|
|
293
|
+
*/
|
|
294
|
+
function malformedSuppressions(rawLines, strictRe = SUPPRESS_RE) {
|
|
295
|
+
const out = [];
|
|
296
|
+
rawLines.forEach((line, idx) => {
|
|
297
|
+
LOOSE_SUPPRESS_RE.lastIndex = 0;
|
|
298
|
+
let m;
|
|
299
|
+
while ((m = LOOSE_SUPPRESS_RE.exec(line))) {
|
|
300
|
+
const candidate = m[0];
|
|
301
|
+
const re = new RegExp(strictRe.source);
|
|
302
|
+
if (!re.test(candidate)) {
|
|
303
|
+
out.push({ lineNo: idx + 1, snippet: candidate.trim().slice(0, 90) });
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
return out;
|
|
308
|
+
}
|
|
309
|
+
|
|
233
310
|
const RE = {
|
|
234
311
|
HEXCOLOR: /#[0-9a-fA-F]{3,8}\b/,
|
|
235
312
|
FUNCCOLOR: /\b(?:rgba?|hsla?|oklch|oklab|lab|lch)\s*\(/,
|
|
@@ -238,12 +315,17 @@ const RE = {
|
|
|
238
315
|
BOOL_TRUE: /\bdefault:\s*true\b/,
|
|
239
316
|
ATTR_TYPO: /\battr:\s*['"]/,
|
|
240
317
|
NATIVE_PRIMITIVE: /<(?:button|input|select|textarea|dialog)(?![\w-])/,
|
|
241
|
-
LEGACY_SHELL:
|
|
318
|
+
LEGACY_SHELL: /^(?:data-chat-(?:messages|input|empty|name)|data-editor-body|data-canvas|data-sidebar|data-pane-(?:side|grow))$/,
|
|
242
319
|
PX_GE: /(?<![\w.-])(\d+)px\b/g,
|
|
243
320
|
SELECTOR_RULE: /^\s*[.#:[&\w][^{}\n]*\{/m,
|
|
244
321
|
SSR_SIGNAL: /['"]use client['"]|\buseEffect\b|\bonMounted\b|\bonMount\b|from\s+['"](?:react|vue|svelte|next|nuxt|@sveltejs|astro)|getServerSideProps|defineNuxtComponent/i,
|
|
245
322
|
TOPLEVEL_IMPORT: /^\s*import\s+['"]@adia-ai\/web-components['"]\s*;?\s*$/m,
|
|
246
323
|
OVERLAY_OPEN: /<(?:modal|drawer)-ui\b[^>]*?(?<![:.\w])\bopen\b(?!\s*=\s*\{)/,
|
|
324
|
+
// gh#3888: a real @scope at-rule opening, never a bare substring match
|
|
325
|
+
// on the word "@scope" (which also matches prose in a comment, the
|
|
326
|
+
// exact loophole this fixes: MISSING-SCOPE's old `text.includes('@scope')`
|
|
327
|
+
// passed any file whose comments merely mentioned the word).
|
|
328
|
+
SCOPE_BLOCK: /@scope\s*\(/,
|
|
247
329
|
};
|
|
248
330
|
|
|
249
331
|
/** Per-declaration split on `;` — mirrors both Python scripts' `line.split(';')` loops. */
|
|
@@ -385,9 +467,18 @@ const VOID_TAGS = new Set([
|
|
|
385
467
|
* are flushed as-is) so a small fixture snippet never throws.
|
|
386
468
|
*
|
|
387
469
|
* Returns one node per open (or self-closing/void) tag, in document
|
|
388
|
-
* order: `{ tag, parentTag, line, childTags }
|
|
389
|
-
*
|
|
390
|
-
* the
|
|
470
|
+
* order: `{ tag, parentTag, line, childTags }`. `parentTag` is the
|
|
471
|
+
* nearest CUSTOM-ELEMENT ancestor (gh#3310) — the stack is walked from
|
|
472
|
+
* the top down past any native, non-hyphenated wrapper tag (`section`,
|
|
473
|
+
* `div`, `td`, `tr`, `tbody`, ...; the Custom Elements naming
|
|
474
|
+
* requirement means no native HTML tag is ever hyphenated, so "contains
|
|
475
|
+
* a hyphen" is the discriminator, not an allowlist) to the first
|
|
476
|
+
* hyphenated frame, and is `'ROOT'` if the walk empties the stack
|
|
477
|
+
* without finding one (the A2UI "Surface" case). `childTags` is the
|
|
478
|
+
* ordered list of DIRECT children only (not descendants, and not
|
|
479
|
+
* ancestor-walked — `allowedChildren` matching stays direct-children-only),
|
|
480
|
+
* each a `{ tag, slot }` pair (`slot` is `null` for a default-slot child —
|
|
481
|
+
* gh#3308, compositionFindings' own slot-aware allowedChildren check).
|
|
391
482
|
*
|
|
392
483
|
* gh#2937: `makeLinter`'s `lintText` calls every active rule's `match()`
|
|
393
484
|
* with the SAME `text` string for one file — and each of the ~48
|
|
@@ -401,16 +492,34 @@ const VOID_TAGS = new Set([
|
|
|
401
492
|
* the next file is a single cache miss that recomputes and replaces
|
|
402
493
|
* the slot — no manual invalidation, no unbounded growth.
|
|
403
494
|
*/
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
495
|
+
// gh#3310: the Custom Elements spec requires a hyphen in every custom
|
|
496
|
+
// tag name, so "contains a hyphen" is a definitional discriminator for
|
|
497
|
+
// "is a catalog component" — no native HTML tag is ever hyphenated, and
|
|
498
|
+
// no allowlist of "transparent" wrapper tags needs maintaining.
|
|
499
|
+
function nearestCustomElementAncestor(stack) {
|
|
500
|
+
for (let i = stack.length - 1; i >= 0; i -= 1) {
|
|
501
|
+
if (stack[i].tag.includes('-')) return stack[i].tag;
|
|
502
|
+
}
|
|
503
|
+
return 'ROOT';
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
let _tagTreeCache = { text: null, path: null, nodes: null };
|
|
507
|
+
// gh#3492: scans `markupScanSurface(text, path)`'s blanked output, not raw
|
|
508
|
+
// `text`. A `<!-- ... -->` comment naming a real tag in prose (a
|
|
509
|
+
// "Pattern source:" doc header) was previously read as live markup, and
|
|
510
|
+
// the comment's missing closing tag left every REAL element after it
|
|
511
|
+
// folded into a phantom nesting context. Blanking (not deleting) keeps
|
|
512
|
+
// line numbers aligned, same guarantee `tagOccurrences` already relies on.
|
|
513
|
+
function tagTree(text, path = '') {
|
|
514
|
+
if (_tagTreeCache.text === text && _tagTreeCache.path === path) return _tagTreeCache.nodes;
|
|
515
|
+
const surface = markupScanSurface(text, path);
|
|
407
516
|
const nodes = [];
|
|
408
|
-
const stack = []; // { tag, parentTag, line, children:
|
|
517
|
+
const stack = []; // { tag, parentTag, line, children: {tag, slot}[] }
|
|
409
518
|
TAG_TOKEN_RE.lastIndex = 0;
|
|
410
519
|
let m;
|
|
411
|
-
while ((m = TAG_TOKEN_RE.exec(
|
|
412
|
-
const [, closing, tag, , selfClose] = m;
|
|
413
|
-
const line = lineOf(
|
|
520
|
+
while ((m = TAG_TOKEN_RE.exec(surface))) {
|
|
521
|
+
const [, closing, tag, attrString, selfClose] = m;
|
|
522
|
+
const line = lineOf(surface, m.index);
|
|
414
523
|
if (closing) {
|
|
415
524
|
let at = -1;
|
|
416
525
|
for (let i = stack.length - 1; i >= 0; i -= 1) {
|
|
@@ -422,8 +531,8 @@ function tagTree(text) {
|
|
|
422
531
|
stack.length = at; // pop this frame and any unclosed frames above it
|
|
423
532
|
continue;
|
|
424
533
|
}
|
|
425
|
-
const parentTag = stack
|
|
426
|
-
if (stack.length) stack[stack.length - 1].children.push(tag);
|
|
534
|
+
const parentTag = nearestCustomElementAncestor(stack);
|
|
535
|
+
if (stack.length) stack[stack.length - 1].children.push({ tag, slot: parseAttrs(attrString).slot ?? null });
|
|
427
536
|
if (selfClose || VOID_TAGS.has(tag.toLowerCase())) {
|
|
428
537
|
nodes.push({ tag, parentTag, line, childTags: [] });
|
|
429
538
|
} else {
|
|
@@ -434,7 +543,7 @@ function tagTree(text) {
|
|
|
434
543
|
const frame = stack.pop();
|
|
435
544
|
nodes.push({ tag: frame.tag, parentTag: frame.parentTag, line: frame.line, childTags: frame.children });
|
|
436
545
|
}
|
|
437
|
-
_tagTreeCache = { text, nodes };
|
|
546
|
+
_tagTreeCache = { text, path, nodes };
|
|
438
547
|
return nodes;
|
|
439
548
|
}
|
|
440
549
|
|
|
@@ -446,10 +555,26 @@ function tagTree(text) {
|
|
|
446
555
|
* string/tree matcher with no registry lookup at match-time, same as
|
|
447
556
|
* every other rule). The reserved catalog name `'Surface'` in
|
|
448
557
|
* `allowedParents` matches a `parentTag === 'ROOT'` occurrence.
|
|
558
|
+
*
|
|
559
|
+
* gh#3308: `allowedChildren` applies to default-slot children only — a
|
|
560
|
+
* child carrying ANY `slot=` attribute (menu-ui's `slot=trigger`,
|
|
561
|
+
* context-menu-ui's wrap-mode target) is a sibling-level named slot whose
|
|
562
|
+
* content is deliberately unconstrained by the component's own source, not
|
|
563
|
+
* a default-slot member subject to the roster check. `allowedChildrenBySlot`
|
|
564
|
+
* is the opt-in per-slot roster for the rare case a named slot DOES want
|
|
565
|
+
* constraining — a slot absent from that map (or the map itself absent)
|
|
566
|
+
* stays exempt by design, same as an unconstrained default slot.
|
|
567
|
+
*
|
|
568
|
+
* gh#3492: `path` is optional and defaults to `''`. Every current caller
|
|
569
|
+
* (the generated `COMPOSITION-*` rules) has no path to give, and doesn't
|
|
570
|
+
* need one: `tagTree()`'s HTML-comment blanking runs unconditionally
|
|
571
|
+
* regardless of path, only its `.vue`-template scoping depends on it.
|
|
449
572
|
*/
|
|
450
|
-
function compositionFindings(text, { tag, allowedParents, allowedChildren }) {
|
|
573
|
+
function compositionFindings(text, { tag, allowedParents, allowedChildren, allowedChildrenBySlot, path = '' }) {
|
|
451
574
|
const out = [];
|
|
452
|
-
|
|
575
|
+
const hasChildRule = (allowedChildren && allowedChildren.length)
|
|
576
|
+
|| (allowedChildrenBySlot && Object.keys(allowedChildrenBySlot).length);
|
|
577
|
+
for (const node of tagTree(text, path)) {
|
|
453
578
|
if (node.tag !== tag) continue;
|
|
454
579
|
if (allowedParents && allowedParents.length) {
|
|
455
580
|
const parentOk = node.parentTag === 'ROOT'
|
|
@@ -464,13 +589,26 @@ function compositionFindings(text, { tag, allowedParents, allowedChildren }) {
|
|
|
464
589
|
});
|
|
465
590
|
}
|
|
466
591
|
}
|
|
467
|
-
if (
|
|
592
|
+
if (hasChildRule) {
|
|
468
593
|
for (const child of node.childTags) {
|
|
469
|
-
if (
|
|
594
|
+
if (child.slot) {
|
|
595
|
+
const slotAllowed = allowedChildrenBySlot && allowedChildrenBySlot[child.slot];
|
|
596
|
+
if (!slotAllowed) continue; // named slot left unconstrained by design
|
|
597
|
+
if (!slotAllowed.includes(child.tag)) {
|
|
598
|
+
out.push({
|
|
599
|
+
line: node.line,
|
|
600
|
+
snippet: `<${tag} slot="${child.slot}"> > <${child.tag}>`,
|
|
601
|
+
why: `<${tag}> declares a2ui.allowedChildrenBySlot.${child.slot}: [${slotAllowed.join(', ')}] — <${child.tag}> is not one of them`,
|
|
602
|
+
});
|
|
603
|
+
}
|
|
604
|
+
continue;
|
|
605
|
+
}
|
|
606
|
+
if (!allowedChildren || !allowedChildren.length) continue; // default slot unconstrained
|
|
607
|
+
if (!allowedChildren.includes(child.tag)) {
|
|
470
608
|
out.push({
|
|
471
609
|
line: node.line,
|
|
472
|
-
snippet: `<${tag}> > <${child}>`,
|
|
473
|
-
why: `<${tag}> declares a2ui.allowedChildren: [${allowedChildren.join(', ')}] — <${child}> is not one of them`,
|
|
610
|
+
snippet: `<${tag}> > <${child.tag}>`,
|
|
611
|
+
why: `<${tag}> declares a2ui.allowedChildren: [${allowedChildren.join(', ')}] — <${child.tag}> is not one of them`,
|
|
474
612
|
});
|
|
475
613
|
}
|
|
476
614
|
}
|
|
@@ -660,6 +798,32 @@ function markupScanSurface(text, path = '') {
|
|
|
660
798
|
return surface;
|
|
661
799
|
}
|
|
662
800
|
|
|
801
|
+
const CSS_COMMENT_RE = /\/\*[\s\S]*?(?:\*\/|$)/g;
|
|
802
|
+
|
|
803
|
+
/**
|
|
804
|
+
* gh#4008: the text `RE.SCOPE_BLOCK` (MISSING-SCOPE) actually tests, BLANKING
|
|
805
|
+
* (not deleting: line numbers must survive) every `/* ... *\/` CSS comment
|
|
806
|
+
* range the same way `markupScanSurface`'s HTML_COMMENT_RE already blanks
|
|
807
|
+
* markup comments above. gh#3888 closed "`@scope` appearing only in a bare
|
|
808
|
+
* word inside a comment must not satisfy MISSING-SCOPE" by switching the
|
|
809
|
+
* rule's substring test to a real at-rule regex (`/@scope\s*\(/`), but never
|
|
810
|
+
* blanked the comment itself, so a comment that carries the FULL pattern,
|
|
811
|
+
* `/* @scope (admin-shell) *\/`, still matches the same regex the raw-text
|
|
812
|
+
* word never could. An unterminated comment blanks to end-of-file, mirroring
|
|
813
|
+
* `markupScanSurface`'s own behavior for an unterminated `<!--`.
|
|
814
|
+
*
|
|
815
|
+
* Only used where a real, live at-rule (or declaration) is what the caller
|
|
816
|
+
* means to detect, NOT a general-purpose "strip all CSS comments" helper.
|
|
817
|
+
* `isFoundationCss`'s `/* forge-lint: foundation *\/` opt-in tag and
|
|
818
|
+
* missing-scope.mjs's own `PREFIX_SCOPED_RE` are deliberately read straight
|
|
819
|
+
* out of raw text instead: those tags are AUTHORED inside a comment on
|
|
820
|
+
* purpose, so blanking comments before reading them would break the very
|
|
821
|
+
* mechanism they are.
|
|
822
|
+
*/
|
|
823
|
+
function cssCommentBlankedSurface(text) {
|
|
824
|
+
return text.replace(CSS_COMMENT_RE, (m) => m.replace(/[^\n]/g, ' '));
|
|
825
|
+
}
|
|
826
|
+
|
|
663
827
|
/**
|
|
664
828
|
* ADR-0108 D5 / LLD-0019 C5: builds lookup tables from a manifest object
|
|
665
829
|
* shaped like `packages/gen-ui/mcp/factory/manifest.js`'s `getManifest()`
|
|
@@ -950,6 +1114,46 @@ function requiredAttrFindings(text, manifest, path = '') {
|
|
|
950
1114
|
return out;
|
|
951
1115
|
}
|
|
952
1116
|
|
|
1117
|
+
/**
|
|
1118
|
+
* UNKNOWN-SLOT (gh#3222): a `slot="…"` value that is not a slot name ANY
|
|
1119
|
+
* component in the manifest declares. `manifest` here is the flat
|
|
1120
|
+
* `{ slotNames: [...] }` shape `trimForEmbed`'s own `'slot-names'` branch
|
|
1121
|
+
* produces (gen-lab-posture-rules.mjs) — not the per-tag `{ components }`
|
|
1122
|
+
* shape `buildManifestIndex` reads for the other five rules.
|
|
1123
|
+
*
|
|
1124
|
+
* Deliberately NOT a per-tag/nearest-ancestor check the way UNKNOWN-ATTR
|
|
1125
|
+
* validates an attribute against its own element's tag: Light DOM's
|
|
1126
|
+
* `slot=` is decorative metadata this kit's own component JS reads with
|
|
1127
|
+
* an unscoped selector, so the element carrying `slot="action"` is
|
|
1128
|
+
* routinely a `<header>`'s own descendant rather than a direct child of
|
|
1129
|
+
* the component that actually declares the `action` slot
|
|
1130
|
+
* (card.examples.html's `<header><span slot="heading">…` — `heading` is
|
|
1131
|
+
* `card-ui`'s slot, two levels down from `<card-ui>` itself, past a plain
|
|
1132
|
+
* `<header>` wrapper with no manifest entry of its own). Reliably finding
|
|
1133
|
+
* the "owning" tag would need a nearest-kit-ancestor tree walk that is
|
|
1134
|
+
* fragile against exactly this shape; checking the NAME against the
|
|
1135
|
+
* manifest-wide vocabulary instead still catches the real failure mode
|
|
1136
|
+
* (a generator inventing a slot name no component anywhere declares)
|
|
1137
|
+
* without that fragility — the same "name only, never placement" scope
|
|
1138
|
+
* this primitive's own callers document.
|
|
1139
|
+
*/
|
|
1140
|
+
function slotNameFindings(text, manifest, path = '') {
|
|
1141
|
+
const known = new Set((manifest && manifest.slotNames) || []);
|
|
1142
|
+
const out = [];
|
|
1143
|
+
for (const occ of tagOccurrences(text, path)) {
|
|
1144
|
+
const value = occ.attrs.slot;
|
|
1145
|
+
if (value === undefined || value === null) continue;
|
|
1146
|
+
if (isDynamicAttr('slot', value)) continue;
|
|
1147
|
+
if (known.has(value)) continue;
|
|
1148
|
+
out.push({
|
|
1149
|
+
line: occ.line,
|
|
1150
|
+
snippet: `<${occ.tag} slot="${value}">`,
|
|
1151
|
+
why: `UNKNOWN-SLOT: slot="${value}" is not a slot name any component in the installed manifest declares`,
|
|
1152
|
+
});
|
|
1153
|
+
}
|
|
1154
|
+
return out;
|
|
1155
|
+
}
|
|
1156
|
+
|
|
953
1157
|
/**
|
|
954
1158
|
* Yaml-corpus primitive (LLD-0016 §C3): reads one component yaml's own
|
|
955
1159
|
* top-level `component:` scalar and its `props:` mapping's first-level key
|
|
@@ -1004,6 +1208,18 @@ function extractYamlComponentPropKeys(text) {
|
|
|
1004
1208
|
* @param {Array<{id:string, severity:string, scope:string, fileTypes:string[], match:Function}>} rules
|
|
1005
1209
|
* @param {{scopes?: string[]}} [opts] which rule scopes to run — omit for all
|
|
1006
1210
|
*/
|
|
1211
|
+
// gh#3716: a `scope: 'forge-only'` rule is declared to check framework
|
|
1212
|
+
// source (packages/web-components, packages/web-modules), the two trees
|
|
1213
|
+
// that are actually authored as scoped components. `npm run lint` sweeps
|
|
1214
|
+
// the whole repo unscoped (the monorepo is both the framework source and
|
|
1215
|
+
// its own consumer), so without this restriction a forge-only rule also
|
|
1216
|
+
// fires against e.g. apps/* page CSS that was never authored to that
|
|
1217
|
+
// contract. `consumer-only`/`shared` rules carry no such corpus fence.
|
|
1218
|
+
const FORGE_ONLY_PATHS = ['packages/web-components/', 'packages/web-modules/'];
|
|
1219
|
+
function isForgeOnlyPath(path) {
|
|
1220
|
+
return FORGE_ONLY_PATHS.some((p) => path.startsWith(p));
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1007
1223
|
function makeLinter(rules, opts = {}) {
|
|
1008
1224
|
const scopes = opts.scopes || null;
|
|
1009
1225
|
const active = rules.filter((r) => !scopes || scopes.includes(r.scope));
|
|
@@ -1014,16 +1230,28 @@ function makeLinter(rules, opts = {}) {
|
|
|
1014
1230
|
let findings = [];
|
|
1015
1231
|
for (const rule of active) {
|
|
1016
1232
|
if (rule.fileTypes && rule.fileTypes.length && !rule.fileTypes.includes(fileExt)) continue;
|
|
1233
|
+
if (rule.scope === 'forge-only' && !isForgeOnlyPath(path)) continue;
|
|
1017
1234
|
const hits = rule.match(text, path, { scopes }) || [];
|
|
1018
1235
|
for (const h of hits) {
|
|
1019
|
-
findings.push({
|
|
1236
|
+
findings.push({
|
|
1237
|
+
name: rule.id,
|
|
1238
|
+
line: h.line,
|
|
1239
|
+
snippet: h.snippet,
|
|
1240
|
+
why: h.why,
|
|
1241
|
+
...(h.severity ? { severity: h.severity } : {}),
|
|
1242
|
+
});
|
|
1020
1243
|
}
|
|
1021
1244
|
}
|
|
1022
1245
|
|
|
1023
1246
|
// Suppression syntax (LLD-0016 §Interfaces):
|
|
1024
|
-
// /* adia-lint-disable
|
|
1025
|
-
// or the line before it drops that one finding.
|
|
1026
|
-
//
|
|
1247
|
+
// /* adia-lint-disable RULE-ID: reason text */ on the finding's own line
|
|
1248
|
+
// or the line before it drops that one finding. The separator may be a
|
|
1249
|
+
// colon, a space-padded hyphen, or an em dash (SUPPRESS_RE in
|
|
1250
|
+
// primitives.mjs is the one source); the padding on the hyphen is
|
|
1251
|
+
// required because rule ids contain hyphens. Prefer the colon or the
|
|
1252
|
+
// padded hyphen when writing one, since check:em-dash-added-lines
|
|
1253
|
+
// (gh#3767) rejects an em dash on any added line. A bare disable with no
|
|
1254
|
+
// <reason> is itself a finding (SUPPRESS-NO-REASON, warn), checked
|
|
1027
1255
|
// once per suppression comment in the file, independent of whether it
|
|
1028
1256
|
// actually suppressed anything this run.
|
|
1029
1257
|
findings = findings.filter((f) => !suppressionFor(rawLines, f.line, f.name).suppressed);
|
|
@@ -1038,6 +1266,24 @@ function makeLinter(rules, opts = {}) {
|
|
|
1038
1266
|
}
|
|
1039
1267
|
}
|
|
1040
1268
|
|
|
1269
|
+
// gh#4161: SUPPRESS_RE is both matcher and detector, so a directive it
|
|
1270
|
+
// refuses produces no suppression, no SUPPRESS-NO-REASON, and no
|
|
1271
|
+
// diagnostic at all, silently invisible (gh#3868/gh#3871 each closed
|
|
1272
|
+
// one specific inert shape, never the general class). This loose scan
|
|
1273
|
+
// closes it: every adia-lint-disable-shaped comment the strict grammar
|
|
1274
|
+
// refuses to parse becomes a warn-severity SUPPRESS-MALFORMED finding
|
|
1275
|
+
// naming the file (via the caller) and line, so a malformed directive
|
|
1276
|
+
// is loud instead of vanishing.
|
|
1277
|
+
for (const s of malformedSuppressions(rawLines)) {
|
|
1278
|
+
findings.push({
|
|
1279
|
+
name: 'SUPPRESS-MALFORMED',
|
|
1280
|
+
line: s.lineNo,
|
|
1281
|
+
snippet: s.snippet,
|
|
1282
|
+
why: 'a comment mentioning adia-lint-disable that the strict directive grammar (SUPPRESS_RE) refuses to parse; it suppresses nothing and raises no other diagnostic, fix the <id>/<separator>/<reason> shape or drop the comment',
|
|
1283
|
+
severity: 'warn',
|
|
1284
|
+
});
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1041
1287
|
findings.sort((a, b) => (a.line - b.line) || (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
|
|
1042
1288
|
return findings;
|
|
1043
1289
|
}
|
|
@@ -1055,22 +1301,161 @@ function render(path, findings) {
|
|
|
1055
1301
|
}
|
|
1056
1302
|
|
|
1057
1303
|
|
|
1304
|
+
/**
|
|
1305
|
+
* scripts/lint/engine/baseline.mjs (gh#3718): the checked-in baseline of
|
|
1306
|
+
* known SCOPE-EXTENT sites, and the normalization that keys them.
|
|
1307
|
+
*
|
|
1308
|
+
* No static `node:fs`/`node:path`/`node:url` import, same as
|
|
1309
|
+
* `scripts/lint/engine/primitives.mjs` and `scripts/lint/engine/run.mjs`,
|
|
1310
|
+
* because this module is inlined into the shared generated bank (LLD-0016
|
|
1311
|
+
* §C5) and copied byte-for-byte to 4 destinations, one of which
|
|
1312
|
+
* (anti-patterns.generated.js) is browser-reachable; check:browser-safe
|
|
1313
|
+
* forbids a top-level `node:*` import there. `process.getBuiltinModule()`
|
|
1314
|
+
* reaches the same builtins with zero import statements, undefined in a
|
|
1315
|
+
* browser, so this fails soft to "excuse nothing" there instead of throwing.
|
|
1316
|
+
*
|
|
1317
|
+
* Loaded once per process. Four outcomes, all of them chosen rather than
|
|
1318
|
+
* incidental:
|
|
1319
|
+
*
|
|
1320
|
+
* 1. No Node fs/path/url builtins (browser context). Not an error: no site
|
|
1321
|
+
* is excused, so every finding reports at the rule's own severity.
|
|
1322
|
+
* 2. No baseline file on disk. Same as (1).
|
|
1323
|
+
* 3. An unusable baseline file: unparseable, OR parseable but not an object
|
|
1324
|
+
* with an object "sites" (JSON.parse succeeds on null, on a bare string, on
|
|
1325
|
+
* a number and on an array, so "it parsed" says nothing about the shape).
|
|
1326
|
+
* Same as (1), excuse nothing, but WARN loudly naming what was wrong. It
|
|
1327
|
+
* must not throw: this is one rule's data file, and an uncaught error here
|
|
1328
|
+
* takes down the whole lint run for every other rule, which is a far worse
|
|
1329
|
+
* failure than losing the downgrades.
|
|
1330
|
+
* 4. A readable baseline. Its sites are excused, nothing else is.
|
|
1331
|
+
*
|
|
1332
|
+
* What is never an outcome is "unreadable, therefore everything is excused",
|
|
1333
|
+
* which would disable the rule silently.
|
|
1334
|
+
*/
|
|
1335
|
+
let cache = null;
|
|
1336
|
+
|
|
1337
|
+
const isPlainObject = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
1338
|
+
|
|
1339
|
+
const describe = (v) => (v === null ? 'null' : Array.isArray(v) ? 'an array' : typeof v);
|
|
1340
|
+
|
|
1341
|
+
function nodeBuiltins() {
|
|
1342
|
+
if (typeof process === 'undefined' || typeof process.getBuiltinModule !== 'function') return null;
|
|
1343
|
+
return {
|
|
1344
|
+
fs: process.getBuiltinModule('node:fs'),
|
|
1345
|
+
path: process.getBuiltinModule('node:path'),
|
|
1346
|
+
url: process.getBuiltinModule('node:url'),
|
|
1347
|
+
};
|
|
1348
|
+
}
|
|
1349
|
+
|
|
1350
|
+
function load() {
|
|
1351
|
+
if (cache) return cache;
|
|
1352
|
+
const builtins = nodeBuiltins();
|
|
1353
|
+
if (!builtins) {
|
|
1354
|
+
cache = { sites: {} };
|
|
1355
|
+
return cache;
|
|
1356
|
+
}
|
|
1357
|
+
const here = builtins.path.dirname(builtins.url.fileURLToPath(import.meta.url));
|
|
1358
|
+
const baselinePath = builtins.path.join(here, '..', 'scope-extent-baseline.json');
|
|
1359
|
+
if (!builtins.fs.existsSync(baselinePath)) {
|
|
1360
|
+
cache = { sites: {} };
|
|
1361
|
+
return cache;
|
|
1362
|
+
}
|
|
1363
|
+
try {
|
|
1364
|
+
const parsed = JSON.parse(builtins.fs.readFileSync(baselinePath, 'utf8'));
|
|
1365
|
+
// Shape validation lives INSIDE the try, deliberately. JSON.parse succeeds
|
|
1366
|
+
// on `null`, on a bare string, on a number and on an array, so a parse that
|
|
1367
|
+
// did not throw proves nothing about the shape. Validating out here is how
|
|
1368
|
+
// a file containing the four characters `null` reached `cache.sites` and
|
|
1369
|
+
// threw past the catch, crashing every other rule's run.
|
|
1370
|
+
if (!isPlainObject(parsed)) {
|
|
1371
|
+
throw new TypeError(`expected a JSON object at the top level, got ${describe(parsed)}`);
|
|
1372
|
+
}
|
|
1373
|
+
// An absent `sites` is a legitimately empty baseline (excuses nothing) and
|
|
1374
|
+
// is NOT warned about; a present-but-wrong-typed `sites` is a real mistake
|
|
1375
|
+
// and is. Warning on the empty case would train readers to ignore the
|
|
1376
|
+
// warning, which is how a loud instrument stops being read.
|
|
1377
|
+
if (parsed.sites !== undefined && !isPlainObject(parsed.sites)) {
|
|
1378
|
+
throw new TypeError(`"sites" must be an object, got ${describe(parsed.sites)}`);
|
|
1379
|
+
}
|
|
1380
|
+
cache = { ...parsed, sites: parsed.sites || {} };
|
|
1381
|
+
} catch (err) {
|
|
1382
|
+
console.warn(
|
|
1383
|
+
`[SCOPE-EXTENT] baseline at ${baselinePath} is unusable, excusing nothing: ${err.message}`,
|
|
1384
|
+
);
|
|
1385
|
+
cache = { sites: {} };
|
|
1386
|
+
}
|
|
1387
|
+
return cache;
|
|
1388
|
+
}
|
|
1389
|
+
|
|
1390
|
+
/**
|
|
1391
|
+
* Normalize a matched block so that reformatting does not invalidate an entry:
|
|
1392
|
+
* strip CSS comments, collapse all whitespace, drop spaces around the
|
|
1393
|
+
* punctuation that separates declarations. Editing the selector or the
|
|
1394
|
+
* declaration itself still changes the key, which is intended, and that is a real
|
|
1395
|
+
* change to a known site.
|
|
1396
|
+
*
|
|
1397
|
+
* The matcher itself can stop mid-comment (a comment mentioning a property
|
|
1398
|
+
* name like "min-width:" satisfies the same width/height text test the real
|
|
1399
|
+
* rule looks for), so a raw match can end inside an unterminated `/* ... `
|
|
1400
|
+
* with no closing marker in the captured text yet. That trailing open
|
|
1401
|
+
* comment is stripped too, same as a closed one: it carries no declaration
|
|
1402
|
+
* text, and dropping it is what keeps a baseline key from carrying prose
|
|
1403
|
+
* (comment wording, including punctuation the rest of this codebase avoids)
|
|
1404
|
+
* that has nothing to do with the actual finding.
|
|
1405
|
+
*/
|
|
1406
|
+
function normalizeMatch(raw) {
|
|
1407
|
+
return raw
|
|
1408
|
+
.replace(/\/\*[\s\S]*?\*\//g, '')
|
|
1409
|
+
.replace(/\/\*[\s\S]*$/g, '')
|
|
1410
|
+
.replace(/\s+/g, ' ')
|
|
1411
|
+
.replace(/\s*([{};:,])\s*/g, '$1')
|
|
1412
|
+
.trim();
|
|
1413
|
+
}
|
|
1414
|
+
|
|
1415
|
+
/** The baselined keys for one file, as a multiset (duplicates preserved). */
|
|
1416
|
+
function baselineFor(path) {
|
|
1417
|
+
const p = (path || '').replace(/\\/g, '/');
|
|
1418
|
+
return load().sites[p] || [];
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1421
|
+
/** Total baselined entries. The acceptance compares this to a live count. */
|
|
1422
|
+
function baselineCount() {
|
|
1423
|
+
const { sites } = load();
|
|
1424
|
+
return Object.values(sites).reduce((n, list) => n + list.length, 0);
|
|
1425
|
+
}
|
|
1426
|
+
|
|
1427
|
+
|
|
1058
1428
|
const RULES = [];
|
|
1059
1429
|
{
|
|
1060
1430
|
|
|
1061
1431
|
|
|
1062
1432
|
const APPLIES_EXT = ['.html', '.htm', '.vue', '.svelte', '.astro', '.tsx', '.jsx', '.js', '.mjs', '.ts'];
|
|
1063
1433
|
|
|
1434
|
+
// gh#3717: a whole-file `String.includes('validate_schema')` cleared the
|
|
1435
|
+
// finding on ANY occurrence of the name anywhere in the file, a prose
|
|
1436
|
+
// comment, a docstring, an unrelated identifier, even a substring baked
|
|
1437
|
+
// into a fixture string. site/pages/catalogs/catalogs.setup.js passed
|
|
1438
|
+
// purely because a comment mentions both names while `.doc =` is set with
|
|
1439
|
+
// no validation ever run. The fix asks two sharper questions instead:
|
|
1440
|
+
// (1) is the `.doc =` assignment itself real code, not commented out
|
|
1441
|
+
// (stripCommentLines, gh#976's own comment-stripping primitive, the same
|
|
1442
|
+
// one that keeps a retired-selector rule from firing on a docstring), and
|
|
1443
|
+
// (2) does the SAME module actually CALL validate_schema(...) or
|
|
1444
|
+
// check_anti_patterns(...), a real call expression, not a bare mention.
|
|
1445
|
+
const VALIDATE_CALL_RE = /\b(?:validate_schema|check_anti_patterns)\s*\(/;
|
|
1446
|
+
|
|
1064
1447
|
const genuiUnvalidated = {
|
|
1065
1448
|
id: 'GENUI-UNVALIDATED',
|
|
1066
1449
|
severity: 'error',
|
|
1067
1450
|
scope: 'consumer-only',
|
|
1068
1451
|
fileTypes: APPLIES_EXT,
|
|
1069
|
-
match(text) {
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
const
|
|
1073
|
-
if (
|
|
1452
|
+
match(text, filePath) {
|
|
1453
|
+
if (!/\.doc\s*=/.test(text)) return [];
|
|
1454
|
+
const stripped = stripCommentLines(text, ext(filePath)).map((l) => l.stripped).join('\n');
|
|
1455
|
+
const m = /\.doc\s*=/.exec(stripped);
|
|
1456
|
+
if (!m) return []; // every `.doc =` in the file was inside a comment
|
|
1457
|
+
if (VALIDATE_CALL_RE.test(stripped)) return [];
|
|
1458
|
+
const line = lineOf(stripped, m.index);
|
|
1074
1459
|
return [{
|
|
1075
1460
|
line,
|
|
1076
1461
|
snippet: '.doc = … with no validate in file',
|
|
@@ -1088,6 +1473,42 @@ const genuiUnvalidated = {
|
|
|
1088
1473
|
// a declarative `src=`/`transport=` on an instance.
|
|
1089
1474
|
const RUNTIME_HOME_PATH = /(?:^|[\\/])packages[\\/]web-modules[\\/]runtime[\\/](?:a2ui-root|gen-root)[\\/]/;
|
|
1090
1475
|
|
|
1476
|
+
// gh#3714: the old check matched ".doc =" and "src="/"transport=" anywhere
|
|
1477
|
+
// in the FILE, so a2ui-root.js's own docstring (documenting both usage
|
|
1478
|
+
// modes side by side in one comment block) tripped it, even with the
|
|
1479
|
+
// RUNTIME_HOME_PATH exemption above already carved out for that one file.
|
|
1480
|
+
// The real bug is broader than that single case: any consumer file wiring
|
|
1481
|
+
// TWO root elements, one fed declaratively and one fed programmatically,
|
|
1482
|
+
// was also a false positive, since the old match never asked WHICH
|
|
1483
|
+
// element each signal belonged to.
|
|
1484
|
+
//
|
|
1485
|
+
// This is a regex heuristic, not a JS/HTML parser, so it correlates by two
|
|
1486
|
+
// cheap signals rather than real scope analysis:
|
|
1487
|
+
// 1. Single-element files: if the file has exactly one <a2ui-root>/
|
|
1488
|
+
// <gen-root> tag, any ".doc =" assignment anywhere in the file is
|
|
1489
|
+
// presumed to target that one element (nothing else for it to mean).
|
|
1490
|
+
// 2. Multi-element files: a ".doc =" assignment correlates to a specific
|
|
1491
|
+
// element only when its target variable was bound via
|
|
1492
|
+
// document.getElementById('id') / document.querySelector('#id') to
|
|
1493
|
+
// an element carrying a matching id="..." attribute.
|
|
1494
|
+
// Documented misses (false negatives), by design rather than oversight:
|
|
1495
|
+
// - A file with 2+ root elements where NONE carry an id= attribute, or
|
|
1496
|
+
// where the ".doc =" target variable is bound some other way (a
|
|
1497
|
+
// framework ref, a destructured array, ".doc =" set via "this.el"),
|
|
1498
|
+
// cannot be correlated and is silently allowed. The old file-wide
|
|
1499
|
+
// check would have (over-)caught this, at the cost of the
|
|
1500
|
+
// a2ui-root.js false positive this ticket exists to fix.
|
|
1501
|
+
// Documented possible false positive: in a single-element file, a ".doc ="
|
|
1502
|
+
// assignment that provably targets a DIFFERENT, unrelated object which
|
|
1503
|
+
// merely has its own "doc" property (e.g. an unrelated "state.doc = ...")
|
|
1504
|
+
// cannot be told apart from a real root reference by rule 1 above.
|
|
1505
|
+
const ROOT_TAG = /<(a2ui-root|gen-root)\b([^>]*)>/g;
|
|
1506
|
+
const ID_ATTR = /\bid\s*=\s*["']([^"']+)["']/;
|
|
1507
|
+
const DECLARATIVE_ATTR = /\b(?:src|transport)\s*=/;
|
|
1508
|
+
const VAR_TO_ID =
|
|
1509
|
+
/(?:const|let|var)?\s*([A-Za-z_$][\w$]*)\s*=\s*document\.(?:getElementById\(\s*['"]([\w-]+)['"]\s*\)|querySelector\(\s*['"]#([\w-]+)['"]\s*\))/g;
|
|
1510
|
+
const DOC_ASSIGN = /([A-Za-z_$][\w$]*)\.doc\s*=/g;
|
|
1511
|
+
|
|
1091
1512
|
const genuiDocConflict = {
|
|
1092
1513
|
id: 'GENUI-DOC-CONFLICT',
|
|
1093
1514
|
severity: 'error',
|
|
@@ -1095,17 +1516,34 @@ const genuiDocConflict = {
|
|
|
1095
1516
|
fileTypes: APPLIES_EXT,
|
|
1096
1517
|
match(text, filePath) {
|
|
1097
1518
|
if (typeof filePath === 'string' && RUNTIME_HOME_PATH.test(filePath)) return [];
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
const
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1519
|
+
|
|
1520
|
+
const elements = [];
|
|
1521
|
+
for (const m of text.matchAll(ROOT_TAG)) {
|
|
1522
|
+
const attrs = m[2];
|
|
1523
|
+
const idMatch = ID_ATTR.exec(attrs);
|
|
1524
|
+
elements.push({ id: idMatch ? idMatch[1] : null, declarative: DECLARATIVE_ATTR.test(attrs) });
|
|
1525
|
+
}
|
|
1526
|
+
if (elements.length === 0) return [];
|
|
1527
|
+
|
|
1528
|
+
const idsWithDeclarative = new Set(elements.filter((e) => e.declarative && e.id).map((e) => e.id));
|
|
1529
|
+
const varToId = new Map();
|
|
1530
|
+
for (const m of text.matchAll(VAR_TO_ID)) {
|
|
1531
|
+
varToId.set(m[1], m[2] || m[3]);
|
|
1532
|
+
}
|
|
1533
|
+
const soleElementIsDeclarative = elements.length === 1 && elements[0].declarative;
|
|
1534
|
+
|
|
1535
|
+
const findings = [];
|
|
1536
|
+
for (const m of text.matchAll(DOC_ASSIGN)) {
|
|
1537
|
+
const targetId = varToId.get(m[1]);
|
|
1538
|
+
const conflicts = targetId ? idsWithDeclarative.has(targetId) : soleElementIsDeclarative;
|
|
1539
|
+
if (!conflicts) continue;
|
|
1540
|
+
findings.push({
|
|
1541
|
+
line: lineOf(text, m.index),
|
|
1542
|
+
snippet: '.doc = … alongside src=/transport= on the same root',
|
|
1105
1543
|
why: 'two feed paths fight — a root is fed EITHER declaratively (src/transport) OR programmatically (.doc), never both',
|
|
1106
|
-
}
|
|
1544
|
+
});
|
|
1107
1545
|
}
|
|
1108
|
-
return
|
|
1546
|
+
return findings;
|
|
1109
1547
|
},
|
|
1110
1548
|
};
|
|
1111
1549
|
|
|
@@ -1126,6 +1564,13 @@ RULES.push(genuiUnvalidated, genuiDocConflict);
|
|
|
1126
1564
|
// gets the exemption; scope it to that tree, not the filename alone.
|
|
1127
1565
|
const EXAMPLES_FILE = /\.examples\.html$/;
|
|
1128
1566
|
const CATALOG_CONTENTS_FILE = /\.contents\.html$/;
|
|
1567
|
+
// packages/web-components/templates/ is the Class R npm mirror of those same
|
|
1568
|
+
// catalog/apps/playgrounds demo fragments (ADR-0084, built by
|
|
1569
|
+
// scripts/build/templates-mirror.mjs). The mirror step renames each file to
|
|
1570
|
+
// `pattern-library-<name>.html` and drops the `catalog/` prefix, so a
|
|
1571
|
+
// mirrored demo's default-open state no longer matches either pattern above
|
|
1572
|
+
// even though it is a byte-for-byte copy of already-exempt source markup.
|
|
1573
|
+
const TEMPLATES_MIRROR_DIR = /^packages\/web-components\/templates\//;
|
|
1129
1574
|
|
|
1130
1575
|
|
|
1131
1576
|
RULES.push({
|
|
@@ -1137,6 +1582,7 @@ RULES.push({
|
|
|
1137
1582
|
const p = (path || '').replace(/\\/g, '/');
|
|
1138
1583
|
if (EXAMPLES_FILE.test(p)) return [];
|
|
1139
1584
|
if (CATALOG_CONTENTS_FILE.test(p) && p.split('/')[0] === 'catalog') return [];
|
|
1585
|
+
if (TEMPLATES_MIRROR_DIR.test(p)) return [];
|
|
1140
1586
|
const out = [];
|
|
1141
1587
|
text.split('\n').forEach((line, i) => {
|
|
1142
1588
|
if (RE.OVERLAY_OPEN.test(line)) {
|
|
@@ -1222,8 +1668,11 @@ RULES.push({
|
|
|
1222
1668
|
const pages = (text.match(/<admin-page[\s/>]/g) || []).length;
|
|
1223
1669
|
const scrolls = (text.match(/<admin-scroll[\s/>]/g) || []).length;
|
|
1224
1670
|
if (scrolls && pages > scrolls) {
|
|
1671
|
+
// report the first <admin-page> occurrence, the line a developer would
|
|
1672
|
+
// actually attach an adia-lint-disable comment to for this finding.
|
|
1673
|
+
const firstIndex = text.search(/<admin-page[\s/>]/);
|
|
1225
1674
|
out.push({
|
|
1226
|
-
line:
|
|
1675
|
+
line: lineOf(text, firstIndex),
|
|
1227
1676
|
snippet: '<admin-page> × N inside <admin-scroll>',
|
|
1228
1677
|
why: 'each <admin-scroll> hosts exactly one <admin-page> — multiple pages need multiple scroll regions',
|
|
1229
1678
|
});
|
|
@@ -1243,6 +1692,8 @@ RULES.push({
|
|
|
1243
1692
|
}
|
|
1244
1693
|
|
|
1245
1694
|
{
|
|
1695
|
+
|
|
1696
|
+
|
|
1246
1697
|
const APPLIES_EXT = ['.html', '.htm', '.vue', '.svelte', '.astro', '.tsx', '.jsx', '.js', '.mjs', '.ts'];
|
|
1247
1698
|
|
|
1248
1699
|
|
|
@@ -1252,9 +1703,10 @@ RULES.push({
|
|
|
1252
1703
|
scope: 'consumer-only',
|
|
1253
1704
|
fileTypes: APPLIES_EXT,
|
|
1254
1705
|
match(text) {
|
|
1255
|
-
|
|
1706
|
+
const m = /<admin-sidebar[^>]*\bresizable\b/.exec(text);
|
|
1707
|
+
if (m && !text.includes('data-sidebar-resize')) {
|
|
1256
1708
|
return [{
|
|
1257
|
-
line:
|
|
1709
|
+
line: lineOf(text, m.index),
|
|
1258
1710
|
snippet: '<admin-sidebar resizable> without [data-sidebar-resize]',
|
|
1259
1711
|
why: '[resizable] needs a child <div data-sidebar-resize> or there is no drag handle',
|
|
1260
1712
|
}];
|
|
@@ -1322,6 +1774,29 @@ RULES.push(ssrDoubleRouter, ssrToplevelImport);
|
|
|
1322
1774
|
{
|
|
1323
1775
|
|
|
1324
1776
|
|
|
1777
|
+
// gh#3888: a second, honestly-named opt-out alongside `forge-lint:
|
|
1778
|
+
// foundation`. Some CSS intentionally scopes via a repeated parent-tag
|
|
1779
|
+
// selector prefix (`admin-shell [data-x] { … }`) instead of a real
|
|
1780
|
+
// `@scope` at-rule. Labeling that shape `forge-lint: foundation` would
|
|
1781
|
+
// be a lie (neither file is a token sheet); this tag says what the
|
|
1782
|
+
// file actually does instead.
|
|
1783
|
+
//
|
|
1784
|
+
// ALLOWLISTED, not a self-serve bypass (gh#3888 critic finding): an
|
|
1785
|
+
// undocumented, unrestricted opt-out comment is the same shape as the
|
|
1786
|
+
// substring-loophole bug this rule just fixed, only deliberate. A
|
|
1787
|
+
// file adding this comment on its own must FAIL, naming the allowlist,
|
|
1788
|
+
// so escaping MISSING-SCOPE this way always needs a human to edit this
|
|
1789
|
+
// rule module, never just a CSS comment.
|
|
1790
|
+
//
|
|
1791
|
+
// gh#3922 closed the follow-up: the two files gh#3888 allowlisted
|
|
1792
|
+
// (admin-shell.helpers.css, admin-shell.mobile-nav.css) are now real
|
|
1793
|
+
// `@scope (admin-shell) { … }` blocks and admin-shell.test.js's prefix
|
|
1794
|
+
// assertions were rewritten to match. The allowlist is empty again;
|
|
1795
|
+
// `forge-lint: prefix-scoped` stays available as a mechanism, not a
|
|
1796
|
+
// standing exemption; a future file needs a human to add it here.
|
|
1797
|
+
const PREFIX_SCOPED_RE = /forge-lint:\s*prefix-scoped/i;
|
|
1798
|
+
const PREFIX_SCOPED_ALLOWLIST = [];
|
|
1799
|
+
|
|
1325
1800
|
|
|
1326
1801
|
RULES.push({
|
|
1327
1802
|
id: 'MISSING-SCOPE',
|
|
@@ -1331,19 +1806,34 @@ RULES.push({
|
|
|
1331
1806
|
match(text, path) {
|
|
1332
1807
|
const isTokenish = isFoundationCss(path, text, 'forge-lint');
|
|
1333
1808
|
if (isTokenish) return [];
|
|
1334
|
-
|
|
1809
|
+
// gh#4008: a comment carrying the full `@scope (...)` pattern (not just
|
|
1810
|
+
// the bare word gh#3888 already excluded) must not satisfy this test:
|
|
1811
|
+
// blank CSS comments first, mirroring markupScanSurface's HTML-comment
|
|
1812
|
+
// blanking, so only a REAL, live at-rule can match.
|
|
1813
|
+
if (RE.SCOPE_BLOCK.test(cssCommentBlankedSurface(text))) return [];
|
|
1814
|
+
const normalizedPath = (path || '').replace(/\\/g, '/');
|
|
1815
|
+
const claimsPrefixScoped = PREFIX_SCOPED_RE.test(text.slice(0, 1000));
|
|
1816
|
+
const isAllowlisted = PREFIX_SCOPED_ALLOWLIST.some((p) => normalizedPath.endsWith(p));
|
|
1817
|
+
if (claimsPrefixScoped && !isAllowlisted) {
|
|
1818
|
+
return [{
|
|
1819
|
+
line: 1,
|
|
1820
|
+
snippet: '(file has CSS rules but no @scope block)',
|
|
1821
|
+
why: `forge-lint: prefix-scoped is allowlisted to zero files (gh#3922 closed the last two, gh#3888). Adding this comment does not opt a file out; either wrap it in a real @scope block, or ask for the allowlist to be extended in scripts/lint/rules/forge/missing-scope.mjs itself.`,
|
|
1822
|
+
}];
|
|
1823
|
+
}
|
|
1824
|
+
if (claimsPrefixScoped && isAllowlisted) return [];
|
|
1335
1825
|
if (!RE.SELECTOR_RULE.test(text)) return [];
|
|
1336
1826
|
return [{
|
|
1337
1827
|
line: 1,
|
|
1338
1828
|
snippet: '(file has CSS rules but no @scope block)',
|
|
1339
|
-
why: 'component CSS must be wrapped in `@scope (<tag>) { … }` so styles don\'t leak in light DOM (foundation/token sheets excepted
|
|
1829
|
+
why: 'component CSS must be wrapped in `@scope (<tag>) { … }` so styles don\'t leak in light DOM (foundation/token sheets excepted with /* forge-lint: foundation */)',
|
|
1340
1830
|
}];
|
|
1341
1831
|
},
|
|
1342
1832
|
});
|
|
1343
1833
|
}
|
|
1344
1834
|
|
|
1345
1835
|
{
|
|
1346
|
-
// GENERATED
|
|
1836
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/accordion/accordion-item.yaml's a2ui.allowedParents/allowedChildren.
|
|
1347
1837
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
1348
1838
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
1349
1839
|
|
|
@@ -1351,15 +1841,16 @@ RULES.push({
|
|
|
1351
1841
|
const TAG = "accordion-item-ui";
|
|
1352
1842
|
const ALLOWED_PARENTS = ["accordion-ui"];
|
|
1353
1843
|
const ALLOWED_CHILDREN = [];
|
|
1844
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
1354
1845
|
|
|
1355
1846
|
|
|
1356
1847
|
RULES.push({
|
|
1357
1848
|
id: "COMPOSITION-ACCORDION-ITEM-UI",
|
|
1358
|
-
severity: '
|
|
1849
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
1359
1850
|
scope: 'shared',
|
|
1360
1851
|
fileTypes: MARKUP_EXT,
|
|
1361
1852
|
match(text) {
|
|
1362
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
1853
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
1363
1854
|
},
|
|
1364
1855
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
1365
1856
|
fixtures: {
|
|
@@ -1374,7 +1865,7 @@ RULES.push({
|
|
|
1374
1865
|
}
|
|
1375
1866
|
|
|
1376
1867
|
{
|
|
1377
|
-
// GENERATED
|
|
1868
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/accordion/accordion.yaml's a2ui.allowedParents/allowedChildren.
|
|
1378
1869
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
1379
1870
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
1380
1871
|
|
|
@@ -1382,15 +1873,16 @@ RULES.push({
|
|
|
1382
1873
|
const TAG = "accordion-ui";
|
|
1383
1874
|
const ALLOWED_PARENTS = [];
|
|
1384
1875
|
const ALLOWED_CHILDREN = ["accordion-item-ui"];
|
|
1876
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
1385
1877
|
|
|
1386
1878
|
|
|
1387
1879
|
RULES.push({
|
|
1388
1880
|
id: "COMPOSITION-ACCORDION-UI",
|
|
1389
|
-
severity: '
|
|
1881
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
1390
1882
|
scope: 'shared',
|
|
1391
1883
|
fileTypes: MARKUP_EXT,
|
|
1392
1884
|
match(text) {
|
|
1393
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
1885
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
1394
1886
|
},
|
|
1395
1887
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
1396
1888
|
fixtures: {
|
|
@@ -1398,14 +1890,15 @@ RULES.push({
|
|
|
1398
1890
|
"<accordion-ui><not-an-allowed-child-ui></not-an-allowed-child-ui></accordion-ui>"
|
|
1399
1891
|
],
|
|
1400
1892
|
"clean": [
|
|
1401
|
-
"<accordion-ui><accordion-item-ui></accordion-item-ui></accordion-ui>"
|
|
1893
|
+
"<accordion-ui><accordion-item-ui></accordion-item-ui></accordion-ui>",
|
|
1894
|
+
"<accordion-ui><not-an-allowed-child-ui slot=\"arbitrary-slot\"></not-an-allowed-child-ui></accordion-ui>"
|
|
1402
1895
|
]
|
|
1403
1896
|
},
|
|
1404
1897
|
});
|
|
1405
1898
|
}
|
|
1406
1899
|
|
|
1407
1900
|
{
|
|
1408
|
-
// GENERATED
|
|
1901
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/action-list/action-item.yaml's a2ui.allowedParents/allowedChildren.
|
|
1409
1902
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
1410
1903
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
1411
1904
|
|
|
@@ -1413,15 +1906,16 @@ RULES.push({
|
|
|
1413
1906
|
const TAG = "action-item-ui";
|
|
1414
1907
|
const ALLOWED_PARENTS = ["action-list-ui"];
|
|
1415
1908
|
const ALLOWED_CHILDREN = [];
|
|
1909
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
1416
1910
|
|
|
1417
1911
|
|
|
1418
1912
|
RULES.push({
|
|
1419
1913
|
id: "COMPOSITION-ACTION-ITEM-UI",
|
|
1420
|
-
severity: '
|
|
1914
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
1421
1915
|
scope: 'shared',
|
|
1422
1916
|
fileTypes: MARKUP_EXT,
|
|
1423
1917
|
match(text) {
|
|
1424
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
1918
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
1425
1919
|
},
|
|
1426
1920
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
1427
1921
|
fixtures: {
|
|
@@ -1436,7 +1930,7 @@ RULES.push({
|
|
|
1436
1930
|
}
|
|
1437
1931
|
|
|
1438
1932
|
{
|
|
1439
|
-
// GENERATED
|
|
1933
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/action-list/action-list.yaml's a2ui.allowedParents/allowedChildren.
|
|
1440
1934
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
1441
1935
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
1442
1936
|
|
|
@@ -1444,15 +1938,16 @@ RULES.push({
|
|
|
1444
1938
|
const TAG = "action-list-ui";
|
|
1445
1939
|
const ALLOWED_PARENTS = [];
|
|
1446
1940
|
const ALLOWED_CHILDREN = ["action-item-ui"];
|
|
1941
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
1447
1942
|
|
|
1448
1943
|
|
|
1449
1944
|
RULES.push({
|
|
1450
1945
|
id: "COMPOSITION-ACTION-LIST-UI",
|
|
1451
|
-
severity: '
|
|
1946
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
1452
1947
|
scope: 'shared',
|
|
1453
1948
|
fileTypes: MARKUP_EXT,
|
|
1454
1949
|
match(text) {
|
|
1455
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
1950
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
1456
1951
|
},
|
|
1457
1952
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
1458
1953
|
fixtures: {
|
|
@@ -1460,14 +1955,15 @@ RULES.push({
|
|
|
1460
1955
|
"<action-list-ui><not-an-allowed-child-ui></not-an-allowed-child-ui></action-list-ui>"
|
|
1461
1956
|
],
|
|
1462
1957
|
"clean": [
|
|
1463
|
-
"<action-list-ui><action-item-ui></action-item-ui></action-list-ui>"
|
|
1958
|
+
"<action-list-ui><action-item-ui></action-item-ui></action-list-ui>",
|
|
1959
|
+
"<action-list-ui><not-an-allowed-child-ui slot=\"arbitrary-slot\"></not-an-allowed-child-ui></action-list-ui>"
|
|
1464
1960
|
]
|
|
1465
1961
|
},
|
|
1466
1962
|
});
|
|
1467
1963
|
}
|
|
1468
1964
|
|
|
1469
1965
|
{
|
|
1470
|
-
// GENERATED
|
|
1966
|
+
// GENERATED: do not hand-edit. Source: packages/web-modules/shell/admin-command/admin-command.yaml's a2ui.allowedParents/allowedChildren.
|
|
1471
1967
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
1472
1968
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
1473
1969
|
|
|
@@ -1475,15 +1971,16 @@ RULES.push({
|
|
|
1475
1971
|
const TAG = "admin-command";
|
|
1476
1972
|
const ALLOWED_PARENTS = ["admin-shell"];
|
|
1477
1973
|
const ALLOWED_CHILDREN = [];
|
|
1974
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
1478
1975
|
|
|
1479
1976
|
|
|
1480
1977
|
RULES.push({
|
|
1481
1978
|
id: "COMPOSITION-ADMIN-COMMAND",
|
|
1482
|
-
severity: '
|
|
1979
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
1483
1980
|
scope: 'shared',
|
|
1484
1981
|
fileTypes: MARKUP_EXT,
|
|
1485
1982
|
match(text) {
|
|
1486
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
1983
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
1487
1984
|
},
|
|
1488
1985
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
1489
1986
|
fixtures: {
|
|
@@ -1498,7 +1995,7 @@ RULES.push({
|
|
|
1498
1995
|
}
|
|
1499
1996
|
|
|
1500
1997
|
{
|
|
1501
|
-
// GENERATED
|
|
1998
|
+
// GENERATED: do not hand-edit. Source: packages/web-modules/shell/admin-content/admin-content.yaml's a2ui.allowedParents/allowedChildren.
|
|
1502
1999
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
1503
2000
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
1504
2001
|
|
|
@@ -1506,15 +2003,16 @@ RULES.push({
|
|
|
1506
2003
|
const TAG = "admin-content";
|
|
1507
2004
|
const ALLOWED_PARENTS = ["admin-shell"];
|
|
1508
2005
|
const ALLOWED_CHILDREN = [];
|
|
2006
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
1509
2007
|
|
|
1510
2008
|
|
|
1511
2009
|
RULES.push({
|
|
1512
2010
|
id: "COMPOSITION-ADMIN-CONTENT",
|
|
1513
|
-
severity: '
|
|
2011
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
1514
2012
|
scope: 'shared',
|
|
1515
2013
|
fileTypes: MARKUP_EXT,
|
|
1516
2014
|
match(text) {
|
|
1517
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
2015
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
1518
2016
|
},
|
|
1519
2017
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
1520
2018
|
fixtures: {
|
|
@@ -1529,38 +2027,103 @@ RULES.push({
|
|
|
1529
2027
|
}
|
|
1530
2028
|
|
|
1531
2029
|
{
|
|
1532
|
-
// GENERATED
|
|
2030
|
+
// GENERATED: do not hand-edit. Source: packages/web-modules/shell/admin-entity-item/admin-entity-item.yaml's a2ui.allowedParents/allowedChildren.
|
|
1533
2031
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
1534
2032
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
1535
2033
|
|
|
1536
2034
|
|
|
1537
|
-
const TAG = "admin-
|
|
1538
|
-
const ALLOWED_PARENTS = ["admin-
|
|
2035
|
+
const TAG = "admin-entity-item";
|
|
2036
|
+
const ALLOWED_PARENTS = ["admin-topbar","admin-statusbar"];
|
|
1539
2037
|
const ALLOWED_CHILDREN = [];
|
|
2038
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
1540
2039
|
|
|
1541
2040
|
|
|
1542
2041
|
RULES.push({
|
|
1543
|
-
id: "COMPOSITION-ADMIN-
|
|
1544
|
-
severity: '
|
|
2042
|
+
id: "COMPOSITION-ADMIN-ENTITY-ITEM",
|
|
2043
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
1545
2044
|
scope: 'shared',
|
|
1546
2045
|
fileTypes: MARKUP_EXT,
|
|
1547
2046
|
match(text) {
|
|
1548
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
2047
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
1549
2048
|
},
|
|
1550
2049
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
1551
2050
|
fixtures: {
|
|
1552
2051
|
"smelly": [
|
|
1553
|
-
"<div><admin-
|
|
2052
|
+
"<div><admin-entity-item></admin-entity-item></div>"
|
|
1554
2053
|
],
|
|
1555
2054
|
"clean": [
|
|
1556
|
-
"<admin-
|
|
2055
|
+
"<admin-topbar><admin-entity-item></admin-entity-item></admin-topbar>"
|
|
1557
2056
|
]
|
|
1558
2057
|
},
|
|
1559
2058
|
});
|
|
1560
2059
|
}
|
|
1561
2060
|
|
|
1562
2061
|
{
|
|
1563
|
-
// GENERATED
|
|
2062
|
+
// GENERATED: do not hand-edit. Source: packages/web-modules/agent-admin/admin-roster/admin-roster.yaml's a2ui.allowedParents/allowedChildren.
|
|
2063
|
+
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2064
|
+
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2065
|
+
|
|
2066
|
+
|
|
2067
|
+
const TAG = "admin-roster-ui";
|
|
2068
|
+
const ALLOWED_PARENTS = ["agent-admin-ui"];
|
|
2069
|
+
const ALLOWED_CHILDREN = [];
|
|
2070
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2071
|
+
|
|
2072
|
+
|
|
2073
|
+
RULES.push({
|
|
2074
|
+
id: "COMPOSITION-ADMIN-ROSTER-UI",
|
|
2075
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2076
|
+
scope: 'shared',
|
|
2077
|
+
fileTypes: MARKUP_EXT,
|
|
2078
|
+
match(text) {
|
|
2079
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2080
|
+
},
|
|
2081
|
+
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2082
|
+
fixtures: {
|
|
2083
|
+
"smelly": [
|
|
2084
|
+
"<div><admin-roster-ui></admin-roster-ui></div>"
|
|
2085
|
+
],
|
|
2086
|
+
"clean": [
|
|
2087
|
+
"<agent-admin-ui><admin-roster-ui></admin-roster-ui></agent-admin-ui>"
|
|
2088
|
+
]
|
|
2089
|
+
},
|
|
2090
|
+
});
|
|
2091
|
+
}
|
|
2092
|
+
|
|
2093
|
+
{
|
|
2094
|
+
// GENERATED: do not hand-edit. Source: packages/web-modules/agent-admin/admin-settings/admin-settings.yaml's a2ui.allowedParents/allowedChildren.
|
|
2095
|
+
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2096
|
+
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2097
|
+
|
|
2098
|
+
|
|
2099
|
+
const TAG = "admin-settings-ui";
|
|
2100
|
+
const ALLOWED_PARENTS = ["agent-admin-ui"];
|
|
2101
|
+
const ALLOWED_CHILDREN = [];
|
|
2102
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2103
|
+
|
|
2104
|
+
|
|
2105
|
+
RULES.push({
|
|
2106
|
+
id: "COMPOSITION-ADMIN-SETTINGS-UI",
|
|
2107
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2108
|
+
scope: 'shared',
|
|
2109
|
+
fileTypes: MARKUP_EXT,
|
|
2110
|
+
match(text) {
|
|
2111
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2112
|
+
},
|
|
2113
|
+
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2114
|
+
fixtures: {
|
|
2115
|
+
"smelly": [
|
|
2116
|
+
"<div><admin-settings-ui></admin-settings-ui></div>"
|
|
2117
|
+
],
|
|
2118
|
+
"clean": [
|
|
2119
|
+
"<agent-admin-ui><admin-settings-ui></admin-settings-ui></agent-admin-ui>"
|
|
2120
|
+
]
|
|
2121
|
+
},
|
|
2122
|
+
});
|
|
2123
|
+
}
|
|
2124
|
+
|
|
2125
|
+
{
|
|
2126
|
+
// GENERATED: do not hand-edit. Source: packages/web-modules/shell/admin-shell/admin-shell.yaml's a2ui.allowedParents/allowedChildren.
|
|
1564
2127
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
1565
2128
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
1566
2129
|
|
|
@@ -1568,15 +2131,16 @@ RULES.push({
|
|
|
1568
2131
|
const TAG = "admin-shell";
|
|
1569
2132
|
const ALLOWED_PARENTS = ["Surface"];
|
|
1570
2133
|
const ALLOWED_CHILDREN = [];
|
|
2134
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
1571
2135
|
|
|
1572
2136
|
|
|
1573
2137
|
RULES.push({
|
|
1574
2138
|
id: "COMPOSITION-ADMIN-SHELL",
|
|
1575
|
-
severity: '
|
|
2139
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
1576
2140
|
scope: 'shared',
|
|
1577
2141
|
fileTypes: MARKUP_EXT,
|
|
1578
2142
|
match(text) {
|
|
1579
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
2143
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
1580
2144
|
},
|
|
1581
2145
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
1582
2146
|
fixtures: {
|
|
@@ -1591,7 +2155,7 @@ RULES.push({
|
|
|
1591
2155
|
}
|
|
1592
2156
|
|
|
1593
2157
|
{
|
|
1594
|
-
// GENERATED
|
|
2158
|
+
// GENERATED: do not hand-edit. Source: packages/web-modules/shell/admin-sidebar/admin-sidebar.yaml's a2ui.allowedParents/allowedChildren.
|
|
1595
2159
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
1596
2160
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
1597
2161
|
|
|
@@ -1599,15 +2163,16 @@ RULES.push({
|
|
|
1599
2163
|
const TAG = "admin-sidebar";
|
|
1600
2164
|
const ALLOWED_PARENTS = ["admin-shell"];
|
|
1601
2165
|
const ALLOWED_CHILDREN = [];
|
|
2166
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
1602
2167
|
|
|
1603
2168
|
|
|
1604
2169
|
RULES.push({
|
|
1605
2170
|
id: "COMPOSITION-ADMIN-SIDEBAR",
|
|
1606
|
-
severity: '
|
|
2171
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
1607
2172
|
scope: 'shared',
|
|
1608
2173
|
fileTypes: MARKUP_EXT,
|
|
1609
2174
|
match(text) {
|
|
1610
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
2175
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
1611
2176
|
},
|
|
1612
2177
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
1613
2178
|
fixtures: {
|
|
@@ -1622,7 +2187,7 @@ RULES.push({
|
|
|
1622
2187
|
}
|
|
1623
2188
|
|
|
1624
2189
|
{
|
|
1625
|
-
// GENERATED
|
|
2190
|
+
// GENERATED: do not hand-edit. Source: packages/web-modules/shell/admin-statusbar/admin-statusbar.yaml's a2ui.allowedParents/allowedChildren.
|
|
1626
2191
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
1627
2192
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
1628
2193
|
|
|
@@ -1630,15 +2195,16 @@ RULES.push({
|
|
|
1630
2195
|
const TAG = "admin-statusbar";
|
|
1631
2196
|
const ALLOWED_PARENTS = ["admin-shell","admin-content","admin-sidebar"];
|
|
1632
2197
|
const ALLOWED_CHILDREN = [];
|
|
2198
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
1633
2199
|
|
|
1634
2200
|
|
|
1635
2201
|
RULES.push({
|
|
1636
2202
|
id: "COMPOSITION-ADMIN-STATUSBAR",
|
|
1637
|
-
severity: '
|
|
2203
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
1638
2204
|
scope: 'shared',
|
|
1639
2205
|
fileTypes: MARKUP_EXT,
|
|
1640
2206
|
match(text) {
|
|
1641
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
2207
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
1642
2208
|
},
|
|
1643
2209
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
1644
2210
|
fixtures: {
|
|
@@ -1653,7 +2219,7 @@ RULES.push({
|
|
|
1653
2219
|
}
|
|
1654
2220
|
|
|
1655
2221
|
{
|
|
1656
|
-
// GENERATED
|
|
2222
|
+
// GENERATED: do not hand-edit. Source: packages/web-modules/shell/admin-topbar/admin-topbar.yaml's a2ui.allowedParents/allowedChildren.
|
|
1657
2223
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
1658
2224
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
1659
2225
|
|
|
@@ -1661,15 +2227,16 @@ RULES.push({
|
|
|
1661
2227
|
const TAG = "admin-topbar";
|
|
1662
2228
|
const ALLOWED_PARENTS = ["admin-shell","admin-content","admin-sidebar"];
|
|
1663
2229
|
const ALLOWED_CHILDREN = [];
|
|
2230
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
1664
2231
|
|
|
1665
2232
|
|
|
1666
2233
|
RULES.push({
|
|
1667
2234
|
id: "COMPOSITION-ADMIN-TOPBAR",
|
|
1668
|
-
severity: '
|
|
2235
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
1669
2236
|
scope: 'shared',
|
|
1670
2237
|
fileTypes: MARKUP_EXT,
|
|
1671
2238
|
match(text) {
|
|
1672
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
2239
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
1673
2240
|
},
|
|
1674
2241
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
1675
2242
|
fixtures: {
|
|
@@ -1684,7 +2251,105 @@ RULES.push({
|
|
|
1684
2251
|
}
|
|
1685
2252
|
|
|
1686
2253
|
{
|
|
1687
|
-
// GENERATED
|
|
2254
|
+
// GENERATED: do not hand-edit. Source: packages/web-modules/agent-admin/agent-admin/agent-admin.yaml's a2ui.allowedParents/allowedChildren.
|
|
2255
|
+
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2256
|
+
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2257
|
+
|
|
2258
|
+
|
|
2259
|
+
const TAG = "agent-admin-ui";
|
|
2260
|
+
const ALLOWED_PARENTS = [];
|
|
2261
|
+
const ALLOWED_CHILDREN = ["admin-roster-ui","admin-settings-ui","chat-shell"];
|
|
2262
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2263
|
+
|
|
2264
|
+
|
|
2265
|
+
RULES.push({
|
|
2266
|
+
id: "COMPOSITION-AGENT-ADMIN-UI",
|
|
2267
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2268
|
+
scope: 'shared',
|
|
2269
|
+
fileTypes: MARKUP_EXT,
|
|
2270
|
+
match(text) {
|
|
2271
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2272
|
+
},
|
|
2273
|
+
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2274
|
+
fixtures: {
|
|
2275
|
+
"smelly": [
|
|
2276
|
+
"<agent-admin-ui><not-an-allowed-child-ui></not-an-allowed-child-ui></agent-admin-ui>"
|
|
2277
|
+
],
|
|
2278
|
+
"clean": [
|
|
2279
|
+
"<agent-admin-ui><admin-roster-ui></admin-roster-ui></agent-admin-ui>",
|
|
2280
|
+
"<agent-admin-ui><not-an-allowed-child-ui slot=\"arbitrary-slot\"></not-an-allowed-child-ui></agent-admin-ui>"
|
|
2281
|
+
]
|
|
2282
|
+
},
|
|
2283
|
+
});
|
|
2284
|
+
}
|
|
2285
|
+
|
|
2286
|
+
{
|
|
2287
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/avatar/avatar-group.yaml's a2ui.allowedParents/allowedChildren.
|
|
2288
|
+
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2289
|
+
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2290
|
+
|
|
2291
|
+
|
|
2292
|
+
const TAG = "avatar-group-ui";
|
|
2293
|
+
const ALLOWED_PARENTS = [];
|
|
2294
|
+
const ALLOWED_CHILDREN = ["avatar-ui"];
|
|
2295
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2296
|
+
|
|
2297
|
+
|
|
2298
|
+
RULES.push({
|
|
2299
|
+
id: "COMPOSITION-AVATAR-GROUP-UI",
|
|
2300
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2301
|
+
scope: 'shared',
|
|
2302
|
+
fileTypes: MARKUP_EXT,
|
|
2303
|
+
match(text) {
|
|
2304
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2305
|
+
},
|
|
2306
|
+
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2307
|
+
fixtures: {
|
|
2308
|
+
"smelly": [
|
|
2309
|
+
"<avatar-group-ui><not-an-allowed-child-ui></not-an-allowed-child-ui></avatar-group-ui>"
|
|
2310
|
+
],
|
|
2311
|
+
"clean": [
|
|
2312
|
+
"<avatar-group-ui><avatar-ui></avatar-ui></avatar-group-ui>",
|
|
2313
|
+
"<avatar-group-ui><not-an-allowed-child-ui slot=\"arbitrary-slot\"></not-an-allowed-child-ui></avatar-group-ui>"
|
|
2314
|
+
]
|
|
2315
|
+
},
|
|
2316
|
+
});
|
|
2317
|
+
}
|
|
2318
|
+
|
|
2319
|
+
{
|
|
2320
|
+
// GENERATED: do not hand-edit. Source: packages/web-modules/chat/chat-composer/chat-composer.yaml's a2ui.allowedParents/allowedChildren.
|
|
2321
|
+
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2322
|
+
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2323
|
+
|
|
2324
|
+
|
|
2325
|
+
const TAG = "chat-composer";
|
|
2326
|
+
const ALLOWED_PARENTS = ["chat-shell"];
|
|
2327
|
+
const ALLOWED_CHILDREN = [];
|
|
2328
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2329
|
+
|
|
2330
|
+
|
|
2331
|
+
RULES.push({
|
|
2332
|
+
id: "COMPOSITION-CHAT-COMPOSER",
|
|
2333
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2334
|
+
scope: 'shared',
|
|
2335
|
+
fileTypes: MARKUP_EXT,
|
|
2336
|
+
match(text) {
|
|
2337
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2338
|
+
},
|
|
2339
|
+
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2340
|
+
fixtures: {
|
|
2341
|
+
"smelly": [
|
|
2342
|
+
"<div><chat-composer></chat-composer></div>"
|
|
2343
|
+
],
|
|
2344
|
+
"clean": [
|
|
2345
|
+
"<chat-shell><chat-composer></chat-composer></chat-shell>"
|
|
2346
|
+
]
|
|
2347
|
+
},
|
|
2348
|
+
});
|
|
2349
|
+
}
|
|
2350
|
+
|
|
2351
|
+
{
|
|
2352
|
+
// GENERATED: do not hand-edit. Source: packages/web-modules/chat/chat-empty/chat-empty.yaml's a2ui.allowedParents/allowedChildren.
|
|
1688
2353
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
1689
2354
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
1690
2355
|
|
|
@@ -1692,15 +2357,16 @@ RULES.push({
|
|
|
1692
2357
|
const TAG = "chat-empty";
|
|
1693
2358
|
const ALLOWED_PARENTS = ["chat-thread"];
|
|
1694
2359
|
const ALLOWED_CHILDREN = [];
|
|
2360
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
1695
2361
|
|
|
1696
2362
|
|
|
1697
2363
|
RULES.push({
|
|
1698
2364
|
id: "COMPOSITION-CHAT-EMPTY",
|
|
1699
|
-
severity: '
|
|
2365
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
1700
2366
|
scope: 'shared',
|
|
1701
2367
|
fileTypes: MARKUP_EXT,
|
|
1702
2368
|
match(text) {
|
|
1703
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
2369
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
1704
2370
|
},
|
|
1705
2371
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
1706
2372
|
fixtures: {
|
|
@@ -1715,7 +2381,7 @@ RULES.push({
|
|
|
1715
2381
|
}
|
|
1716
2382
|
|
|
1717
2383
|
{
|
|
1718
|
-
// GENERATED
|
|
2384
|
+
// GENERATED: do not hand-edit. Source: packages/web-modules/chat/chat-header/chat-header.yaml's a2ui.allowedParents/allowedChildren.
|
|
1719
2385
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
1720
2386
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
1721
2387
|
|
|
@@ -1723,15 +2389,16 @@ RULES.push({
|
|
|
1723
2389
|
const TAG = "chat-header";
|
|
1724
2390
|
const ALLOWED_PARENTS = ["chat-shell","chat-sidebar"];
|
|
1725
2391
|
const ALLOWED_CHILDREN = [];
|
|
2392
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
1726
2393
|
|
|
1727
2394
|
|
|
1728
2395
|
RULES.push({
|
|
1729
2396
|
id: "COMPOSITION-CHAT-HEADER",
|
|
1730
|
-
severity: '
|
|
2397
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
1731
2398
|
scope: 'shared',
|
|
1732
2399
|
fileTypes: MARKUP_EXT,
|
|
1733
2400
|
match(text) {
|
|
1734
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
2401
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
1735
2402
|
},
|
|
1736
2403
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
1737
2404
|
fixtures: {
|
|
@@ -1746,23 +2413,24 @@ RULES.push({
|
|
|
1746
2413
|
}
|
|
1747
2414
|
|
|
1748
2415
|
{
|
|
1749
|
-
// GENERATED
|
|
2416
|
+
// GENERATED: do not hand-edit. Source: packages/web-modules/chat/chat-shell/chat-shell.yaml's a2ui.allowedParents/allowedChildren.
|
|
1750
2417
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
1751
2418
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
1752
2419
|
|
|
1753
2420
|
|
|
1754
2421
|
const TAG = "chat-shell";
|
|
1755
|
-
const ALLOWED_PARENTS = ["Surface"];
|
|
2422
|
+
const ALLOWED_PARENTS = ["Surface","agent-admin-ui","pane-ui"];
|
|
1756
2423
|
const ALLOWED_CHILDREN = [];
|
|
2424
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
1757
2425
|
|
|
1758
2426
|
|
|
1759
2427
|
RULES.push({
|
|
1760
2428
|
id: "COMPOSITION-CHAT-SHELL",
|
|
1761
|
-
severity: '
|
|
2429
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
1762
2430
|
scope: 'shared',
|
|
1763
2431
|
fileTypes: MARKUP_EXT,
|
|
1764
2432
|
match(text) {
|
|
1765
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
2433
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
1766
2434
|
},
|
|
1767
2435
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
1768
2436
|
fixtures: {
|
|
@@ -1777,7 +2445,7 @@ RULES.push({
|
|
|
1777
2445
|
}
|
|
1778
2446
|
|
|
1779
2447
|
{
|
|
1780
|
-
// GENERATED
|
|
2448
|
+
// GENERATED: do not hand-edit. Source: packages/web-modules/chat/chat-sidebar/chat-sidebar.yaml's a2ui.allowedParents/allowedChildren.
|
|
1781
2449
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
1782
2450
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
1783
2451
|
|
|
@@ -1785,15 +2453,16 @@ RULES.push({
|
|
|
1785
2453
|
const TAG = "chat-sidebar";
|
|
1786
2454
|
const ALLOWED_PARENTS = ["chat-shell"];
|
|
1787
2455
|
const ALLOWED_CHILDREN = [];
|
|
2456
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
1788
2457
|
|
|
1789
2458
|
|
|
1790
2459
|
RULES.push({
|
|
1791
2460
|
id: "COMPOSITION-CHAT-SIDEBAR",
|
|
1792
|
-
severity: '
|
|
2461
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
1793
2462
|
scope: 'shared',
|
|
1794
2463
|
fileTypes: MARKUP_EXT,
|
|
1795
2464
|
match(text) {
|
|
1796
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
2465
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
1797
2466
|
},
|
|
1798
2467
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
1799
2468
|
fixtures: {
|
|
@@ -1808,7 +2477,7 @@ RULES.push({
|
|
|
1808
2477
|
}
|
|
1809
2478
|
|
|
1810
2479
|
{
|
|
1811
|
-
// GENERATED
|
|
2480
|
+
// GENERATED: do not hand-edit. Source: packages/web-modules/chat/chat-status/chat-status.yaml's a2ui.allowedParents/allowedChildren.
|
|
1812
2481
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
1813
2482
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
1814
2483
|
|
|
@@ -1816,15 +2485,16 @@ RULES.push({
|
|
|
1816
2485
|
const TAG = "chat-status";
|
|
1817
2486
|
const ALLOWED_PARENTS = ["chat-header"];
|
|
1818
2487
|
const ALLOWED_CHILDREN = [];
|
|
2488
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
1819
2489
|
|
|
1820
2490
|
|
|
1821
2491
|
RULES.push({
|
|
1822
2492
|
id: "COMPOSITION-CHAT-STATUS",
|
|
1823
|
-
severity: '
|
|
2493
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
1824
2494
|
scope: 'shared',
|
|
1825
2495
|
fileTypes: MARKUP_EXT,
|
|
1826
2496
|
match(text) {
|
|
1827
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
2497
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
1828
2498
|
},
|
|
1829
2499
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
1830
2500
|
fixtures: {
|
|
@@ -1839,7 +2509,7 @@ RULES.push({
|
|
|
1839
2509
|
}
|
|
1840
2510
|
|
|
1841
2511
|
{
|
|
1842
|
-
// GENERATED
|
|
2512
|
+
// GENERATED: do not hand-edit. Source: packages/web-modules/chat/chat-thread/chat-thread.yaml's a2ui.allowedParents/allowedChildren.
|
|
1843
2513
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
1844
2514
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
1845
2515
|
|
|
@@ -1847,15 +2517,16 @@ RULES.push({
|
|
|
1847
2517
|
const TAG = "chat-thread";
|
|
1848
2518
|
const ALLOWED_PARENTS = ["chat-shell"];
|
|
1849
2519
|
const ALLOWED_CHILDREN = [];
|
|
2520
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
1850
2521
|
|
|
1851
2522
|
|
|
1852
2523
|
RULES.push({
|
|
1853
2524
|
id: "COMPOSITION-CHAT-THREAD",
|
|
1854
|
-
severity: '
|
|
2525
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
1855
2526
|
scope: 'shared',
|
|
1856
2527
|
fileTypes: MARKUP_EXT,
|
|
1857
2528
|
match(text) {
|
|
1858
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
2529
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
1859
2530
|
},
|
|
1860
2531
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
1861
2532
|
fixtures: {
|
|
@@ -1870,7 +2541,7 @@ RULES.push({
|
|
|
1870
2541
|
}
|
|
1871
2542
|
|
|
1872
2543
|
{
|
|
1873
|
-
// GENERATED
|
|
2544
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/choice-card/choice-card.yaml's a2ui.allowedParents/allowedChildren.
|
|
1874
2545
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
1875
2546
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
1876
2547
|
|
|
@@ -1878,15 +2549,16 @@ RULES.push({
|
|
|
1878
2549
|
const TAG = "choice-card-ui";
|
|
1879
2550
|
const ALLOWED_PARENTS = [];
|
|
1880
2551
|
const ALLOWED_CHILDREN = ["choice-ui"];
|
|
2552
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
1881
2553
|
|
|
1882
2554
|
|
|
1883
2555
|
RULES.push({
|
|
1884
2556
|
id: "COMPOSITION-CHOICE-CARD-UI",
|
|
1885
|
-
severity: '
|
|
2557
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
1886
2558
|
scope: 'shared',
|
|
1887
2559
|
fileTypes: MARKUP_EXT,
|
|
1888
2560
|
match(text) {
|
|
1889
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
2561
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
1890
2562
|
},
|
|
1891
2563
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
1892
2564
|
fixtures: {
|
|
@@ -1894,14 +2566,15 @@ RULES.push({
|
|
|
1894
2566
|
"<choice-card-ui><not-an-allowed-child-ui></not-an-allowed-child-ui></choice-card-ui>"
|
|
1895
2567
|
],
|
|
1896
2568
|
"clean": [
|
|
1897
|
-
"<choice-card-ui><choice-ui></choice-ui></choice-card-ui>"
|
|
2569
|
+
"<choice-card-ui><choice-ui></choice-ui></choice-card-ui>",
|
|
2570
|
+
"<choice-card-ui><not-an-allowed-child-ui slot=\"arbitrary-slot\"></not-an-allowed-child-ui></choice-card-ui>"
|
|
1898
2571
|
]
|
|
1899
2572
|
},
|
|
1900
2573
|
});
|
|
1901
2574
|
}
|
|
1902
2575
|
|
|
1903
2576
|
{
|
|
1904
|
-
// GENERATED
|
|
2577
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/choice-card/choice.yaml's a2ui.allowedParents/allowedChildren.
|
|
1905
2578
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
1906
2579
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
1907
2580
|
|
|
@@ -1909,15 +2582,16 @@ RULES.push({
|
|
|
1909
2582
|
const TAG = "choice-ui";
|
|
1910
2583
|
const ALLOWED_PARENTS = ["choice-card-ui"];
|
|
1911
2584
|
const ALLOWED_CHILDREN = [];
|
|
2585
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
1912
2586
|
|
|
1913
2587
|
|
|
1914
2588
|
RULES.push({
|
|
1915
2589
|
id: "COMPOSITION-CHOICE-UI",
|
|
1916
|
-
severity: '
|
|
2590
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
1917
2591
|
scope: 'shared',
|
|
1918
2592
|
fileTypes: MARKUP_EXT,
|
|
1919
2593
|
match(text) {
|
|
1920
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
2594
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
1921
2595
|
},
|
|
1922
2596
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
1923
2597
|
fixtures: {
|
|
@@ -1932,7 +2606,7 @@ RULES.push({
|
|
|
1932
2606
|
}
|
|
1933
2607
|
|
|
1934
2608
|
{
|
|
1935
|
-
// GENERATED
|
|
2609
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/drilldown/drilldown.yaml's a2ui.allowedParents/allowedChildren.
|
|
1936
2610
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
1937
2611
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
1938
2612
|
|
|
@@ -1940,15 +2614,16 @@ RULES.push({
|
|
|
1940
2614
|
const TAG = "drilldown-ui";
|
|
1941
2615
|
const ALLOWED_PARENTS = [];
|
|
1942
2616
|
const ALLOWED_CHILDREN = ["breadcrumb-ui"];
|
|
2617
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
1943
2618
|
|
|
1944
2619
|
|
|
1945
2620
|
RULES.push({
|
|
1946
2621
|
id: "COMPOSITION-DRILLDOWN-UI",
|
|
1947
|
-
severity: '
|
|
2622
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
1948
2623
|
scope: 'shared',
|
|
1949
2624
|
fileTypes: MARKUP_EXT,
|
|
1950
2625
|
match(text) {
|
|
1951
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
2626
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
1952
2627
|
},
|
|
1953
2628
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
1954
2629
|
fixtures: {
|
|
@@ -1956,14 +2631,15 @@ RULES.push({
|
|
|
1956
2631
|
"<drilldown-ui><not-an-allowed-child-ui></not-an-allowed-child-ui></drilldown-ui>"
|
|
1957
2632
|
],
|
|
1958
2633
|
"clean": [
|
|
1959
|
-
"<drilldown-ui><breadcrumb-ui></breadcrumb-ui></drilldown-ui>"
|
|
2634
|
+
"<drilldown-ui><breadcrumb-ui></breadcrumb-ui></drilldown-ui>",
|
|
2635
|
+
"<drilldown-ui><not-an-allowed-child-ui slot=\"arbitrary-slot\"></not-an-allowed-child-ui></drilldown-ui>"
|
|
1960
2636
|
]
|
|
1961
2637
|
},
|
|
1962
2638
|
});
|
|
1963
2639
|
}
|
|
1964
2640
|
|
|
1965
2641
|
{
|
|
1966
|
-
// GENERATED
|
|
2642
|
+
// GENERATED: do not hand-edit. Source: packages/web-modules/editor/editor-canvas-empty/editor-canvas-empty.yaml's a2ui.allowedParents/allowedChildren.
|
|
1967
2643
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
1968
2644
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
1969
2645
|
|
|
@@ -1971,15 +2647,16 @@ RULES.push({
|
|
|
1971
2647
|
const TAG = "editor-canvas-empty";
|
|
1972
2648
|
const ALLOWED_PARENTS = ["editor-canvas"];
|
|
1973
2649
|
const ALLOWED_CHILDREN = [];
|
|
2650
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
1974
2651
|
|
|
1975
2652
|
|
|
1976
2653
|
RULES.push({
|
|
1977
2654
|
id: "COMPOSITION-EDITOR-CANVAS-EMPTY",
|
|
1978
|
-
severity: '
|
|
2655
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
1979
2656
|
scope: 'shared',
|
|
1980
2657
|
fileTypes: MARKUP_EXT,
|
|
1981
2658
|
match(text) {
|
|
1982
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
2659
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
1983
2660
|
},
|
|
1984
2661
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
1985
2662
|
fixtures: {
|
|
@@ -1994,7 +2671,7 @@ RULES.push({
|
|
|
1994
2671
|
}
|
|
1995
2672
|
|
|
1996
2673
|
{
|
|
1997
|
-
// GENERATED
|
|
2674
|
+
// GENERATED: do not hand-edit. Source: packages/web-modules/editor/editor-canvas-toolbar/editor-canvas-toolbar.yaml's a2ui.allowedParents/allowedChildren.
|
|
1998
2675
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
1999
2676
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2000
2677
|
|
|
@@ -2002,15 +2679,16 @@ RULES.push({
|
|
|
2002
2679
|
const TAG = "editor-canvas-toolbar";
|
|
2003
2680
|
const ALLOWED_PARENTS = ["editor-canvas"];
|
|
2004
2681
|
const ALLOWED_CHILDREN = [];
|
|
2682
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2005
2683
|
|
|
2006
2684
|
|
|
2007
2685
|
RULES.push({
|
|
2008
2686
|
id: "COMPOSITION-EDITOR-CANVAS-TOOLBAR",
|
|
2009
|
-
severity: '
|
|
2687
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2010
2688
|
scope: 'shared',
|
|
2011
2689
|
fileTypes: MARKUP_EXT,
|
|
2012
2690
|
match(text) {
|
|
2013
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
2691
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2014
2692
|
},
|
|
2015
2693
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2016
2694
|
fixtures: {
|
|
@@ -2025,7 +2703,7 @@ RULES.push({
|
|
|
2025
2703
|
}
|
|
2026
2704
|
|
|
2027
2705
|
{
|
|
2028
|
-
// GENERATED
|
|
2706
|
+
// GENERATED: do not hand-edit. Source: packages/web-modules/editor/editor-canvas/editor-canvas.yaml's a2ui.allowedParents/allowedChildren.
|
|
2029
2707
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2030
2708
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2031
2709
|
|
|
@@ -2033,15 +2711,16 @@ RULES.push({
|
|
|
2033
2711
|
const TAG = "editor-canvas";
|
|
2034
2712
|
const ALLOWED_PARENTS = ["editor-shell"];
|
|
2035
2713
|
const ALLOWED_CHILDREN = [];
|
|
2714
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2036
2715
|
|
|
2037
2716
|
|
|
2038
2717
|
RULES.push({
|
|
2039
2718
|
id: "COMPOSITION-EDITOR-CANVAS",
|
|
2040
|
-
severity: '
|
|
2719
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2041
2720
|
scope: 'shared',
|
|
2042
2721
|
fileTypes: MARKUP_EXT,
|
|
2043
2722
|
match(text) {
|
|
2044
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
2723
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2045
2724
|
},
|
|
2046
2725
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2047
2726
|
fixtures: {
|
|
@@ -2056,7 +2735,7 @@ RULES.push({
|
|
|
2056
2735
|
}
|
|
2057
2736
|
|
|
2058
2737
|
{
|
|
2059
|
-
// GENERATED
|
|
2738
|
+
// GENERATED: do not hand-edit. Source: packages/web-modules/editor/editor-shell/editor-shell.yaml's a2ui.allowedParents/allowedChildren.
|
|
2060
2739
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2061
2740
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2062
2741
|
|
|
@@ -2064,15 +2743,16 @@ RULES.push({
|
|
|
2064
2743
|
const TAG = "editor-shell";
|
|
2065
2744
|
const ALLOWED_PARENTS = ["Surface"];
|
|
2066
2745
|
const ALLOWED_CHILDREN = [];
|
|
2746
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2067
2747
|
|
|
2068
2748
|
|
|
2069
2749
|
RULES.push({
|
|
2070
2750
|
id: "COMPOSITION-EDITOR-SHELL",
|
|
2071
|
-
severity: '
|
|
2751
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2072
2752
|
scope: 'shared',
|
|
2073
2753
|
fileTypes: MARKUP_EXT,
|
|
2074
2754
|
match(text) {
|
|
2075
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
2755
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2076
2756
|
},
|
|
2077
2757
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2078
2758
|
fixtures: {
|
|
@@ -2087,7 +2767,7 @@ RULES.push({
|
|
|
2087
2767
|
}
|
|
2088
2768
|
|
|
2089
2769
|
{
|
|
2090
|
-
// GENERATED
|
|
2770
|
+
// GENERATED: do not hand-edit. Source: packages/web-modules/editor/editor-sidebar/editor-sidebar.yaml's a2ui.allowedParents/allowedChildren.
|
|
2091
2771
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2092
2772
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2093
2773
|
|
|
@@ -2095,15 +2775,16 @@ RULES.push({
|
|
|
2095
2775
|
const TAG = "editor-sidebar";
|
|
2096
2776
|
const ALLOWED_PARENTS = ["editor-shell"];
|
|
2097
2777
|
const ALLOWED_CHILDREN = [];
|
|
2778
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2098
2779
|
|
|
2099
2780
|
|
|
2100
2781
|
RULES.push({
|
|
2101
2782
|
id: "COMPOSITION-EDITOR-SIDEBAR",
|
|
2102
|
-
severity: '
|
|
2783
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2103
2784
|
scope: 'shared',
|
|
2104
2785
|
fileTypes: MARKUP_EXT,
|
|
2105
2786
|
match(text) {
|
|
2106
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
2787
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2107
2788
|
},
|
|
2108
2789
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2109
2790
|
fixtures: {
|
|
@@ -2118,7 +2799,7 @@ RULES.push({
|
|
|
2118
2799
|
}
|
|
2119
2800
|
|
|
2120
2801
|
{
|
|
2121
|
-
// GENERATED
|
|
2802
|
+
// GENERATED: do not hand-edit. Source: packages/web-modules/editor/editor-statusbar/editor-statusbar.yaml's a2ui.allowedParents/allowedChildren.
|
|
2122
2803
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2123
2804
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2124
2805
|
|
|
@@ -2126,15 +2807,16 @@ RULES.push({
|
|
|
2126
2807
|
const TAG = "editor-statusbar";
|
|
2127
2808
|
const ALLOWED_PARENTS = ["editor-shell"];
|
|
2128
2809
|
const ALLOWED_CHILDREN = [];
|
|
2810
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2129
2811
|
|
|
2130
2812
|
|
|
2131
2813
|
RULES.push({
|
|
2132
2814
|
id: "COMPOSITION-EDITOR-STATUSBAR",
|
|
2133
|
-
severity: '
|
|
2815
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2134
2816
|
scope: 'shared',
|
|
2135
2817
|
fileTypes: MARKUP_EXT,
|
|
2136
2818
|
match(text) {
|
|
2137
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
2819
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2138
2820
|
},
|
|
2139
2821
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2140
2822
|
fixtures: {
|
|
@@ -2149,7 +2831,7 @@ RULES.push({
|
|
|
2149
2831
|
}
|
|
2150
2832
|
|
|
2151
2833
|
{
|
|
2152
|
-
// GENERATED
|
|
2834
|
+
// GENERATED: do not hand-edit. Source: packages/web-modules/editor/editor-toolbar/editor-toolbar.yaml's a2ui.allowedParents/allowedChildren.
|
|
2153
2835
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2154
2836
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2155
2837
|
|
|
@@ -2157,15 +2839,16 @@ RULES.push({
|
|
|
2157
2839
|
const TAG = "editor-toolbar";
|
|
2158
2840
|
const ALLOWED_PARENTS = ["editor-shell"];
|
|
2159
2841
|
const ALLOWED_CHILDREN = [];
|
|
2842
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2160
2843
|
|
|
2161
2844
|
|
|
2162
2845
|
RULES.push({
|
|
2163
2846
|
id: "COMPOSITION-EDITOR-TOOLBAR",
|
|
2164
|
-
severity: '
|
|
2847
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2165
2848
|
scope: 'shared',
|
|
2166
2849
|
fileTypes: MARKUP_EXT,
|
|
2167
2850
|
match(text) {
|
|
2168
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
2851
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2169
2852
|
},
|
|
2170
2853
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2171
2854
|
fixtures: {
|
|
@@ -2180,7 +2863,39 @@ RULES.push({
|
|
|
2180
2863
|
}
|
|
2181
2864
|
|
|
2182
2865
|
{
|
|
2183
|
-
// GENERATED
|
|
2866
|
+
// GENERATED: do not hand-edit. Source: packages/web-modules/shell/embed-shell/embed-shell.yaml's a2ui.allowedParents/allowedChildren.
|
|
2867
|
+
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2868
|
+
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2869
|
+
|
|
2870
|
+
|
|
2871
|
+
const TAG = "embed-shell";
|
|
2872
|
+
const ALLOWED_PARENTS = ["Surface","theme-provider"];
|
|
2873
|
+
const ALLOWED_CHILDREN = [];
|
|
2874
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2875
|
+
|
|
2876
|
+
|
|
2877
|
+
RULES.push({
|
|
2878
|
+
id: "COMPOSITION-EMBED-SHELL",
|
|
2879
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2880
|
+
scope: 'shared',
|
|
2881
|
+
fileTypes: MARKUP_EXT,
|
|
2882
|
+
match(text) {
|
|
2883
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2884
|
+
},
|
|
2885
|
+
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2886
|
+
fixtures: {
|
|
2887
|
+
"smelly": [
|
|
2888
|
+
"<col-ui><embed-shell></embed-shell></col-ui>"
|
|
2889
|
+
],
|
|
2890
|
+
"clean": [
|
|
2891
|
+
"<embed-shell></embed-shell>"
|
|
2892
|
+
]
|
|
2893
|
+
},
|
|
2894
|
+
});
|
|
2895
|
+
}
|
|
2896
|
+
|
|
2897
|
+
{
|
|
2898
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/feed/feed-item.yaml's a2ui.allowedParents/allowedChildren.
|
|
2184
2899
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2185
2900
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2186
2901
|
|
|
@@ -2188,15 +2903,16 @@ RULES.push({
|
|
|
2188
2903
|
const TAG = "feed-item-ui";
|
|
2189
2904
|
const ALLOWED_PARENTS = ["feed-ui"];
|
|
2190
2905
|
const ALLOWED_CHILDREN = [];
|
|
2906
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2191
2907
|
|
|
2192
2908
|
|
|
2193
2909
|
RULES.push({
|
|
2194
2910
|
id: "COMPOSITION-FEED-ITEM-UI",
|
|
2195
|
-
severity: '
|
|
2911
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2196
2912
|
scope: 'shared',
|
|
2197
2913
|
fileTypes: MARKUP_EXT,
|
|
2198
2914
|
match(text) {
|
|
2199
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
2915
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2200
2916
|
},
|
|
2201
2917
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2202
2918
|
fixtures: {
|
|
@@ -2211,7 +2927,7 @@ RULES.push({
|
|
|
2211
2927
|
}
|
|
2212
2928
|
|
|
2213
2929
|
{
|
|
2214
|
-
// GENERATED
|
|
2930
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/feed/feed.yaml's a2ui.allowedParents/allowedChildren.
|
|
2215
2931
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2216
2932
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2217
2933
|
|
|
@@ -2219,185 +2935,520 @@ RULES.push({
|
|
|
2219
2935
|
const TAG = "feed-ui";
|
|
2220
2936
|
const ALLOWED_PARENTS = [];
|
|
2221
2937
|
const ALLOWED_CHILDREN = ["feed-item-ui"];
|
|
2938
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2939
|
+
|
|
2940
|
+
|
|
2941
|
+
RULES.push({
|
|
2942
|
+
id: "COMPOSITION-FEED-UI",
|
|
2943
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2944
|
+
scope: 'shared',
|
|
2945
|
+
fileTypes: MARKUP_EXT,
|
|
2946
|
+
match(text) {
|
|
2947
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2948
|
+
},
|
|
2949
|
+
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2950
|
+
fixtures: {
|
|
2951
|
+
"smelly": [
|
|
2952
|
+
"<feed-ui><not-an-allowed-child-ui></not-an-allowed-child-ui></feed-ui>"
|
|
2953
|
+
],
|
|
2954
|
+
"clean": [
|
|
2955
|
+
"<feed-ui><feed-item-ui></feed-item-ui></feed-ui>",
|
|
2956
|
+
"<feed-ui><not-an-allowed-child-ui slot=\"arbitrary-slot\"></not-an-allowed-child-ui></feed-ui>"
|
|
2957
|
+
]
|
|
2958
|
+
},
|
|
2959
|
+
});
|
|
2960
|
+
}
|
|
2961
|
+
|
|
2962
|
+
{
|
|
2963
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/fields/fields.yaml's a2ui.allowedParents/allowedChildren.
|
|
2964
|
+
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2965
|
+
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2966
|
+
|
|
2967
|
+
|
|
2968
|
+
const TAG = "fields-ui";
|
|
2969
|
+
const ALLOWED_PARENTS = [];
|
|
2970
|
+
const ALLOWED_CHILDREN = ["field-ui"];
|
|
2971
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2972
|
+
|
|
2973
|
+
|
|
2974
|
+
RULES.push({
|
|
2975
|
+
id: "COMPOSITION-FIELDS-UI",
|
|
2976
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2977
|
+
scope: 'shared',
|
|
2978
|
+
fileTypes: MARKUP_EXT,
|
|
2979
|
+
match(text) {
|
|
2980
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2981
|
+
},
|
|
2982
|
+
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2983
|
+
fixtures: {
|
|
2984
|
+
"smelly": [
|
|
2985
|
+
"<fields-ui><not-an-allowed-child-ui></not-an-allowed-child-ui></fields-ui>"
|
|
2986
|
+
],
|
|
2987
|
+
"clean": [
|
|
2988
|
+
"<fields-ui><field-ui></field-ui></fields-ui>",
|
|
2989
|
+
"<fields-ui><not-an-allowed-child-ui slot=\"arbitrary-slot\"></not-an-allowed-child-ui></fields-ui>"
|
|
2990
|
+
]
|
|
2991
|
+
},
|
|
2992
|
+
});
|
|
2993
|
+
}
|
|
2994
|
+
|
|
2995
|
+
{
|
|
2996
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/footer/footer.yaml's a2ui.allowedParents/allowedChildren.
|
|
2997
|
+
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2998
|
+
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2999
|
+
|
|
3000
|
+
|
|
3001
|
+
const TAG = "footer-ui";
|
|
3002
|
+
const ALLOWED_PARENTS = ["page-ui"];
|
|
3003
|
+
const ALLOWED_CHILDREN = [];
|
|
3004
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
3005
|
+
|
|
3006
|
+
|
|
3007
|
+
RULES.push({
|
|
3008
|
+
id: "COMPOSITION-FOOTER-UI",
|
|
3009
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
3010
|
+
scope: 'shared',
|
|
3011
|
+
fileTypes: MARKUP_EXT,
|
|
3012
|
+
match(text) {
|
|
3013
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
3014
|
+
},
|
|
3015
|
+
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
3016
|
+
fixtures: {
|
|
3017
|
+
"smelly": [
|
|
3018
|
+
"<div><footer-ui></footer-ui></div>"
|
|
3019
|
+
],
|
|
3020
|
+
"clean": [
|
|
3021
|
+
"<page-ui><footer-ui></footer-ui></page-ui>"
|
|
3022
|
+
]
|
|
3023
|
+
},
|
|
3024
|
+
});
|
|
3025
|
+
}
|
|
3026
|
+
|
|
3027
|
+
{
|
|
3028
|
+
// GENERATED: do not hand-edit. Source: packages/web-modules/form/form-popover/form-popover.yaml's a2ui.allowedParents/allowedChildren.
|
|
3029
|
+
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
3030
|
+
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
3031
|
+
|
|
3032
|
+
|
|
3033
|
+
const TAG = "form-popover-ui";
|
|
3034
|
+
const ALLOWED_PARENTS = [];
|
|
3035
|
+
const ALLOWED_CHILDREN = ["check-ui","radio-ui","input-ui","textarea-ui","divider-ui","field-ui"];
|
|
3036
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
3037
|
+
|
|
3038
|
+
|
|
3039
|
+
RULES.push({
|
|
3040
|
+
id: "COMPOSITION-FORM-POPOVER-UI",
|
|
3041
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
3042
|
+
scope: 'shared',
|
|
3043
|
+
fileTypes: MARKUP_EXT,
|
|
3044
|
+
match(text) {
|
|
3045
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
3046
|
+
},
|
|
3047
|
+
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
3048
|
+
fixtures: {
|
|
3049
|
+
"smelly": [
|
|
3050
|
+
"<form-popover-ui><not-an-allowed-child-ui></not-an-allowed-child-ui></form-popover-ui>"
|
|
3051
|
+
],
|
|
3052
|
+
"clean": [
|
|
3053
|
+
"<form-popover-ui><check-ui></check-ui></form-popover-ui>",
|
|
3054
|
+
"<form-popover-ui><not-an-allowed-child-ui slot=\"arbitrary-slot\"></not-an-allowed-child-ui></form-popover-ui>"
|
|
3055
|
+
]
|
|
3056
|
+
},
|
|
3057
|
+
});
|
|
3058
|
+
}
|
|
3059
|
+
|
|
3060
|
+
{
|
|
3061
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/header/header.yaml's a2ui.allowedParents/allowedChildren.
|
|
3062
|
+
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
3063
|
+
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
3064
|
+
|
|
3065
|
+
|
|
3066
|
+
const TAG = "header-ui";
|
|
3067
|
+
const ALLOWED_PARENTS = ["page-ui"];
|
|
3068
|
+
const ALLOWED_CHILDREN = [];
|
|
3069
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
3070
|
+
|
|
3071
|
+
|
|
3072
|
+
RULES.push({
|
|
3073
|
+
id: "COMPOSITION-HEADER-UI",
|
|
3074
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
3075
|
+
scope: 'shared',
|
|
3076
|
+
fileTypes: MARKUP_EXT,
|
|
3077
|
+
match(text) {
|
|
3078
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
3079
|
+
},
|
|
3080
|
+
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
3081
|
+
fixtures: {
|
|
3082
|
+
"smelly": [
|
|
3083
|
+
"<div><header-ui></header-ui></div>"
|
|
3084
|
+
],
|
|
3085
|
+
"clean": [
|
|
3086
|
+
"<page-ui><header-ui></header-ui></page-ui>"
|
|
3087
|
+
]
|
|
3088
|
+
},
|
|
3089
|
+
});
|
|
3090
|
+
}
|
|
3091
|
+
|
|
3092
|
+
{
|
|
3093
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/list/list-item.yaml's a2ui.allowedParents/allowedChildren.
|
|
3094
|
+
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
3095
|
+
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
3096
|
+
|
|
3097
|
+
|
|
3098
|
+
const TAG = "list-item-ui";
|
|
3099
|
+
const ALLOWED_PARENTS = ["list-ui"];
|
|
3100
|
+
const ALLOWED_CHILDREN = [];
|
|
3101
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
3102
|
+
|
|
3103
|
+
|
|
3104
|
+
RULES.push({
|
|
3105
|
+
id: "COMPOSITION-LIST-ITEM-UI",
|
|
3106
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
3107
|
+
scope: 'shared',
|
|
3108
|
+
fileTypes: MARKUP_EXT,
|
|
3109
|
+
match(text) {
|
|
3110
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
3111
|
+
},
|
|
3112
|
+
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
3113
|
+
fixtures: {
|
|
3114
|
+
"smelly": [
|
|
3115
|
+
"<div><list-item-ui></list-item-ui></div>"
|
|
3116
|
+
],
|
|
3117
|
+
"clean": [
|
|
3118
|
+
"<list-ui><list-item-ui></list-item-ui></list-ui>"
|
|
3119
|
+
]
|
|
3120
|
+
},
|
|
3121
|
+
});
|
|
3122
|
+
}
|
|
3123
|
+
|
|
3124
|
+
{
|
|
3125
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/menu/menu-divider.yaml's a2ui.allowedParents/allowedChildren.
|
|
3126
|
+
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
3127
|
+
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
3128
|
+
|
|
3129
|
+
|
|
3130
|
+
const TAG = "menu-divider-ui";
|
|
3131
|
+
const ALLOWED_PARENTS = ["menu-ui","context-menu-ui"];
|
|
3132
|
+
const ALLOWED_CHILDREN = [];
|
|
3133
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
3134
|
+
|
|
3135
|
+
|
|
3136
|
+
RULES.push({
|
|
3137
|
+
id: "COMPOSITION-MENU-DIVIDER-UI",
|
|
3138
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
3139
|
+
scope: 'shared',
|
|
3140
|
+
fileTypes: MARKUP_EXT,
|
|
3141
|
+
match(text) {
|
|
3142
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
3143
|
+
},
|
|
3144
|
+
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
3145
|
+
fixtures: {
|
|
3146
|
+
"smelly": [
|
|
3147
|
+
"<div><menu-divider-ui></menu-divider-ui></div>"
|
|
3148
|
+
],
|
|
3149
|
+
"clean": [
|
|
3150
|
+
"<menu-ui><menu-divider-ui></menu-divider-ui></menu-ui>"
|
|
3151
|
+
]
|
|
3152
|
+
},
|
|
3153
|
+
});
|
|
3154
|
+
}
|
|
3155
|
+
|
|
3156
|
+
{
|
|
3157
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/menu/menu-item.yaml's a2ui.allowedParents/allowedChildren.
|
|
3158
|
+
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
3159
|
+
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
3160
|
+
|
|
3161
|
+
|
|
3162
|
+
const TAG = "menu-item-ui";
|
|
3163
|
+
const ALLOWED_PARENTS = ["menu-ui","context-menu-ui"];
|
|
3164
|
+
const ALLOWED_CHILDREN = [];
|
|
3165
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
3166
|
+
|
|
3167
|
+
|
|
3168
|
+
RULES.push({
|
|
3169
|
+
id: "COMPOSITION-MENU-ITEM-UI",
|
|
3170
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
3171
|
+
scope: 'shared',
|
|
3172
|
+
fileTypes: MARKUP_EXT,
|
|
3173
|
+
match(text) {
|
|
3174
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
3175
|
+
},
|
|
3176
|
+
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
3177
|
+
fixtures: {
|
|
3178
|
+
"smelly": [
|
|
3179
|
+
"<div><menu-item-ui></menu-item-ui></div>"
|
|
3180
|
+
],
|
|
3181
|
+
"clean": [
|
|
3182
|
+
"<menu-ui><menu-item-ui></menu-item-ui></menu-ui>"
|
|
3183
|
+
]
|
|
3184
|
+
},
|
|
3185
|
+
});
|
|
3186
|
+
}
|
|
3187
|
+
|
|
3188
|
+
{
|
|
3189
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/menu/menu-label.yaml's a2ui.allowedParents/allowedChildren.
|
|
3190
|
+
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
3191
|
+
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
3192
|
+
|
|
3193
|
+
|
|
3194
|
+
const TAG = "menu-label-ui";
|
|
3195
|
+
const ALLOWED_PARENTS = ["menu-ui"];
|
|
3196
|
+
const ALLOWED_CHILDREN = [];
|
|
3197
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
3198
|
+
|
|
3199
|
+
|
|
3200
|
+
RULES.push({
|
|
3201
|
+
id: "COMPOSITION-MENU-LABEL-UI",
|
|
3202
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
3203
|
+
scope: 'shared',
|
|
3204
|
+
fileTypes: MARKUP_EXT,
|
|
3205
|
+
match(text) {
|
|
3206
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
3207
|
+
},
|
|
3208
|
+
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
3209
|
+
fixtures: {
|
|
3210
|
+
"smelly": [
|
|
3211
|
+
"<div><menu-label-ui></menu-label-ui></div>"
|
|
3212
|
+
],
|
|
3213
|
+
"clean": [
|
|
3214
|
+
"<menu-ui><menu-label-ui></menu-label-ui></menu-ui>"
|
|
3215
|
+
]
|
|
3216
|
+
},
|
|
3217
|
+
});
|
|
3218
|
+
}
|
|
3219
|
+
|
|
3220
|
+
{
|
|
3221
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/menu/menu.yaml's a2ui.allowedParents/allowedChildren.
|
|
3222
|
+
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
3223
|
+
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
3224
|
+
|
|
3225
|
+
|
|
3226
|
+
const TAG = "menu-ui";
|
|
3227
|
+
const ALLOWED_PARENTS = [];
|
|
3228
|
+
const ALLOWED_CHILDREN = ["menu-item-ui","menu-divider-ui","menu-label-ui"];
|
|
3229
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
3230
|
+
|
|
3231
|
+
|
|
3232
|
+
RULES.push({
|
|
3233
|
+
id: "COMPOSITION-MENU-UI",
|
|
3234
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
3235
|
+
scope: 'shared',
|
|
3236
|
+
fileTypes: MARKUP_EXT,
|
|
3237
|
+
match(text) {
|
|
3238
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
3239
|
+
},
|
|
3240
|
+
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
3241
|
+
fixtures: {
|
|
3242
|
+
"smelly": [
|
|
3243
|
+
"<menu-ui><not-an-allowed-child-ui></not-an-allowed-child-ui></menu-ui>"
|
|
3244
|
+
],
|
|
3245
|
+
"clean": [
|
|
3246
|
+
"<menu-ui><menu-item-ui></menu-item-ui></menu-ui>",
|
|
3247
|
+
"<menu-ui><not-an-allowed-child-ui slot=\"arbitrary-slot\"></not-an-allowed-child-ui></menu-ui>"
|
|
3248
|
+
]
|
|
3249
|
+
},
|
|
3250
|
+
});
|
|
3251
|
+
}
|
|
3252
|
+
|
|
3253
|
+
{
|
|
3254
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/nav-group/nav-group.yaml's a2ui.allowedParents/allowedChildren.
|
|
3255
|
+
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
3256
|
+
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
3257
|
+
|
|
3258
|
+
|
|
3259
|
+
const TAG = "nav-group-ui";
|
|
3260
|
+
const ALLOWED_PARENTS = ["nav-ui"];
|
|
3261
|
+
const ALLOWED_CHILDREN = ["nav-item-ui"];
|
|
3262
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2222
3263
|
|
|
2223
3264
|
|
|
2224
3265
|
RULES.push({
|
|
2225
|
-
id: "COMPOSITION-
|
|
2226
|
-
severity: '
|
|
3266
|
+
id: "COMPOSITION-NAV-GROUP-UI",
|
|
3267
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2227
3268
|
scope: 'shared',
|
|
2228
3269
|
fileTypes: MARKUP_EXT,
|
|
2229
3270
|
match(text) {
|
|
2230
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
3271
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2231
3272
|
},
|
|
2232
3273
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2233
3274
|
fixtures: {
|
|
2234
3275
|
"smelly": [
|
|
2235
|
-
"<
|
|
3276
|
+
"<div><nav-group-ui></nav-group-ui></div>",
|
|
3277
|
+
"<nav-group-ui><not-an-allowed-child-ui></not-an-allowed-child-ui></nav-group-ui>"
|
|
2236
3278
|
],
|
|
2237
3279
|
"clean": [
|
|
2238
|
-
"<
|
|
3280
|
+
"<nav-ui><nav-group-ui></nav-group-ui></nav-ui>",
|
|
3281
|
+
"<nav-ui><nav-group-ui><nav-item-ui></nav-item-ui></nav-group-ui></nav-ui>",
|
|
3282
|
+
"<nav-ui><nav-group-ui><not-an-allowed-child-ui slot=\"arbitrary-slot\"></not-an-allowed-child-ui></nav-group-ui></nav-ui>"
|
|
2239
3283
|
]
|
|
2240
3284
|
},
|
|
2241
3285
|
});
|
|
2242
3286
|
}
|
|
2243
3287
|
|
|
2244
3288
|
{
|
|
2245
|
-
// GENERATED
|
|
3289
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/nav-item/nav-item.yaml's a2ui.allowedParents/allowedChildren.
|
|
2246
3290
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2247
3291
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2248
3292
|
|
|
2249
3293
|
|
|
2250
|
-
const TAG = "
|
|
2251
|
-
const ALLOWED_PARENTS = ["
|
|
3294
|
+
const TAG = "nav-item-ui";
|
|
3295
|
+
const ALLOWED_PARENTS = ["nav-ui","nav-group-ui"];
|
|
2252
3296
|
const ALLOWED_CHILDREN = [];
|
|
3297
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2253
3298
|
|
|
2254
3299
|
|
|
2255
3300
|
RULES.push({
|
|
2256
|
-
id: "COMPOSITION-
|
|
2257
|
-
severity: '
|
|
3301
|
+
id: "COMPOSITION-NAV-ITEM-UI",
|
|
3302
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2258
3303
|
scope: 'shared',
|
|
2259
3304
|
fileTypes: MARKUP_EXT,
|
|
2260
3305
|
match(text) {
|
|
2261
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
3306
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2262
3307
|
},
|
|
2263
3308
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2264
3309
|
fixtures: {
|
|
2265
3310
|
"smelly": [
|
|
2266
|
-
"<div><
|
|
3311
|
+
"<div><nav-item-ui></nav-item-ui></div>"
|
|
2267
3312
|
],
|
|
2268
3313
|
"clean": [
|
|
2269
|
-
"<
|
|
3314
|
+
"<nav-ui><nav-item-ui></nav-item-ui></nav-ui>"
|
|
2270
3315
|
]
|
|
2271
3316
|
},
|
|
2272
3317
|
});
|
|
2273
3318
|
}
|
|
2274
3319
|
|
|
2275
3320
|
{
|
|
2276
|
-
// GENERATED
|
|
3321
|
+
// GENERATED: do not hand-edit. Source: packages/web-modules/shell/page-scroll/page-scroll.yaml's a2ui.allowedParents/allowedChildren.
|
|
2277
3322
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2278
3323
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2279
3324
|
|
|
2280
3325
|
|
|
2281
|
-
const TAG = "
|
|
2282
|
-
const ALLOWED_PARENTS = ["
|
|
3326
|
+
const TAG = "page-scroll";
|
|
3327
|
+
const ALLOWED_PARENTS = ["admin-content"];
|
|
2283
3328
|
const ALLOWED_CHILDREN = [];
|
|
3329
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2284
3330
|
|
|
2285
3331
|
|
|
2286
3332
|
RULES.push({
|
|
2287
|
-
id: "COMPOSITION-
|
|
2288
|
-
severity: '
|
|
3333
|
+
id: "COMPOSITION-PAGE-SCROLL",
|
|
3334
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2289
3335
|
scope: 'shared',
|
|
2290
3336
|
fileTypes: MARKUP_EXT,
|
|
2291
3337
|
match(text) {
|
|
2292
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
3338
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2293
3339
|
},
|
|
2294
3340
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2295
3341
|
fixtures: {
|
|
2296
3342
|
"smelly": [
|
|
2297
|
-
"<div><
|
|
3343
|
+
"<div><page-scroll></page-scroll></div>"
|
|
2298
3344
|
],
|
|
2299
3345
|
"clean": [
|
|
2300
|
-
"<
|
|
3346
|
+
"<admin-content><page-scroll></page-scroll></admin-content>"
|
|
2301
3347
|
]
|
|
2302
3348
|
},
|
|
2303
3349
|
});
|
|
2304
3350
|
}
|
|
2305
3351
|
|
|
2306
3352
|
{
|
|
2307
|
-
// GENERATED
|
|
3353
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/radio-group/radio-group.yaml's a2ui.allowedParents/allowedChildren.
|
|
2308
3354
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2309
3355
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2310
3356
|
|
|
2311
3357
|
|
|
2312
|
-
const TAG = "
|
|
2313
|
-
const ALLOWED_PARENTS = [
|
|
2314
|
-
const ALLOWED_CHILDREN = [];
|
|
3358
|
+
const TAG = "radio-group-ui";
|
|
3359
|
+
const ALLOWED_PARENTS = [];
|
|
3360
|
+
const ALLOWED_CHILDREN = ["radio-ui"];
|
|
3361
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2315
3362
|
|
|
2316
3363
|
|
|
2317
3364
|
RULES.push({
|
|
2318
|
-
id: "COMPOSITION-
|
|
2319
|
-
severity: '
|
|
3365
|
+
id: "COMPOSITION-RADIO-GROUP-UI",
|
|
3366
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2320
3367
|
scope: 'shared',
|
|
2321
3368
|
fileTypes: MARKUP_EXT,
|
|
2322
3369
|
match(text) {
|
|
2323
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
3370
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2324
3371
|
},
|
|
2325
3372
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2326
3373
|
fixtures: {
|
|
2327
3374
|
"smelly": [
|
|
2328
|
-
"<
|
|
3375
|
+
"<radio-group-ui><not-an-allowed-child-ui></not-an-allowed-child-ui></radio-group-ui>"
|
|
2329
3376
|
],
|
|
2330
3377
|
"clean": [
|
|
2331
|
-
"<
|
|
3378
|
+
"<radio-group-ui><radio-ui></radio-ui></radio-group-ui>",
|
|
3379
|
+
"<radio-group-ui><not-an-allowed-child-ui slot=\"arbitrary-slot\"></not-an-allowed-child-ui></radio-group-ui>"
|
|
2332
3380
|
]
|
|
2333
3381
|
},
|
|
2334
3382
|
});
|
|
2335
3383
|
}
|
|
2336
3384
|
|
|
2337
3385
|
{
|
|
2338
|
-
// GENERATED
|
|
3386
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/search/search.yaml's a2ui.allowedParents/allowedChildren.
|
|
2339
3387
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2340
3388
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2341
3389
|
|
|
2342
3390
|
|
|
2343
|
-
const TAG = "
|
|
2344
|
-
const ALLOWED_PARENTS = [
|
|
2345
|
-
const ALLOWED_CHILDREN = [];
|
|
3391
|
+
const TAG = "search-ui";
|
|
3392
|
+
const ALLOWED_PARENTS = [];
|
|
3393
|
+
const ALLOWED_CHILDREN = ["input-ui"];
|
|
3394
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2346
3395
|
|
|
2347
3396
|
|
|
2348
3397
|
RULES.push({
|
|
2349
|
-
id: "COMPOSITION-
|
|
2350
|
-
severity: '
|
|
3398
|
+
id: "COMPOSITION-SEARCH-UI",
|
|
3399
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2351
3400
|
scope: 'shared',
|
|
2352
3401
|
fileTypes: MARKUP_EXT,
|
|
2353
3402
|
match(text) {
|
|
2354
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
3403
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2355
3404
|
},
|
|
2356
3405
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2357
3406
|
fixtures: {
|
|
2358
3407
|
"smelly": [
|
|
2359
|
-
"<
|
|
3408
|
+
"<search-ui><not-an-allowed-child-ui></not-an-allowed-child-ui></search-ui>"
|
|
2360
3409
|
],
|
|
2361
3410
|
"clean": [
|
|
2362
|
-
"<
|
|
3411
|
+
"<search-ui><input-ui></input-ui></search-ui>",
|
|
3412
|
+
"<search-ui><not-an-allowed-child-ui slot=\"arbitrary-slot\"></not-an-allowed-child-ui></search-ui>"
|
|
2363
3413
|
]
|
|
2364
3414
|
},
|
|
2365
3415
|
});
|
|
2366
3416
|
}
|
|
2367
3417
|
|
|
2368
3418
|
{
|
|
2369
|
-
// GENERATED
|
|
3419
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/section/section.yaml's a2ui.allowedParents/allowedChildren.
|
|
2370
3420
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2371
3421
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2372
3422
|
|
|
2373
3423
|
|
|
2374
|
-
const TAG = "
|
|
2375
|
-
const ALLOWED_PARENTS = ["admin-
|
|
3424
|
+
const TAG = "section-ui";
|
|
3425
|
+
const ALLOWED_PARENTS = ["page-ui","admin-sidebar"];
|
|
2376
3426
|
const ALLOWED_CHILDREN = [];
|
|
3427
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2377
3428
|
|
|
2378
3429
|
|
|
2379
3430
|
RULES.push({
|
|
2380
|
-
id: "COMPOSITION-
|
|
2381
|
-
severity: '
|
|
3431
|
+
id: "COMPOSITION-SECTION-UI",
|
|
3432
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2382
3433
|
scope: 'shared',
|
|
2383
3434
|
fileTypes: MARKUP_EXT,
|
|
2384
3435
|
match(text) {
|
|
2385
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
3436
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2386
3437
|
},
|
|
2387
3438
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2388
3439
|
fixtures: {
|
|
2389
3440
|
"smelly": [
|
|
2390
|
-
"<div><
|
|
3441
|
+
"<div><section-ui></section-ui></div>"
|
|
2391
3442
|
],
|
|
2392
3443
|
"clean": [
|
|
2393
|
-
"<
|
|
3444
|
+
"<page-ui><section-ui></section-ui></page-ui>"
|
|
2394
3445
|
]
|
|
2395
3446
|
},
|
|
2396
3447
|
});
|
|
2397
3448
|
}
|
|
2398
3449
|
|
|
2399
3450
|
{
|
|
2400
|
-
// GENERATED
|
|
3451
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/segment/segment.yaml's a2ui.allowedParents/allowedChildren.
|
|
2401
3452
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2402
3453
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2403
3454
|
|
|
@@ -2405,15 +3456,16 @@ RULES.push({
|
|
|
2405
3456
|
const TAG = "segment-ui";
|
|
2406
3457
|
const ALLOWED_PARENTS = ["segmented-ui"];
|
|
2407
3458
|
const ALLOWED_CHILDREN = [];
|
|
3459
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2408
3460
|
|
|
2409
3461
|
|
|
2410
3462
|
RULES.push({
|
|
2411
3463
|
id: "COMPOSITION-SEGMENT-UI",
|
|
2412
|
-
severity: '
|
|
3464
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2413
3465
|
scope: 'shared',
|
|
2414
3466
|
fileTypes: MARKUP_EXT,
|
|
2415
3467
|
match(text) {
|
|
2416
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
3468
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2417
3469
|
},
|
|
2418
3470
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2419
3471
|
fixtures: {
|
|
@@ -2428,7 +3480,7 @@ RULES.push({
|
|
|
2428
3480
|
}
|
|
2429
3481
|
|
|
2430
3482
|
{
|
|
2431
|
-
// GENERATED
|
|
3483
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/segmented/segmented.yaml's a2ui.allowedParents/allowedChildren.
|
|
2432
3484
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2433
3485
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2434
3486
|
|
|
@@ -2436,15 +3488,16 @@ RULES.push({
|
|
|
2436
3488
|
const TAG = "segmented-ui";
|
|
2437
3489
|
const ALLOWED_PARENTS = [];
|
|
2438
3490
|
const ALLOWED_CHILDREN = ["segment-ui"];
|
|
3491
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2439
3492
|
|
|
2440
3493
|
|
|
2441
3494
|
RULES.push({
|
|
2442
3495
|
id: "COMPOSITION-SEGMENTED-UI",
|
|
2443
|
-
severity: '
|
|
3496
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2444
3497
|
scope: 'shared',
|
|
2445
3498
|
fileTypes: MARKUP_EXT,
|
|
2446
3499
|
match(text) {
|
|
2447
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
3500
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2448
3501
|
},
|
|
2449
3502
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2450
3503
|
fixtures: {
|
|
@@ -2452,14 +3505,15 @@ RULES.push({
|
|
|
2452
3505
|
"<segmented-ui><not-an-allowed-child-ui></not-an-allowed-child-ui></segmented-ui>"
|
|
2453
3506
|
],
|
|
2454
3507
|
"clean": [
|
|
2455
|
-
"<segmented-ui><segment-ui></segment-ui></segmented-ui>"
|
|
3508
|
+
"<segmented-ui><segment-ui></segment-ui></segmented-ui>",
|
|
3509
|
+
"<segmented-ui><not-an-allowed-child-ui slot=\"arbitrary-slot\"></not-an-allowed-child-ui></segmented-ui>"
|
|
2456
3510
|
]
|
|
2457
3511
|
},
|
|
2458
3512
|
});
|
|
2459
3513
|
}
|
|
2460
3514
|
|
|
2461
3515
|
{
|
|
2462
|
-
// GENERATED
|
|
3516
|
+
// GENERATED: do not hand-edit. Source: packages/web-modules/simple/simple-content/simple-content.yaml's a2ui.allowedParents/allowedChildren.
|
|
2463
3517
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2464
3518
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2465
3519
|
|
|
@@ -2467,15 +3521,16 @@ RULES.push({
|
|
|
2467
3521
|
const TAG = "simple-content";
|
|
2468
3522
|
const ALLOWED_PARENTS = ["simple-shell"];
|
|
2469
3523
|
const ALLOWED_CHILDREN = [];
|
|
3524
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2470
3525
|
|
|
2471
3526
|
|
|
2472
3527
|
RULES.push({
|
|
2473
3528
|
id: "COMPOSITION-SIMPLE-CONTENT",
|
|
2474
|
-
severity: '
|
|
3529
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2475
3530
|
scope: 'shared',
|
|
2476
3531
|
fileTypes: MARKUP_EXT,
|
|
2477
3532
|
match(text) {
|
|
2478
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
3533
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2479
3534
|
},
|
|
2480
3535
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2481
3536
|
fixtures: {
|
|
@@ -2490,7 +3545,7 @@ RULES.push({
|
|
|
2490
3545
|
}
|
|
2491
3546
|
|
|
2492
3547
|
{
|
|
2493
|
-
// GENERATED
|
|
3548
|
+
// GENERATED: do not hand-edit. Source: packages/web-modules/simple/simple-hero/simple-hero.yaml's a2ui.allowedParents/allowedChildren.
|
|
2494
3549
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2495
3550
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2496
3551
|
|
|
@@ -2498,15 +3553,16 @@ RULES.push({
|
|
|
2498
3553
|
const TAG = "simple-hero";
|
|
2499
3554
|
const ALLOWED_PARENTS = ["simple-shell"];
|
|
2500
3555
|
const ALLOWED_CHILDREN = [];
|
|
3556
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2501
3557
|
|
|
2502
3558
|
|
|
2503
3559
|
RULES.push({
|
|
2504
3560
|
id: "COMPOSITION-SIMPLE-HERO",
|
|
2505
|
-
severity: '
|
|
3561
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2506
3562
|
scope: 'shared',
|
|
2507
3563
|
fileTypes: MARKUP_EXT,
|
|
2508
3564
|
match(text) {
|
|
2509
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
3565
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2510
3566
|
},
|
|
2511
3567
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2512
3568
|
fixtures: {
|
|
@@ -2521,7 +3577,7 @@ RULES.push({
|
|
|
2521
3577
|
}
|
|
2522
3578
|
|
|
2523
3579
|
{
|
|
2524
|
-
// GENERATED
|
|
3580
|
+
// GENERATED: do not hand-edit. Source: packages/web-modules/simple/simple-shell/simple-shell.yaml's a2ui.allowedParents/allowedChildren.
|
|
2525
3581
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2526
3582
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2527
3583
|
|
|
@@ -2529,15 +3585,16 @@ RULES.push({
|
|
|
2529
3585
|
const TAG = "simple-shell";
|
|
2530
3586
|
const ALLOWED_PARENTS = ["Surface"];
|
|
2531
3587
|
const ALLOWED_CHILDREN = [];
|
|
3588
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2532
3589
|
|
|
2533
3590
|
|
|
2534
3591
|
RULES.push({
|
|
2535
3592
|
id: "COMPOSITION-SIMPLE-SHELL",
|
|
2536
|
-
severity: '
|
|
3593
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2537
3594
|
scope: 'shared',
|
|
2538
3595
|
fileTypes: MARKUP_EXT,
|
|
2539
3596
|
match(text) {
|
|
2540
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
3597
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2541
3598
|
},
|
|
2542
3599
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2543
3600
|
fixtures: {
|
|
@@ -2552,7 +3609,39 @@ RULES.push({
|
|
|
2552
3609
|
}
|
|
2553
3610
|
|
|
2554
3611
|
{
|
|
2555
|
-
// GENERATED
|
|
3612
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/skip-nav/skip-nav.yaml's a2ui.allowedParents/allowedChildren.
|
|
3613
|
+
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
3614
|
+
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
3615
|
+
|
|
3616
|
+
|
|
3617
|
+
const TAG = "skip-nav-ui";
|
|
3618
|
+
const ALLOWED_PARENTS = ["Surface"];
|
|
3619
|
+
const ALLOWED_CHILDREN = [];
|
|
3620
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
3621
|
+
|
|
3622
|
+
|
|
3623
|
+
RULES.push({
|
|
3624
|
+
id: "COMPOSITION-SKIP-NAV-UI",
|
|
3625
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
3626
|
+
scope: 'shared',
|
|
3627
|
+
fileTypes: MARKUP_EXT,
|
|
3628
|
+
match(text) {
|
|
3629
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
3630
|
+
},
|
|
3631
|
+
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
3632
|
+
fixtures: {
|
|
3633
|
+
"smelly": [
|
|
3634
|
+
"<col-ui><skip-nav-ui></skip-nav-ui></col-ui>"
|
|
3635
|
+
],
|
|
3636
|
+
"clean": [
|
|
3637
|
+
"<skip-nav-ui></skip-nav-ui>"
|
|
3638
|
+
]
|
|
3639
|
+
},
|
|
3640
|
+
});
|
|
3641
|
+
}
|
|
3642
|
+
|
|
3643
|
+
{
|
|
3644
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/stepper/stepper-item.yaml's a2ui.allowedParents/allowedChildren.
|
|
2556
3645
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2557
3646
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2558
3647
|
|
|
@@ -2560,15 +3649,16 @@ RULES.push({
|
|
|
2560
3649
|
const TAG = "stepper-item-ui";
|
|
2561
3650
|
const ALLOWED_PARENTS = ["stepper-ui"];
|
|
2562
3651
|
const ALLOWED_CHILDREN = [];
|
|
3652
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2563
3653
|
|
|
2564
3654
|
|
|
2565
3655
|
RULES.push({
|
|
2566
3656
|
id: "COMPOSITION-STEPPER-ITEM-UI",
|
|
2567
|
-
severity: '
|
|
3657
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2568
3658
|
scope: 'shared',
|
|
2569
3659
|
fileTypes: MARKUP_EXT,
|
|
2570
3660
|
match(text) {
|
|
2571
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
3661
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2572
3662
|
},
|
|
2573
3663
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2574
3664
|
fixtures: {
|
|
@@ -2583,7 +3673,7 @@ RULES.push({
|
|
|
2583
3673
|
}
|
|
2584
3674
|
|
|
2585
3675
|
{
|
|
2586
|
-
// GENERATED
|
|
3676
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/stepper/stepper.yaml's a2ui.allowedParents/allowedChildren.
|
|
2587
3677
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2588
3678
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2589
3679
|
|
|
@@ -2591,15 +3681,16 @@ RULES.push({
|
|
|
2591
3681
|
const TAG = "stepper-ui";
|
|
2592
3682
|
const ALLOWED_PARENTS = [];
|
|
2593
3683
|
const ALLOWED_CHILDREN = ["stepper-item-ui"];
|
|
3684
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2594
3685
|
|
|
2595
3686
|
|
|
2596
3687
|
RULES.push({
|
|
2597
3688
|
id: "COMPOSITION-STEPPER-UI",
|
|
2598
|
-
severity: '
|
|
3689
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2599
3690
|
scope: 'shared',
|
|
2600
3691
|
fileTypes: MARKUP_EXT,
|
|
2601
3692
|
match(text) {
|
|
2602
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
3693
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2603
3694
|
},
|
|
2604
3695
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2605
3696
|
fixtures: {
|
|
@@ -2607,14 +3698,15 @@ RULES.push({
|
|
|
2607
3698
|
"<stepper-ui><not-an-allowed-child-ui></not-an-allowed-child-ui></stepper-ui>"
|
|
2608
3699
|
],
|
|
2609
3700
|
"clean": [
|
|
2610
|
-
"<stepper-ui><stepper-item-ui></stepper-item-ui></stepper-ui>"
|
|
3701
|
+
"<stepper-ui><stepper-item-ui></stepper-item-ui></stepper-ui>",
|
|
3702
|
+
"<stepper-ui><not-an-allowed-child-ui slot=\"arbitrary-slot\"></not-an-allowed-child-ui></stepper-ui>"
|
|
2611
3703
|
]
|
|
2612
3704
|
},
|
|
2613
3705
|
});
|
|
2614
3706
|
}
|
|
2615
3707
|
|
|
2616
3708
|
{
|
|
2617
|
-
// GENERATED
|
|
3709
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/tabs/tab.yaml's a2ui.allowedParents/allowedChildren.
|
|
2618
3710
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2619
3711
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2620
3712
|
|
|
@@ -2622,15 +3714,16 @@ RULES.push({
|
|
|
2622
3714
|
const TAG = "tab-ui";
|
|
2623
3715
|
const ALLOWED_PARENTS = ["tabs-ui"];
|
|
2624
3716
|
const ALLOWED_CHILDREN = [];
|
|
3717
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2625
3718
|
|
|
2626
3719
|
|
|
2627
3720
|
RULES.push({
|
|
2628
3721
|
id: "COMPOSITION-TAB-UI",
|
|
2629
|
-
severity: '
|
|
3722
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2630
3723
|
scope: 'shared',
|
|
2631
3724
|
fileTypes: MARKUP_EXT,
|
|
2632
3725
|
match(text) {
|
|
2633
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
3726
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2634
3727
|
},
|
|
2635
3728
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2636
3729
|
fixtures: {
|
|
@@ -2645,7 +3738,7 @@ RULES.push({
|
|
|
2645
3738
|
}
|
|
2646
3739
|
|
|
2647
3740
|
{
|
|
2648
|
-
// GENERATED
|
|
3741
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/tabs/tabs.yaml's a2ui.allowedParents/allowedChildren.
|
|
2649
3742
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2650
3743
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2651
3744
|
|
|
@@ -2653,15 +3746,16 @@ RULES.push({
|
|
|
2653
3746
|
const TAG = "tabs-ui";
|
|
2654
3747
|
const ALLOWED_PARENTS = [];
|
|
2655
3748
|
const ALLOWED_CHILDREN = ["tab-ui"];
|
|
3749
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2656
3750
|
|
|
2657
3751
|
|
|
2658
3752
|
RULES.push({
|
|
2659
3753
|
id: "COMPOSITION-TABS-UI",
|
|
2660
|
-
severity: '
|
|
3754
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2661
3755
|
scope: 'shared',
|
|
2662
3756
|
fileTypes: MARKUP_EXT,
|
|
2663
3757
|
match(text) {
|
|
2664
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
3758
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2665
3759
|
},
|
|
2666
3760
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2667
3761
|
fixtures: {
|
|
@@ -2669,14 +3763,15 @@ RULES.push({
|
|
|
2669
3763
|
"<tabs-ui><not-an-allowed-child-ui></not-an-allowed-child-ui></tabs-ui>"
|
|
2670
3764
|
],
|
|
2671
3765
|
"clean": [
|
|
2672
|
-
"<tabs-ui><tab-ui></tab-ui></tabs-ui>"
|
|
3766
|
+
"<tabs-ui><tab-ui></tab-ui></tabs-ui>",
|
|
3767
|
+
"<tabs-ui><not-an-allowed-child-ui slot=\"arbitrary-slot\"></not-an-allowed-child-ui></tabs-ui>"
|
|
2673
3768
|
]
|
|
2674
3769
|
},
|
|
2675
3770
|
});
|
|
2676
3771
|
}
|
|
2677
3772
|
|
|
2678
3773
|
{
|
|
2679
|
-
// GENERATED
|
|
3774
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/timeline/timeline-item.yaml's a2ui.allowedParents/allowedChildren.
|
|
2680
3775
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2681
3776
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2682
3777
|
|
|
@@ -2684,15 +3779,16 @@ RULES.push({
|
|
|
2684
3779
|
const TAG = "timeline-item-ui";
|
|
2685
3780
|
const ALLOWED_PARENTS = ["timeline-ui"];
|
|
2686
3781
|
const ALLOWED_CHILDREN = [];
|
|
3782
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2687
3783
|
|
|
2688
3784
|
|
|
2689
3785
|
RULES.push({
|
|
2690
3786
|
id: "COMPOSITION-TIMELINE-ITEM-UI",
|
|
2691
|
-
severity: '
|
|
3787
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2692
3788
|
scope: 'shared',
|
|
2693
3789
|
fileTypes: MARKUP_EXT,
|
|
2694
3790
|
match(text) {
|
|
2695
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
3791
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2696
3792
|
},
|
|
2697
3793
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2698
3794
|
fixtures: {
|
|
@@ -2707,7 +3803,7 @@ RULES.push({
|
|
|
2707
3803
|
}
|
|
2708
3804
|
|
|
2709
3805
|
{
|
|
2710
|
-
// GENERATED
|
|
3806
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/timeline/timeline.yaml's a2ui.allowedParents/allowedChildren.
|
|
2711
3807
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2712
3808
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2713
3809
|
|
|
@@ -2715,15 +3811,16 @@ RULES.push({
|
|
|
2715
3811
|
const TAG = "timeline-ui";
|
|
2716
3812
|
const ALLOWED_PARENTS = [];
|
|
2717
3813
|
const ALLOWED_CHILDREN = ["timeline-item-ui"];
|
|
3814
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2718
3815
|
|
|
2719
3816
|
|
|
2720
3817
|
RULES.push({
|
|
2721
3818
|
id: "COMPOSITION-TIMELINE-UI",
|
|
2722
|
-
severity: '
|
|
3819
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2723
3820
|
scope: 'shared',
|
|
2724
3821
|
fileTypes: MARKUP_EXT,
|
|
2725
3822
|
match(text) {
|
|
2726
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
3823
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2727
3824
|
},
|
|
2728
3825
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2729
3826
|
fixtures: {
|
|
@@ -2731,14 +3828,15 @@ RULES.push({
|
|
|
2731
3828
|
"<timeline-ui><not-an-allowed-child-ui></not-an-allowed-child-ui></timeline-ui>"
|
|
2732
3829
|
],
|
|
2733
3830
|
"clean": [
|
|
2734
|
-
"<timeline-ui><timeline-item-ui></timeline-item-ui></timeline-ui>"
|
|
3831
|
+
"<timeline-ui><timeline-item-ui></timeline-item-ui></timeline-ui>",
|
|
3832
|
+
"<timeline-ui><not-an-allowed-child-ui slot=\"arbitrary-slot\"></not-an-allowed-child-ui></timeline-ui>"
|
|
2735
3833
|
]
|
|
2736
3834
|
},
|
|
2737
3835
|
});
|
|
2738
3836
|
}
|
|
2739
3837
|
|
|
2740
3838
|
{
|
|
2741
|
-
// GENERATED
|
|
3839
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/toolbar/toolbar-group.yaml's a2ui.allowedParents/allowedChildren.
|
|
2742
3840
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2743
3841
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2744
3842
|
|
|
@@ -2746,15 +3844,16 @@ RULES.push({
|
|
|
2746
3844
|
const TAG = "toolbar-group-ui";
|
|
2747
3845
|
const ALLOWED_PARENTS = ["toolbar-ui"];
|
|
2748
3846
|
const ALLOWED_CHILDREN = [];
|
|
3847
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2749
3848
|
|
|
2750
3849
|
|
|
2751
3850
|
RULES.push({
|
|
2752
3851
|
id: "COMPOSITION-TOOLBAR-GROUP-UI",
|
|
2753
|
-
severity: '
|
|
3852
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2754
3853
|
scope: 'shared',
|
|
2755
3854
|
fileTypes: MARKUP_EXT,
|
|
2756
3855
|
match(text) {
|
|
2757
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
3856
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2758
3857
|
},
|
|
2759
3858
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2760
3859
|
fixtures: {
|
|
@@ -2769,7 +3868,7 @@ RULES.push({
|
|
|
2769
3868
|
}
|
|
2770
3869
|
|
|
2771
3870
|
{
|
|
2772
|
-
// GENERATED
|
|
3871
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/tour/tour-step.yaml's a2ui.allowedParents/allowedChildren.
|
|
2773
3872
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2774
3873
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2775
3874
|
|
|
@@ -2777,15 +3876,16 @@ RULES.push({
|
|
|
2777
3876
|
const TAG = "tour-step-ui";
|
|
2778
3877
|
const ALLOWED_PARENTS = ["tour-ui"];
|
|
2779
3878
|
const ALLOWED_CHILDREN = [];
|
|
3879
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2780
3880
|
|
|
2781
3881
|
|
|
2782
3882
|
RULES.push({
|
|
2783
3883
|
id: "COMPOSITION-TOUR-STEP-UI",
|
|
2784
|
-
severity: '
|
|
3884
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2785
3885
|
scope: 'shared',
|
|
2786
3886
|
fileTypes: MARKUP_EXT,
|
|
2787
3887
|
match(text) {
|
|
2788
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
3888
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2789
3889
|
},
|
|
2790
3890
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2791
3891
|
fixtures: {
|
|
@@ -2800,7 +3900,7 @@ RULES.push({
|
|
|
2800
3900
|
}
|
|
2801
3901
|
|
|
2802
3902
|
{
|
|
2803
|
-
// GENERATED
|
|
3903
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/tour/tour.yaml's a2ui.allowedParents/allowedChildren.
|
|
2804
3904
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2805
3905
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2806
3906
|
|
|
@@ -2808,15 +3908,16 @@ RULES.push({
|
|
|
2808
3908
|
const TAG = "tour-ui";
|
|
2809
3909
|
const ALLOWED_PARENTS = [];
|
|
2810
3910
|
const ALLOWED_CHILDREN = ["tour-step-ui"];
|
|
3911
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2811
3912
|
|
|
2812
3913
|
|
|
2813
3914
|
RULES.push({
|
|
2814
3915
|
id: "COMPOSITION-TOUR-UI",
|
|
2815
|
-
severity: '
|
|
3916
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2816
3917
|
scope: 'shared',
|
|
2817
3918
|
fileTypes: MARKUP_EXT,
|
|
2818
3919
|
match(text) {
|
|
2819
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
3920
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2820
3921
|
},
|
|
2821
3922
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2822
3923
|
fixtures: {
|
|
@@ -2824,14 +3925,15 @@ RULES.push({
|
|
|
2824
3925
|
"<tour-ui><not-an-allowed-child-ui></not-an-allowed-child-ui></tour-ui>"
|
|
2825
3926
|
],
|
|
2826
3927
|
"clean": [
|
|
2827
|
-
"<tour-ui><tour-step-ui></tour-step-ui></tour-ui>"
|
|
3928
|
+
"<tour-ui><tour-step-ui></tour-step-ui></tour-ui>",
|
|
3929
|
+
"<tour-ui><not-an-allowed-child-ui slot=\"arbitrary-slot\"></not-an-allowed-child-ui></tour-ui>"
|
|
2828
3930
|
]
|
|
2829
3931
|
},
|
|
2830
3932
|
});
|
|
2831
3933
|
}
|
|
2832
3934
|
|
|
2833
3935
|
{
|
|
2834
|
-
// GENERATED
|
|
3936
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/tree/tree-item.yaml's a2ui.allowedParents/allowedChildren.
|
|
2835
3937
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2836
3938
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2837
3939
|
|
|
@@ -2839,15 +3941,16 @@ RULES.push({
|
|
|
2839
3941
|
const TAG = "tree-item-ui";
|
|
2840
3942
|
const ALLOWED_PARENTS = ["tree-ui","tree-item-ui"];
|
|
2841
3943
|
const ALLOWED_CHILDREN = [];
|
|
3944
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2842
3945
|
|
|
2843
3946
|
|
|
2844
3947
|
RULES.push({
|
|
2845
3948
|
id: "COMPOSITION-TREE-ITEM-UI",
|
|
2846
|
-
severity: '
|
|
3949
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2847
3950
|
scope: 'shared',
|
|
2848
3951
|
fileTypes: MARKUP_EXT,
|
|
2849
3952
|
match(text) {
|
|
2850
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
3953
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2851
3954
|
},
|
|
2852
3955
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2853
3956
|
fixtures: {
|
|
@@ -2862,7 +3965,7 @@ RULES.push({
|
|
|
2862
3965
|
}
|
|
2863
3966
|
|
|
2864
3967
|
{
|
|
2865
|
-
// GENERATED
|
|
3968
|
+
// GENERATED: do not hand-edit. Source: packages/web-components/components/tree/tree.yaml's a2ui.allowedParents/allowedChildren.
|
|
2866
3969
|
// Rebuild: node scripts/build/gen-composition-rules.mjs
|
|
2867
3970
|
// Freshness gate: node scripts/verify/check-composition-rules-fresh.mjs --verify
|
|
2868
3971
|
|
|
@@ -2870,15 +3973,16 @@ RULES.push({
|
|
|
2870
3973
|
const TAG = "tree-ui";
|
|
2871
3974
|
const ALLOWED_PARENTS = [];
|
|
2872
3975
|
const ALLOWED_CHILDREN = ["tree-item-ui"];
|
|
3976
|
+
const ALLOWED_CHILDREN_BY_SLOT = null;
|
|
2873
3977
|
|
|
2874
3978
|
|
|
2875
3979
|
RULES.push({
|
|
2876
3980
|
id: "COMPOSITION-TREE-UI",
|
|
2877
|
-
severity: '
|
|
3981
|
+
severity: 'error', // gh#3719: promoted from warn once the corpus-wide rollout (LLD-0016 §C4) cleared clean, every COMPOSITION-* rule's real corpus hits fixed, so this stays advisory no longer.
|
|
2878
3982
|
scope: 'shared',
|
|
2879
3983
|
fileTypes: MARKUP_EXT,
|
|
2880
3984
|
match(text) {
|
|
2881
|
-
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN });
|
|
3985
|
+
return compositionFindings(text, { tag: TAG, allowedParents: ALLOWED_PARENTS, allowedChildren: ALLOWED_CHILDREN, allowedChildrenBySlot: ALLOWED_CHILDREN_BY_SLOT });
|
|
2882
3986
|
},
|
|
2883
3987
|
fix: null, // moving markup to satisfy a composition constraint is a judgment call, not a mechanical rename (LLD-0016 §Risks R4/R5)
|
|
2884
3988
|
fixtures: {
|
|
@@ -2886,35 +3990,27 @@ RULES.push({
|
|
|
2886
3990
|
"<tree-ui><not-an-allowed-child-ui></not-an-allowed-child-ui></tree-ui>"
|
|
2887
3991
|
],
|
|
2888
3992
|
"clean": [
|
|
2889
|
-
"<tree-ui><tree-item-ui></tree-item-ui></tree-ui>"
|
|
3993
|
+
"<tree-ui><tree-item-ui></tree-item-ui></tree-ui>",
|
|
3994
|
+
"<tree-ui><not-an-allowed-child-ui slot=\"arbitrary-slot\"></not-an-allowed-child-ui></tree-ui>"
|
|
2890
3995
|
]
|
|
2891
3996
|
},
|
|
2892
3997
|
});
|
|
2893
3998
|
}
|
|
2894
3999
|
|
|
2895
4000
|
{
|
|
2896
|
-
// GENERATED
|
|
4001
|
+
// GENERATED, do not hand-edit. Source: packages/web-components/**/*.a2ui.json + yaml,
|
|
2897
4002
|
// packages/web-modules/**/*.a2ui.json + yaml (ADR-0108 D5 / LLD-0019 C5).
|
|
2898
4003
|
// Rebuild: node scripts/build/gen-lab-posture-rules.mjs
|
|
2899
4004
|
// Freshness gate: node scripts/verify/check-lab-posture-rules-fresh.mjs --verify
|
|
2900
4005
|
//
|
|
2901
4006
|
// ENUM-VALUE (ADR-0108 D5): a declared enum attribute set to a value outside its manifest-declared enum (default + opt-in + internal).
|
|
2902
4007
|
//
|
|
2903
|
-
// severity: '
|
|
4008
|
+
// severity: 'error' here governs ONLY `npm run lint`'s bare-repo-shaped
|
|
2904
4009
|
// advisory bank (ADR-0040 unchanged). The lab-posture write-time hook
|
|
2905
4010
|
// (packages/plugins/adia-ui-factory/scripts/lab-posture-guard.mjs,
|
|
2906
4011
|
// LLD-0019 C4) does not read this field — a lab-posture write denies on
|
|
2907
4012
|
// ANY finding from these same matcher functions regardless of severity
|
|
2908
4013
|
// (ADR-0108 D5: "PreToolUse deny... error under the lab hook").
|
|
2909
|
-
//
|
|
2910
|
-
// Demoted warn -> info (gh#2939, Kim-ruled 2026-09-03): gh#2911's G2
|
|
2911
|
-
// warn-triage sample found this rule's class overwhelmingly manifest
|
|
2912
|
-
// drift, not real authoring bugs (INTERNAL-TIER 594/1413 findings, 42%
|
|
2913
|
-
// of the corpus total — almost entirely shipped-and-sanctioned values
|
|
2914
|
-
// like button-ui[variant="primary"] the tier manifest hasn't promoted
|
|
2915
|
-
// to match reality). The matcher/detection logic is UNCHANGED — this is
|
|
2916
|
-
// a severity relabel only. Fixing the underlying manifest drift itself
|
|
2917
|
-
// is split out as gh#3044, not this ticket.
|
|
2918
4014
|
|
|
2919
4015
|
|
|
2920
4016
|
const MANIFEST_SNAPSHOT = {
|
|
@@ -3133,10 +4229,6 @@ const MANIFEST_SNAPSHOT = {
|
|
|
3133
4229
|
}
|
|
3134
4230
|
]
|
|
3135
4231
|
},
|
|
3136
|
-
{
|
|
3137
|
-
"tag": "admin-scroll",
|
|
3138
|
-
"attrs": []
|
|
3139
|
-
},
|
|
3140
4232
|
{
|
|
3141
4233
|
"tag": "admin-settings-ui",
|
|
3142
4234
|
"attrs": [
|
|
@@ -3252,6 +4344,9 @@ const MANIFEST_SNAPSHOT = {
|
|
|
3252
4344
|
{
|
|
3253
4345
|
"name": "multi"
|
|
3254
4346
|
},
|
|
4347
|
+
{
|
|
4348
|
+
"name": "options"
|
|
4349
|
+
},
|
|
3255
4350
|
{
|
|
3256
4351
|
"name": "question"
|
|
3257
4352
|
},
|
|
@@ -3315,6 +4410,9 @@ const MANIFEST_SNAPSHOT = {
|
|
|
3315
4410
|
}
|
|
3316
4411
|
]
|
|
3317
4412
|
},
|
|
4413
|
+
{
|
|
4414
|
+
"name": "suggestions"
|
|
4415
|
+
},
|
|
3318
4416
|
{
|
|
3319
4417
|
"name": "variant",
|
|
3320
4418
|
"values": [
|
|
@@ -4048,13 +5146,16 @@ const MANIFEST_SNAPSHOT = {
|
|
|
4048
5146
|
"name": "precision",
|
|
4049
5147
|
"values": [
|
|
4050
5148
|
{
|
|
4051
|
-
"value": "date"
|
|
5149
|
+
"value": "date",
|
|
5150
|
+
"tier": "default"
|
|
4052
5151
|
},
|
|
4053
5152
|
{
|
|
4054
|
-
"value": "minute"
|
|
5153
|
+
"value": "minute",
|
|
5154
|
+
"tier": "opt-in"
|
|
4055
5155
|
},
|
|
4056
5156
|
{
|
|
4057
|
-
"value": "second"
|
|
5157
|
+
"value": "second",
|
|
5158
|
+
"tier": "opt-in"
|
|
4058
5159
|
}
|
|
4059
5160
|
]
|
|
4060
5161
|
},
|
|
@@ -4578,6 +5679,10 @@ const MANIFEST_SNAPSHOT = {
|
|
|
4578
5679
|
},
|
|
4579
5680
|
{
|
|
4580
5681
|
"name": "thinking"
|
|
5682
|
+
},
|
|
5683
|
+
{
|
|
5684
|
+
"name": "thinkingBudget",
|
|
5685
|
+
"attribute": "thinking-budget"
|
|
4581
5686
|
}
|
|
4582
5687
|
]
|
|
4583
5688
|
},
|
|
@@ -5270,7 +6375,30 @@ const MANIFEST_SNAPSHOT = {
|
|
|
5270
6375
|
"name": "to"
|
|
5271
6376
|
},
|
|
5272
6377
|
{
|
|
5273
|
-
"name": "value"
|
|
6378
|
+
"name": "value",
|
|
6379
|
+
"values": [
|
|
6380
|
+
{
|
|
6381
|
+
"value": "today"
|
|
6382
|
+
},
|
|
6383
|
+
{
|
|
6384
|
+
"value": "7d"
|
|
6385
|
+
},
|
|
6386
|
+
{
|
|
6387
|
+
"value": "30d"
|
|
6388
|
+
},
|
|
6389
|
+
{
|
|
6390
|
+
"value": "90d"
|
|
6391
|
+
},
|
|
6392
|
+
{
|
|
6393
|
+
"value": "qtd"
|
|
6394
|
+
},
|
|
6395
|
+
{
|
|
6396
|
+
"value": "ytd"
|
|
6397
|
+
},
|
|
6398
|
+
{
|
|
6399
|
+
"value": "custom"
|
|
6400
|
+
}
|
|
6401
|
+
]
|
|
5274
6402
|
}
|
|
5275
6403
|
]
|
|
5276
6404
|
},
|
|
@@ -5403,16 +6531,19 @@ const MANIFEST_SNAPSHOT = {
|
|
|
5403
6531
|
"name": "side",
|
|
5404
6532
|
"values": [
|
|
5405
6533
|
{
|
|
5406
|
-
"value": "left"
|
|
6534
|
+
"value": "left",
|
|
6535
|
+
"tier": "opt-in"
|
|
5407
6536
|
},
|
|
5408
6537
|
{
|
|
5409
|
-
"value": "right"
|
|
6538
|
+
"value": "right",
|
|
6539
|
+
"tier": "default"
|
|
5410
6540
|
},
|
|
5411
6541
|
{
|
|
5412
6542
|
"value": "top"
|
|
5413
6543
|
},
|
|
5414
6544
|
{
|
|
5415
|
-
"value": "bottom"
|
|
6545
|
+
"value": "bottom",
|
|
6546
|
+
"tier": "opt-in"
|
|
5416
6547
|
}
|
|
5417
6548
|
]
|
|
5418
6549
|
},
|
|
@@ -5907,13 +7038,16 @@ const MANIFEST_SNAPSHOT = {
|
|
|
5907
7038
|
"name": "scale",
|
|
5908
7039
|
"values": [
|
|
5909
7040
|
{
|
|
5910
|
-
"value": "linear"
|
|
7041
|
+
"value": "linear",
|
|
7042
|
+
"tier": "default"
|
|
5911
7043
|
},
|
|
5912
7044
|
{
|
|
5913
|
-
"value": "log"
|
|
7045
|
+
"value": "log",
|
|
7046
|
+
"tier": "opt-in"
|
|
5914
7047
|
},
|
|
5915
7048
|
{
|
|
5916
|
-
"value": "quantile"
|
|
7049
|
+
"value": "quantile",
|
|
7050
|
+
"tier": "opt-in"
|
|
5917
7051
|
}
|
|
5918
7052
|
]
|
|
5919
7053
|
},
|
|
@@ -6134,7 +7268,29 @@ const MANIFEST_SNAPSHOT = {
|
|
|
6134
7268
|
"name": "text"
|
|
6135
7269
|
},
|
|
6136
7270
|
{
|
|
6137
|
-
"name": "variant"
|
|
7271
|
+
"name": "variant",
|
|
7272
|
+
"values": [
|
|
7273
|
+
{
|
|
7274
|
+
"value": "default",
|
|
7275
|
+
"tier": "default"
|
|
7276
|
+
},
|
|
7277
|
+
{
|
|
7278
|
+
"value": "info",
|
|
7279
|
+
"tier": "opt-in"
|
|
7280
|
+
},
|
|
7281
|
+
{
|
|
7282
|
+
"value": "success",
|
|
7283
|
+
"tier": "opt-in"
|
|
7284
|
+
},
|
|
7285
|
+
{
|
|
7286
|
+
"value": "warning",
|
|
7287
|
+
"tier": "opt-in"
|
|
7288
|
+
},
|
|
7289
|
+
{
|
|
7290
|
+
"value": "danger",
|
|
7291
|
+
"tier": "opt-in"
|
|
7292
|
+
}
|
|
7293
|
+
]
|
|
6138
7294
|
}
|
|
6139
7295
|
]
|
|
6140
7296
|
},
|
|
@@ -6180,7 +7336,33 @@ const MANIFEST_SNAPSHOT = {
|
|
|
6180
7336
|
"name": "error"
|
|
6181
7337
|
},
|
|
6182
7338
|
{
|
|
6183
|
-
"name": "inputmode"
|
|
7339
|
+
"name": "inputmode",
|
|
7340
|
+
"values": [
|
|
7341
|
+
{
|
|
7342
|
+
"value": "text"
|
|
7343
|
+
},
|
|
7344
|
+
{
|
|
7345
|
+
"value": "decimal"
|
|
7346
|
+
},
|
|
7347
|
+
{
|
|
7348
|
+
"value": "numeric"
|
|
7349
|
+
},
|
|
7350
|
+
{
|
|
7351
|
+
"value": "tel"
|
|
7352
|
+
},
|
|
7353
|
+
{
|
|
7354
|
+
"value": "search"
|
|
7355
|
+
},
|
|
7356
|
+
{
|
|
7357
|
+
"value": "email"
|
|
7358
|
+
},
|
|
7359
|
+
{
|
|
7360
|
+
"value": "url"
|
|
7361
|
+
},
|
|
7362
|
+
{
|
|
7363
|
+
"value": "none"
|
|
7364
|
+
}
|
|
7365
|
+
]
|
|
6184
7366
|
},
|
|
6185
7367
|
{
|
|
6186
7368
|
"name": "label"
|
|
@@ -6281,7 +7463,24 @@ const MANIFEST_SNAPSHOT = {
|
|
|
6281
7463
|
"required": true
|
|
6282
7464
|
},
|
|
6283
7465
|
{
|
|
6284
|
-
"name": "status"
|
|
7466
|
+
"name": "status",
|
|
7467
|
+
"values": [
|
|
7468
|
+
{
|
|
7469
|
+
"value": "available"
|
|
7470
|
+
},
|
|
7471
|
+
{
|
|
7472
|
+
"value": "connected"
|
|
7473
|
+
},
|
|
7474
|
+
{
|
|
7475
|
+
"value": "error"
|
|
7476
|
+
},
|
|
7477
|
+
{
|
|
7478
|
+
"value": "pending"
|
|
7479
|
+
},
|
|
7480
|
+
{
|
|
7481
|
+
"value": "coming-soon"
|
|
7482
|
+
}
|
|
7483
|
+
]
|
|
6285
7484
|
}
|
|
6286
7485
|
]
|
|
6287
7486
|
},
|
|
@@ -6313,7 +7512,24 @@ const MANIFEST_SNAPSHOT = {
|
|
|
6313
7512
|
"name": "searchPlaceholder"
|
|
6314
7513
|
},
|
|
6315
7514
|
{
|
|
6316
|
-
"name": "statusFilter"
|
|
7515
|
+
"name": "statusFilter",
|
|
7516
|
+
"values": [
|
|
7517
|
+
{
|
|
7518
|
+
"value": "all"
|
|
7519
|
+
},
|
|
7520
|
+
{
|
|
7521
|
+
"value": "available"
|
|
7522
|
+
},
|
|
7523
|
+
{
|
|
7524
|
+
"value": "connected"
|
|
7525
|
+
},
|
|
7526
|
+
{
|
|
7527
|
+
"value": "error"
|
|
7528
|
+
},
|
|
7529
|
+
{
|
|
7530
|
+
"value": "coming-soon"
|
|
7531
|
+
}
|
|
7532
|
+
]
|
|
6317
7533
|
}
|
|
6318
7534
|
]
|
|
6319
7535
|
},
|
|
@@ -6355,7 +7571,24 @@ const MANIFEST_SNAPSHOT = {
|
|
|
6355
7571
|
"name": "printable"
|
|
6356
7572
|
},
|
|
6357
7573
|
{
|
|
6358
|
-
"name": "status"
|
|
7574
|
+
"name": "status",
|
|
7575
|
+
"values": [
|
|
7576
|
+
{
|
|
7577
|
+
"value": "draft"
|
|
7578
|
+
},
|
|
7579
|
+
{
|
|
7580
|
+
"value": "open"
|
|
7581
|
+
},
|
|
7582
|
+
{
|
|
7583
|
+
"value": "paid"
|
|
7584
|
+
},
|
|
7585
|
+
{
|
|
7586
|
+
"value": "past-due"
|
|
7587
|
+
},
|
|
7588
|
+
{
|
|
7589
|
+
"value": "void"
|
|
7590
|
+
}
|
|
7591
|
+
]
|
|
6359
7592
|
}
|
|
6360
7593
|
]
|
|
6361
7594
|
},
|
|
@@ -6387,7 +7620,27 @@ const MANIFEST_SNAPSHOT = {
|
|
|
6387
7620
|
"name": "exportable"
|
|
6388
7621
|
},
|
|
6389
7622
|
{
|
|
6390
|
-
"name": "filter"
|
|
7623
|
+
"name": "filter",
|
|
7624
|
+
"values": [
|
|
7625
|
+
{
|
|
7626
|
+
"value": ""
|
|
7627
|
+
},
|
|
7628
|
+
{
|
|
7629
|
+
"value": "draft"
|
|
7630
|
+
},
|
|
7631
|
+
{
|
|
7632
|
+
"value": "open"
|
|
7633
|
+
},
|
|
7634
|
+
{
|
|
7635
|
+
"value": "paid"
|
|
7636
|
+
},
|
|
7637
|
+
{
|
|
7638
|
+
"value": "past-due"
|
|
7639
|
+
},
|
|
7640
|
+
{
|
|
7641
|
+
"value": "void"
|
|
7642
|
+
}
|
|
7643
|
+
]
|
|
6391
7644
|
},
|
|
6392
7645
|
{
|
|
6393
7646
|
"name": "hrefPattern",
|
|
@@ -6600,7 +7853,21 @@ const MANIFEST_SNAPSHOT = {
|
|
|
6600
7853
|
"name": "label"
|
|
6601
7854
|
},
|
|
6602
7855
|
{
|
|
6603
|
-
"name": "variant"
|
|
7856
|
+
"name": "variant",
|
|
7857
|
+
"values": [
|
|
7858
|
+
{
|
|
7859
|
+
"value": "default",
|
|
7860
|
+
"tier": "default"
|
|
7861
|
+
},
|
|
7862
|
+
{
|
|
7863
|
+
"value": "transparent",
|
|
7864
|
+
"tier": "opt-in"
|
|
7865
|
+
},
|
|
7866
|
+
{
|
|
7867
|
+
"value": "blur",
|
|
7868
|
+
"tier": "opt-in"
|
|
7869
|
+
}
|
|
7870
|
+
]
|
|
6604
7871
|
}
|
|
6605
7872
|
]
|
|
6606
7873
|
},
|
|
@@ -7229,6 +8496,10 @@ const MANIFEST_SNAPSHOT = {
|
|
|
7229
8496
|
{
|
|
7230
8497
|
"tag": "pagination-ui",
|
|
7231
8498
|
"attrs": [
|
|
8499
|
+
{
|
|
8500
|
+
"name": "noLandmark",
|
|
8501
|
+
"attribute": "no-landmark"
|
|
8502
|
+
},
|
|
7232
8503
|
{
|
|
7233
8504
|
"name": "page"
|
|
7234
8505
|
},
|
|
@@ -7434,7 +8705,15 @@ const MANIFEST_SNAPSHOT = {
|
|
|
7434
8705
|
"name": "current"
|
|
7435
8706
|
},
|
|
7436
8707
|
{
|
|
7437
|
-
"name": "cycle"
|
|
8708
|
+
"name": "cycle",
|
|
8709
|
+
"values": [
|
|
8710
|
+
{
|
|
8711
|
+
"value": "monthly"
|
|
8712
|
+
},
|
|
8713
|
+
{
|
|
8714
|
+
"value": "annual"
|
|
8715
|
+
}
|
|
8716
|
+
]
|
|
7438
8717
|
},
|
|
7439
8718
|
{
|
|
7440
8719
|
"name": "cycleToggle",
|
|
@@ -8149,6 +9428,10 @@ const MANIFEST_SNAPSHOT = {
|
|
|
8149
9428
|
{
|
|
8150
9429
|
"value": "dot-grid",
|
|
8151
9430
|
"tier": "default"
|
|
9431
|
+
},
|
|
9432
|
+
{
|
|
9433
|
+
"value": "noise",
|
|
9434
|
+
"tier": "alternative"
|
|
8152
9435
|
}
|
|
8153
9436
|
]
|
|
8154
9437
|
}
|
|
@@ -10082,7 +11365,7 @@ const MANIFEST_SNAPSHOT = {
|
|
|
10082
11365
|
|
|
10083
11366
|
RULES.push({
|
|
10084
11367
|
id: "ENUM-VALUE",
|
|
10085
|
-
severity: "
|
|
11368
|
+
severity: "error",
|
|
10086
11369
|
scope: 'shared',
|
|
10087
11370
|
fileTypes: MARKUP_EXT,
|
|
10088
11371
|
match(text, path = '') {
|
|
@@ -10103,12 +11386,12 @@ RULES.push({
|
|
|
10103
11386
|
}
|
|
10104
11387
|
|
|
10105
11388
|
{
|
|
10106
|
-
// GENERATED
|
|
11389
|
+
// GENERATED, do not hand-edit. Source: packages/web-components/**/*.a2ui.json + yaml,
|
|
10107
11390
|
// packages/web-modules/**/*.a2ui.json + yaml (ADR-0108 D5 / LLD-0019 C5).
|
|
10108
11391
|
// Rebuild: node scripts/build/gen-lab-posture-rules.mjs
|
|
10109
11392
|
// Freshness gate: node scripts/verify/check-lab-posture-rules-fresh.mjs --verify
|
|
10110
11393
|
//
|
|
10111
|
-
// INTERNAL-TIER (ADR-0108 D3/D5): a declared enum value present in the manifest but tiered `internal
|
|
11394
|
+
// INTERNAL-TIER (ADR-0108 D3/D5): a declared enum value present in the manifest but tiered `internal`, reachable in source, never the intended answer for a generator or author.
|
|
10112
11395
|
//
|
|
10113
11396
|
// severity: 'info' here governs ONLY `npm run lint`'s bare-repo-shaped
|
|
10114
11397
|
// advisory bank (ADR-0040 unchanged). The lab-posture write-time hook
|
|
@@ -10343,10 +11626,6 @@ const MANIFEST_SNAPSHOT = {
|
|
|
10343
11626
|
}
|
|
10344
11627
|
]
|
|
10345
11628
|
},
|
|
10346
|
-
{
|
|
10347
|
-
"tag": "admin-scroll",
|
|
10348
|
-
"attrs": []
|
|
10349
|
-
},
|
|
10350
11629
|
{
|
|
10351
11630
|
"tag": "admin-settings-ui",
|
|
10352
11631
|
"attrs": [
|
|
@@ -10462,6 +11741,9 @@ const MANIFEST_SNAPSHOT = {
|
|
|
10462
11741
|
{
|
|
10463
11742
|
"name": "multi"
|
|
10464
11743
|
},
|
|
11744
|
+
{
|
|
11745
|
+
"name": "options"
|
|
11746
|
+
},
|
|
10465
11747
|
{
|
|
10466
11748
|
"name": "question"
|
|
10467
11749
|
},
|
|
@@ -10525,6 +11807,9 @@ const MANIFEST_SNAPSHOT = {
|
|
|
10525
11807
|
}
|
|
10526
11808
|
]
|
|
10527
11809
|
},
|
|
11810
|
+
{
|
|
11811
|
+
"name": "suggestions"
|
|
11812
|
+
},
|
|
10528
11813
|
{
|
|
10529
11814
|
"name": "variant",
|
|
10530
11815
|
"values": [
|
|
@@ -11258,13 +12543,16 @@ const MANIFEST_SNAPSHOT = {
|
|
|
11258
12543
|
"name": "precision",
|
|
11259
12544
|
"values": [
|
|
11260
12545
|
{
|
|
11261
|
-
"value": "date"
|
|
12546
|
+
"value": "date",
|
|
12547
|
+
"tier": "default"
|
|
11262
12548
|
},
|
|
11263
12549
|
{
|
|
11264
|
-
"value": "minute"
|
|
12550
|
+
"value": "minute",
|
|
12551
|
+
"tier": "opt-in"
|
|
11265
12552
|
},
|
|
11266
12553
|
{
|
|
11267
|
-
"value": "second"
|
|
12554
|
+
"value": "second",
|
|
12555
|
+
"tier": "opt-in"
|
|
11268
12556
|
}
|
|
11269
12557
|
]
|
|
11270
12558
|
},
|
|
@@ -11788,6 +13076,10 @@ const MANIFEST_SNAPSHOT = {
|
|
|
11788
13076
|
},
|
|
11789
13077
|
{
|
|
11790
13078
|
"name": "thinking"
|
|
13079
|
+
},
|
|
13080
|
+
{
|
|
13081
|
+
"name": "thinkingBudget",
|
|
13082
|
+
"attribute": "thinking-budget"
|
|
11791
13083
|
}
|
|
11792
13084
|
]
|
|
11793
13085
|
},
|
|
@@ -12480,7 +13772,30 @@ const MANIFEST_SNAPSHOT = {
|
|
|
12480
13772
|
"name": "to"
|
|
12481
13773
|
},
|
|
12482
13774
|
{
|
|
12483
|
-
"name": "value"
|
|
13775
|
+
"name": "value",
|
|
13776
|
+
"values": [
|
|
13777
|
+
{
|
|
13778
|
+
"value": "today"
|
|
13779
|
+
},
|
|
13780
|
+
{
|
|
13781
|
+
"value": "7d"
|
|
13782
|
+
},
|
|
13783
|
+
{
|
|
13784
|
+
"value": "30d"
|
|
13785
|
+
},
|
|
13786
|
+
{
|
|
13787
|
+
"value": "90d"
|
|
13788
|
+
},
|
|
13789
|
+
{
|
|
13790
|
+
"value": "qtd"
|
|
13791
|
+
},
|
|
13792
|
+
{
|
|
13793
|
+
"value": "ytd"
|
|
13794
|
+
},
|
|
13795
|
+
{
|
|
13796
|
+
"value": "custom"
|
|
13797
|
+
}
|
|
13798
|
+
]
|
|
12484
13799
|
}
|
|
12485
13800
|
]
|
|
12486
13801
|
},
|
|
@@ -12613,16 +13928,19 @@ const MANIFEST_SNAPSHOT = {
|
|
|
12613
13928
|
"name": "side",
|
|
12614
13929
|
"values": [
|
|
12615
13930
|
{
|
|
12616
|
-
"value": "left"
|
|
13931
|
+
"value": "left",
|
|
13932
|
+
"tier": "opt-in"
|
|
12617
13933
|
},
|
|
12618
13934
|
{
|
|
12619
|
-
"value": "right"
|
|
13935
|
+
"value": "right",
|
|
13936
|
+
"tier": "default"
|
|
12620
13937
|
},
|
|
12621
13938
|
{
|
|
12622
13939
|
"value": "top"
|
|
12623
13940
|
},
|
|
12624
13941
|
{
|
|
12625
|
-
"value": "bottom"
|
|
13942
|
+
"value": "bottom",
|
|
13943
|
+
"tier": "opt-in"
|
|
12626
13944
|
}
|
|
12627
13945
|
]
|
|
12628
13946
|
},
|
|
@@ -13117,13 +14435,16 @@ const MANIFEST_SNAPSHOT = {
|
|
|
13117
14435
|
"name": "scale",
|
|
13118
14436
|
"values": [
|
|
13119
14437
|
{
|
|
13120
|
-
"value": "linear"
|
|
14438
|
+
"value": "linear",
|
|
14439
|
+
"tier": "default"
|
|
13121
14440
|
},
|
|
13122
14441
|
{
|
|
13123
|
-
"value": "log"
|
|
14442
|
+
"value": "log",
|
|
14443
|
+
"tier": "opt-in"
|
|
13124
14444
|
},
|
|
13125
14445
|
{
|
|
13126
|
-
"value": "quantile"
|
|
14446
|
+
"value": "quantile",
|
|
14447
|
+
"tier": "opt-in"
|
|
13127
14448
|
}
|
|
13128
14449
|
]
|
|
13129
14450
|
},
|
|
@@ -13344,7 +14665,29 @@ const MANIFEST_SNAPSHOT = {
|
|
|
13344
14665
|
"name": "text"
|
|
13345
14666
|
},
|
|
13346
14667
|
{
|
|
13347
|
-
"name": "variant"
|
|
14668
|
+
"name": "variant",
|
|
14669
|
+
"values": [
|
|
14670
|
+
{
|
|
14671
|
+
"value": "default",
|
|
14672
|
+
"tier": "default"
|
|
14673
|
+
},
|
|
14674
|
+
{
|
|
14675
|
+
"value": "info",
|
|
14676
|
+
"tier": "opt-in"
|
|
14677
|
+
},
|
|
14678
|
+
{
|
|
14679
|
+
"value": "success",
|
|
14680
|
+
"tier": "opt-in"
|
|
14681
|
+
},
|
|
14682
|
+
{
|
|
14683
|
+
"value": "warning",
|
|
14684
|
+
"tier": "opt-in"
|
|
14685
|
+
},
|
|
14686
|
+
{
|
|
14687
|
+
"value": "danger",
|
|
14688
|
+
"tier": "opt-in"
|
|
14689
|
+
}
|
|
14690
|
+
]
|
|
13348
14691
|
}
|
|
13349
14692
|
]
|
|
13350
14693
|
},
|
|
@@ -13390,7 +14733,33 @@ const MANIFEST_SNAPSHOT = {
|
|
|
13390
14733
|
"name": "error"
|
|
13391
14734
|
},
|
|
13392
14735
|
{
|
|
13393
|
-
"name": "inputmode"
|
|
14736
|
+
"name": "inputmode",
|
|
14737
|
+
"values": [
|
|
14738
|
+
{
|
|
14739
|
+
"value": "text"
|
|
14740
|
+
},
|
|
14741
|
+
{
|
|
14742
|
+
"value": "decimal"
|
|
14743
|
+
},
|
|
14744
|
+
{
|
|
14745
|
+
"value": "numeric"
|
|
14746
|
+
},
|
|
14747
|
+
{
|
|
14748
|
+
"value": "tel"
|
|
14749
|
+
},
|
|
14750
|
+
{
|
|
14751
|
+
"value": "search"
|
|
14752
|
+
},
|
|
14753
|
+
{
|
|
14754
|
+
"value": "email"
|
|
14755
|
+
},
|
|
14756
|
+
{
|
|
14757
|
+
"value": "url"
|
|
14758
|
+
},
|
|
14759
|
+
{
|
|
14760
|
+
"value": "none"
|
|
14761
|
+
}
|
|
14762
|
+
]
|
|
13394
14763
|
},
|
|
13395
14764
|
{
|
|
13396
14765
|
"name": "label"
|
|
@@ -13491,7 +14860,24 @@ const MANIFEST_SNAPSHOT = {
|
|
|
13491
14860
|
"required": true
|
|
13492
14861
|
},
|
|
13493
14862
|
{
|
|
13494
|
-
"name": "status"
|
|
14863
|
+
"name": "status",
|
|
14864
|
+
"values": [
|
|
14865
|
+
{
|
|
14866
|
+
"value": "available"
|
|
14867
|
+
},
|
|
14868
|
+
{
|
|
14869
|
+
"value": "connected"
|
|
14870
|
+
},
|
|
14871
|
+
{
|
|
14872
|
+
"value": "error"
|
|
14873
|
+
},
|
|
14874
|
+
{
|
|
14875
|
+
"value": "pending"
|
|
14876
|
+
},
|
|
14877
|
+
{
|
|
14878
|
+
"value": "coming-soon"
|
|
14879
|
+
}
|
|
14880
|
+
]
|
|
13495
14881
|
}
|
|
13496
14882
|
]
|
|
13497
14883
|
},
|
|
@@ -13523,7 +14909,24 @@ const MANIFEST_SNAPSHOT = {
|
|
|
13523
14909
|
"name": "searchPlaceholder"
|
|
13524
14910
|
},
|
|
13525
14911
|
{
|
|
13526
|
-
"name": "statusFilter"
|
|
14912
|
+
"name": "statusFilter",
|
|
14913
|
+
"values": [
|
|
14914
|
+
{
|
|
14915
|
+
"value": "all"
|
|
14916
|
+
},
|
|
14917
|
+
{
|
|
14918
|
+
"value": "available"
|
|
14919
|
+
},
|
|
14920
|
+
{
|
|
14921
|
+
"value": "connected"
|
|
14922
|
+
},
|
|
14923
|
+
{
|
|
14924
|
+
"value": "error"
|
|
14925
|
+
},
|
|
14926
|
+
{
|
|
14927
|
+
"value": "coming-soon"
|
|
14928
|
+
}
|
|
14929
|
+
]
|
|
13527
14930
|
}
|
|
13528
14931
|
]
|
|
13529
14932
|
},
|
|
@@ -13565,7 +14968,24 @@ const MANIFEST_SNAPSHOT = {
|
|
|
13565
14968
|
"name": "printable"
|
|
13566
14969
|
},
|
|
13567
14970
|
{
|
|
13568
|
-
"name": "status"
|
|
14971
|
+
"name": "status",
|
|
14972
|
+
"values": [
|
|
14973
|
+
{
|
|
14974
|
+
"value": "draft"
|
|
14975
|
+
},
|
|
14976
|
+
{
|
|
14977
|
+
"value": "open"
|
|
14978
|
+
},
|
|
14979
|
+
{
|
|
14980
|
+
"value": "paid"
|
|
14981
|
+
},
|
|
14982
|
+
{
|
|
14983
|
+
"value": "past-due"
|
|
14984
|
+
},
|
|
14985
|
+
{
|
|
14986
|
+
"value": "void"
|
|
14987
|
+
}
|
|
14988
|
+
]
|
|
13569
14989
|
}
|
|
13570
14990
|
]
|
|
13571
14991
|
},
|
|
@@ -13597,7 +15017,27 @@ const MANIFEST_SNAPSHOT = {
|
|
|
13597
15017
|
"name": "exportable"
|
|
13598
15018
|
},
|
|
13599
15019
|
{
|
|
13600
|
-
"name": "filter"
|
|
15020
|
+
"name": "filter",
|
|
15021
|
+
"values": [
|
|
15022
|
+
{
|
|
15023
|
+
"value": ""
|
|
15024
|
+
},
|
|
15025
|
+
{
|
|
15026
|
+
"value": "draft"
|
|
15027
|
+
},
|
|
15028
|
+
{
|
|
15029
|
+
"value": "open"
|
|
15030
|
+
},
|
|
15031
|
+
{
|
|
15032
|
+
"value": "paid"
|
|
15033
|
+
},
|
|
15034
|
+
{
|
|
15035
|
+
"value": "past-due"
|
|
15036
|
+
},
|
|
15037
|
+
{
|
|
15038
|
+
"value": "void"
|
|
15039
|
+
}
|
|
15040
|
+
]
|
|
13601
15041
|
},
|
|
13602
15042
|
{
|
|
13603
15043
|
"name": "hrefPattern",
|
|
@@ -13810,7 +15250,21 @@ const MANIFEST_SNAPSHOT = {
|
|
|
13810
15250
|
"name": "label"
|
|
13811
15251
|
},
|
|
13812
15252
|
{
|
|
13813
|
-
"name": "variant"
|
|
15253
|
+
"name": "variant",
|
|
15254
|
+
"values": [
|
|
15255
|
+
{
|
|
15256
|
+
"value": "default",
|
|
15257
|
+
"tier": "default"
|
|
15258
|
+
},
|
|
15259
|
+
{
|
|
15260
|
+
"value": "transparent",
|
|
15261
|
+
"tier": "opt-in"
|
|
15262
|
+
},
|
|
15263
|
+
{
|
|
15264
|
+
"value": "blur",
|
|
15265
|
+
"tier": "opt-in"
|
|
15266
|
+
}
|
|
15267
|
+
]
|
|
13814
15268
|
}
|
|
13815
15269
|
]
|
|
13816
15270
|
},
|
|
@@ -14439,6 +15893,10 @@ const MANIFEST_SNAPSHOT = {
|
|
|
14439
15893
|
{
|
|
14440
15894
|
"tag": "pagination-ui",
|
|
14441
15895
|
"attrs": [
|
|
15896
|
+
{
|
|
15897
|
+
"name": "noLandmark",
|
|
15898
|
+
"attribute": "no-landmark"
|
|
15899
|
+
},
|
|
14442
15900
|
{
|
|
14443
15901
|
"name": "page"
|
|
14444
15902
|
},
|
|
@@ -14644,7 +16102,15 @@ const MANIFEST_SNAPSHOT = {
|
|
|
14644
16102
|
"name": "current"
|
|
14645
16103
|
},
|
|
14646
16104
|
{
|
|
14647
|
-
"name": "cycle"
|
|
16105
|
+
"name": "cycle",
|
|
16106
|
+
"values": [
|
|
16107
|
+
{
|
|
16108
|
+
"value": "monthly"
|
|
16109
|
+
},
|
|
16110
|
+
{
|
|
16111
|
+
"value": "annual"
|
|
16112
|
+
}
|
|
16113
|
+
]
|
|
14648
16114
|
},
|
|
14649
16115
|
{
|
|
14650
16116
|
"name": "cycleToggle",
|
|
@@ -15359,6 +16825,10 @@ const MANIFEST_SNAPSHOT = {
|
|
|
15359
16825
|
{
|
|
15360
16826
|
"value": "dot-grid",
|
|
15361
16827
|
"tier": "default"
|
|
16828
|
+
},
|
|
16829
|
+
{
|
|
16830
|
+
"value": "noise",
|
|
16831
|
+
"tier": "alternative"
|
|
15362
16832
|
}
|
|
15363
16833
|
]
|
|
15364
16834
|
}
|
|
@@ -17313,18 +18783,23 @@ RULES.push({
|
|
|
17313
18783
|
}
|
|
17314
18784
|
|
|
17315
18785
|
{
|
|
17316
|
-
// GENERATED
|
|
18786
|
+
// GENERATED, do not hand-edit. Source: packages/web-components/**/*.a2ui.json + yaml,
|
|
17317
18787
|
// packages/web-modules/**/*.a2ui.json + yaml (ADR-0108 D5 / LLD-0019 C5).
|
|
17318
18788
|
// Rebuild: node scripts/build/gen-lab-posture-rules.mjs
|
|
17319
18789
|
// Freshness gate: node scripts/verify/check-lab-posture-rules-fresh.mjs --verify
|
|
17320
18790
|
//
|
|
17321
18791
|
// REQUIRED-ATTR (ADR-0108 D5 / gh#3221): a manifest-declared `required: true` prop with no matching attribute set on the occurrence at all.
|
|
17322
18792
|
//
|
|
17323
|
-
// severity: 'warn' here governs
|
|
17324
|
-
// advisory bank (ADR-0040 unchanged)
|
|
18793
|
+
// severity: 'warn' here governs `npm run lint`'s bare-repo-shaped
|
|
18794
|
+
// advisory bank (ADR-0040 unchanged) AND the lab-posture write-time hook
|
|
17325
18795
|
// (packages/plugins/adia-ui-factory/scripts/lab-posture-guard.mjs,
|
|
17326
|
-
// LLD-0019 C4
|
|
17327
|
-
//
|
|
18796
|
+
// LLD-0019 C4 amendment, gh#3236) — unlike every sibling rule in this
|
|
18797
|
+
// family, this one IS wired into the hook's write-time pass but never
|
|
18798
|
+
// denies: a finding surfaces as a non-blocking `hookSpecificOutput.
|
|
18799
|
+
// additionalContext` on a "allow" decision instead (conductor ruling,
|
|
18800
|
+
// gh#3221, 2026-09-04: "a false-positive rule never blocks authoring at
|
|
18801
|
+
// the keystroke"). The other four rules in this family stay severity-
|
|
18802
|
+
// blind at write time — ANY of their findings still denies unconditionally
|
|
17328
18803
|
// (ADR-0108 D5: "PreToolUse deny... error under the lab hook").
|
|
17329
18804
|
|
|
17330
18805
|
|
|
@@ -17544,10 +19019,6 @@ const MANIFEST_SNAPSHOT = {
|
|
|
17544
19019
|
}
|
|
17545
19020
|
]
|
|
17546
19021
|
},
|
|
17547
|
-
{
|
|
17548
|
-
"tag": "admin-scroll",
|
|
17549
|
-
"attrs": []
|
|
17550
|
-
},
|
|
17551
19022
|
{
|
|
17552
19023
|
"tag": "admin-settings-ui",
|
|
17553
19024
|
"attrs": [
|
|
@@ -17663,6 +19134,9 @@ const MANIFEST_SNAPSHOT = {
|
|
|
17663
19134
|
{
|
|
17664
19135
|
"name": "multi"
|
|
17665
19136
|
},
|
|
19137
|
+
{
|
|
19138
|
+
"name": "options"
|
|
19139
|
+
},
|
|
17666
19140
|
{
|
|
17667
19141
|
"name": "question"
|
|
17668
19142
|
},
|
|
@@ -17726,6 +19200,9 @@ const MANIFEST_SNAPSHOT = {
|
|
|
17726
19200
|
}
|
|
17727
19201
|
]
|
|
17728
19202
|
},
|
|
19203
|
+
{
|
|
19204
|
+
"name": "suggestions"
|
|
19205
|
+
},
|
|
17729
19206
|
{
|
|
17730
19207
|
"name": "variant",
|
|
17731
19208
|
"values": [
|
|
@@ -18459,13 +19936,16 @@ const MANIFEST_SNAPSHOT = {
|
|
|
18459
19936
|
"name": "precision",
|
|
18460
19937
|
"values": [
|
|
18461
19938
|
{
|
|
18462
|
-
"value": "date"
|
|
19939
|
+
"value": "date",
|
|
19940
|
+
"tier": "default"
|
|
18463
19941
|
},
|
|
18464
19942
|
{
|
|
18465
|
-
"value": "minute"
|
|
19943
|
+
"value": "minute",
|
|
19944
|
+
"tier": "opt-in"
|
|
18466
19945
|
},
|
|
18467
19946
|
{
|
|
18468
|
-
"value": "second"
|
|
19947
|
+
"value": "second",
|
|
19948
|
+
"tier": "opt-in"
|
|
18469
19949
|
}
|
|
18470
19950
|
]
|
|
18471
19951
|
},
|
|
@@ -18989,6 +20469,10 @@ const MANIFEST_SNAPSHOT = {
|
|
|
18989
20469
|
},
|
|
18990
20470
|
{
|
|
18991
20471
|
"name": "thinking"
|
|
20472
|
+
},
|
|
20473
|
+
{
|
|
20474
|
+
"name": "thinkingBudget",
|
|
20475
|
+
"attribute": "thinking-budget"
|
|
18992
20476
|
}
|
|
18993
20477
|
]
|
|
18994
20478
|
},
|
|
@@ -19681,7 +21165,30 @@ const MANIFEST_SNAPSHOT = {
|
|
|
19681
21165
|
"name": "to"
|
|
19682
21166
|
},
|
|
19683
21167
|
{
|
|
19684
|
-
"name": "value"
|
|
21168
|
+
"name": "value",
|
|
21169
|
+
"values": [
|
|
21170
|
+
{
|
|
21171
|
+
"value": "today"
|
|
21172
|
+
},
|
|
21173
|
+
{
|
|
21174
|
+
"value": "7d"
|
|
21175
|
+
},
|
|
21176
|
+
{
|
|
21177
|
+
"value": "30d"
|
|
21178
|
+
},
|
|
21179
|
+
{
|
|
21180
|
+
"value": "90d"
|
|
21181
|
+
},
|
|
21182
|
+
{
|
|
21183
|
+
"value": "qtd"
|
|
21184
|
+
},
|
|
21185
|
+
{
|
|
21186
|
+
"value": "ytd"
|
|
21187
|
+
},
|
|
21188
|
+
{
|
|
21189
|
+
"value": "custom"
|
|
21190
|
+
}
|
|
21191
|
+
]
|
|
19685
21192
|
}
|
|
19686
21193
|
]
|
|
19687
21194
|
},
|
|
@@ -19814,16 +21321,19 @@ const MANIFEST_SNAPSHOT = {
|
|
|
19814
21321
|
"name": "side",
|
|
19815
21322
|
"values": [
|
|
19816
21323
|
{
|
|
19817
|
-
"value": "left"
|
|
21324
|
+
"value": "left",
|
|
21325
|
+
"tier": "opt-in"
|
|
19818
21326
|
},
|
|
19819
21327
|
{
|
|
19820
|
-
"value": "right"
|
|
21328
|
+
"value": "right",
|
|
21329
|
+
"tier": "default"
|
|
19821
21330
|
},
|
|
19822
21331
|
{
|
|
19823
21332
|
"value": "top"
|
|
19824
21333
|
},
|
|
19825
21334
|
{
|
|
19826
|
-
"value": "bottom"
|
|
21335
|
+
"value": "bottom",
|
|
21336
|
+
"tier": "opt-in"
|
|
19827
21337
|
}
|
|
19828
21338
|
]
|
|
19829
21339
|
},
|
|
@@ -20318,13 +21828,16 @@ const MANIFEST_SNAPSHOT = {
|
|
|
20318
21828
|
"name": "scale",
|
|
20319
21829
|
"values": [
|
|
20320
21830
|
{
|
|
20321
|
-
"value": "linear"
|
|
21831
|
+
"value": "linear",
|
|
21832
|
+
"tier": "default"
|
|
20322
21833
|
},
|
|
20323
21834
|
{
|
|
20324
|
-
"value": "log"
|
|
21835
|
+
"value": "log",
|
|
21836
|
+
"tier": "opt-in"
|
|
20325
21837
|
},
|
|
20326
21838
|
{
|
|
20327
|
-
"value": "quantile"
|
|
21839
|
+
"value": "quantile",
|
|
21840
|
+
"tier": "opt-in"
|
|
20328
21841
|
}
|
|
20329
21842
|
]
|
|
20330
21843
|
},
|
|
@@ -20534,18 +22047,40 @@ const MANIFEST_SNAPSHOT = {
|
|
|
20534
22047
|
"value": "off"
|
|
20535
22048
|
},
|
|
20536
22049
|
{
|
|
20537
|
-
"value": "polite"
|
|
22050
|
+
"value": "polite"
|
|
22051
|
+
},
|
|
22052
|
+
{
|
|
22053
|
+
"value": "assertive"
|
|
22054
|
+
}
|
|
22055
|
+
]
|
|
22056
|
+
},
|
|
22057
|
+
{
|
|
22058
|
+
"name": "text"
|
|
22059
|
+
},
|
|
22060
|
+
{
|
|
22061
|
+
"name": "variant",
|
|
22062
|
+
"values": [
|
|
22063
|
+
{
|
|
22064
|
+
"value": "default",
|
|
22065
|
+
"tier": "default"
|
|
22066
|
+
},
|
|
22067
|
+
{
|
|
22068
|
+
"value": "info",
|
|
22069
|
+
"tier": "opt-in"
|
|
22070
|
+
},
|
|
22071
|
+
{
|
|
22072
|
+
"value": "success",
|
|
22073
|
+
"tier": "opt-in"
|
|
22074
|
+
},
|
|
22075
|
+
{
|
|
22076
|
+
"value": "warning",
|
|
22077
|
+
"tier": "opt-in"
|
|
20538
22078
|
},
|
|
20539
22079
|
{
|
|
20540
|
-
"value": "
|
|
22080
|
+
"value": "danger",
|
|
22081
|
+
"tier": "opt-in"
|
|
20541
22082
|
}
|
|
20542
22083
|
]
|
|
20543
|
-
},
|
|
20544
|
-
{
|
|
20545
|
-
"name": "text"
|
|
20546
|
-
},
|
|
20547
|
-
{
|
|
20548
|
-
"name": "variant"
|
|
20549
22084
|
}
|
|
20550
22085
|
]
|
|
20551
22086
|
},
|
|
@@ -20591,7 +22126,33 @@ const MANIFEST_SNAPSHOT = {
|
|
|
20591
22126
|
"name": "error"
|
|
20592
22127
|
},
|
|
20593
22128
|
{
|
|
20594
|
-
"name": "inputmode"
|
|
22129
|
+
"name": "inputmode",
|
|
22130
|
+
"values": [
|
|
22131
|
+
{
|
|
22132
|
+
"value": "text"
|
|
22133
|
+
},
|
|
22134
|
+
{
|
|
22135
|
+
"value": "decimal"
|
|
22136
|
+
},
|
|
22137
|
+
{
|
|
22138
|
+
"value": "numeric"
|
|
22139
|
+
},
|
|
22140
|
+
{
|
|
22141
|
+
"value": "tel"
|
|
22142
|
+
},
|
|
22143
|
+
{
|
|
22144
|
+
"value": "search"
|
|
22145
|
+
},
|
|
22146
|
+
{
|
|
22147
|
+
"value": "email"
|
|
22148
|
+
},
|
|
22149
|
+
{
|
|
22150
|
+
"value": "url"
|
|
22151
|
+
},
|
|
22152
|
+
{
|
|
22153
|
+
"value": "none"
|
|
22154
|
+
}
|
|
22155
|
+
]
|
|
20595
22156
|
},
|
|
20596
22157
|
{
|
|
20597
22158
|
"name": "label"
|
|
@@ -20692,7 +22253,24 @@ const MANIFEST_SNAPSHOT = {
|
|
|
20692
22253
|
"required": true
|
|
20693
22254
|
},
|
|
20694
22255
|
{
|
|
20695
|
-
"name": "status"
|
|
22256
|
+
"name": "status",
|
|
22257
|
+
"values": [
|
|
22258
|
+
{
|
|
22259
|
+
"value": "available"
|
|
22260
|
+
},
|
|
22261
|
+
{
|
|
22262
|
+
"value": "connected"
|
|
22263
|
+
},
|
|
22264
|
+
{
|
|
22265
|
+
"value": "error"
|
|
22266
|
+
},
|
|
22267
|
+
{
|
|
22268
|
+
"value": "pending"
|
|
22269
|
+
},
|
|
22270
|
+
{
|
|
22271
|
+
"value": "coming-soon"
|
|
22272
|
+
}
|
|
22273
|
+
]
|
|
20696
22274
|
}
|
|
20697
22275
|
]
|
|
20698
22276
|
},
|
|
@@ -20724,7 +22302,24 @@ const MANIFEST_SNAPSHOT = {
|
|
|
20724
22302
|
"name": "searchPlaceholder"
|
|
20725
22303
|
},
|
|
20726
22304
|
{
|
|
20727
|
-
"name": "statusFilter"
|
|
22305
|
+
"name": "statusFilter",
|
|
22306
|
+
"values": [
|
|
22307
|
+
{
|
|
22308
|
+
"value": "all"
|
|
22309
|
+
},
|
|
22310
|
+
{
|
|
22311
|
+
"value": "available"
|
|
22312
|
+
},
|
|
22313
|
+
{
|
|
22314
|
+
"value": "connected"
|
|
22315
|
+
},
|
|
22316
|
+
{
|
|
22317
|
+
"value": "error"
|
|
22318
|
+
},
|
|
22319
|
+
{
|
|
22320
|
+
"value": "coming-soon"
|
|
22321
|
+
}
|
|
22322
|
+
]
|
|
20728
22323
|
}
|
|
20729
22324
|
]
|
|
20730
22325
|
},
|
|
@@ -20766,7 +22361,24 @@ const MANIFEST_SNAPSHOT = {
|
|
|
20766
22361
|
"name": "printable"
|
|
20767
22362
|
},
|
|
20768
22363
|
{
|
|
20769
|
-
"name": "status"
|
|
22364
|
+
"name": "status",
|
|
22365
|
+
"values": [
|
|
22366
|
+
{
|
|
22367
|
+
"value": "draft"
|
|
22368
|
+
},
|
|
22369
|
+
{
|
|
22370
|
+
"value": "open"
|
|
22371
|
+
},
|
|
22372
|
+
{
|
|
22373
|
+
"value": "paid"
|
|
22374
|
+
},
|
|
22375
|
+
{
|
|
22376
|
+
"value": "past-due"
|
|
22377
|
+
},
|
|
22378
|
+
{
|
|
22379
|
+
"value": "void"
|
|
22380
|
+
}
|
|
22381
|
+
]
|
|
20770
22382
|
}
|
|
20771
22383
|
]
|
|
20772
22384
|
},
|
|
@@ -20798,7 +22410,27 @@ const MANIFEST_SNAPSHOT = {
|
|
|
20798
22410
|
"name": "exportable"
|
|
20799
22411
|
},
|
|
20800
22412
|
{
|
|
20801
|
-
"name": "filter"
|
|
22413
|
+
"name": "filter",
|
|
22414
|
+
"values": [
|
|
22415
|
+
{
|
|
22416
|
+
"value": ""
|
|
22417
|
+
},
|
|
22418
|
+
{
|
|
22419
|
+
"value": "draft"
|
|
22420
|
+
},
|
|
22421
|
+
{
|
|
22422
|
+
"value": "open"
|
|
22423
|
+
},
|
|
22424
|
+
{
|
|
22425
|
+
"value": "paid"
|
|
22426
|
+
},
|
|
22427
|
+
{
|
|
22428
|
+
"value": "past-due"
|
|
22429
|
+
},
|
|
22430
|
+
{
|
|
22431
|
+
"value": "void"
|
|
22432
|
+
}
|
|
22433
|
+
]
|
|
20802
22434
|
},
|
|
20803
22435
|
{
|
|
20804
22436
|
"name": "hrefPattern",
|
|
@@ -21011,7 +22643,21 @@ const MANIFEST_SNAPSHOT = {
|
|
|
21011
22643
|
"name": "label"
|
|
21012
22644
|
},
|
|
21013
22645
|
{
|
|
21014
|
-
"name": "variant"
|
|
22646
|
+
"name": "variant",
|
|
22647
|
+
"values": [
|
|
22648
|
+
{
|
|
22649
|
+
"value": "default",
|
|
22650
|
+
"tier": "default"
|
|
22651
|
+
},
|
|
22652
|
+
{
|
|
22653
|
+
"value": "transparent",
|
|
22654
|
+
"tier": "opt-in"
|
|
22655
|
+
},
|
|
22656
|
+
{
|
|
22657
|
+
"value": "blur",
|
|
22658
|
+
"tier": "opt-in"
|
|
22659
|
+
}
|
|
22660
|
+
]
|
|
21015
22661
|
}
|
|
21016
22662
|
]
|
|
21017
22663
|
},
|
|
@@ -21640,6 +23286,10 @@ const MANIFEST_SNAPSHOT = {
|
|
|
21640
23286
|
{
|
|
21641
23287
|
"tag": "pagination-ui",
|
|
21642
23288
|
"attrs": [
|
|
23289
|
+
{
|
|
23290
|
+
"name": "noLandmark",
|
|
23291
|
+
"attribute": "no-landmark"
|
|
23292
|
+
},
|
|
21643
23293
|
{
|
|
21644
23294
|
"name": "page"
|
|
21645
23295
|
},
|
|
@@ -21845,7 +23495,15 @@ const MANIFEST_SNAPSHOT = {
|
|
|
21845
23495
|
"name": "current"
|
|
21846
23496
|
},
|
|
21847
23497
|
{
|
|
21848
|
-
"name": "cycle"
|
|
23498
|
+
"name": "cycle",
|
|
23499
|
+
"values": [
|
|
23500
|
+
{
|
|
23501
|
+
"value": "monthly"
|
|
23502
|
+
},
|
|
23503
|
+
{
|
|
23504
|
+
"value": "annual"
|
|
23505
|
+
}
|
|
23506
|
+
]
|
|
21849
23507
|
},
|
|
21850
23508
|
{
|
|
21851
23509
|
"name": "cycleToggle",
|
|
@@ -22560,6 +24218,10 @@ const MANIFEST_SNAPSHOT = {
|
|
|
22560
24218
|
{
|
|
22561
24219
|
"value": "dot-grid",
|
|
22562
24220
|
"tier": "default"
|
|
24221
|
+
},
|
|
24222
|
+
{
|
|
24223
|
+
"value": "noise",
|
|
24224
|
+
"tier": "alternative"
|
|
22563
24225
|
}
|
|
22564
24226
|
]
|
|
22565
24227
|
}
|
|
@@ -24513,7 +26175,7 @@ RULES.push({
|
|
|
24513
26175
|
}
|
|
24514
26176
|
|
|
24515
26177
|
{
|
|
24516
|
-
// GENERATED
|
|
26178
|
+
// GENERATED, do not hand-edit. Source: packages/web-components/**/*.a2ui.json + yaml,
|
|
24517
26179
|
// packages/web-modules/**/*.a2ui.json + yaml (ADR-0108 D5 / LLD-0019 C5).
|
|
24518
26180
|
// Rebuild: node scripts/build/gen-lab-posture-rules.mjs
|
|
24519
26181
|
// Freshness gate: node scripts/verify/check-lab-posture-rules-fresh.mjs --verify
|
|
@@ -24672,10 +26334,6 @@ const MANIFEST_SNAPSHOT = {
|
|
|
24672
26334
|
}
|
|
24673
26335
|
]
|
|
24674
26336
|
},
|
|
24675
|
-
{
|
|
24676
|
-
"tag": "admin-scroll",
|
|
24677
|
-
"attrs": []
|
|
24678
|
-
},
|
|
24679
26337
|
{
|
|
24680
26338
|
"tag": "admin-settings-ui",
|
|
24681
26339
|
"attrs": [
|
|
@@ -24788,6 +26446,9 @@ const MANIFEST_SNAPSHOT = {
|
|
|
24788
26446
|
{
|
|
24789
26447
|
"name": "multi"
|
|
24790
26448
|
},
|
|
26449
|
+
{
|
|
26450
|
+
"name": "options"
|
|
26451
|
+
},
|
|
24791
26452
|
{
|
|
24792
26453
|
"name": "question"
|
|
24793
26454
|
},
|
|
@@ -24827,6 +26488,9 @@ const MANIFEST_SNAPSHOT = {
|
|
|
24827
26488
|
{
|
|
24828
26489
|
"name": "size"
|
|
24829
26490
|
},
|
|
26491
|
+
{
|
|
26492
|
+
"name": "suggestions"
|
|
26493
|
+
},
|
|
24830
26494
|
{
|
|
24831
26495
|
"name": "variant"
|
|
24832
26496
|
}
|
|
@@ -25380,6 +27044,10 @@ const MANIFEST_SNAPSHOT = {
|
|
|
25380
27044
|
},
|
|
25381
27045
|
{
|
|
25382
27046
|
"name": "thinking"
|
|
27047
|
+
},
|
|
27048
|
+
{
|
|
27049
|
+
"name": "thinkingBudget",
|
|
27050
|
+
"attribute": "thinking-budget"
|
|
25383
27051
|
}
|
|
25384
27052
|
]
|
|
25385
27053
|
},
|
|
@@ -27129,6 +28797,10 @@ const MANIFEST_SNAPSHOT = {
|
|
|
27129
28797
|
{
|
|
27130
28798
|
"tag": "pagination-ui",
|
|
27131
28799
|
"attrs": [
|
|
28800
|
+
{
|
|
28801
|
+
"name": "noLandmark",
|
|
28802
|
+
"attribute": "no-landmark"
|
|
28803
|
+
},
|
|
27132
28804
|
{
|
|
27133
28805
|
"name": "page"
|
|
27134
28806
|
},
|
|
@@ -28963,7 +30635,131 @@ RULES.push({
|
|
|
28963
30635
|
}
|
|
28964
30636
|
|
|
28965
30637
|
{
|
|
28966
|
-
// GENERATED
|
|
30638
|
+
// GENERATED, do not hand-edit. Source: packages/web-components/**/*.a2ui.json + yaml,
|
|
30639
|
+
// packages/web-modules/**/*.a2ui.json + yaml (ADR-0108 D5 / LLD-0019 C5).
|
|
30640
|
+
// Rebuild: node scripts/build/gen-lab-posture-rules.mjs
|
|
30641
|
+
// Freshness gate: node scripts/verify/check-lab-posture-rules-fresh.mjs --verify
|
|
30642
|
+
//
|
|
30643
|
+
// UNKNOWN-SLOT (gh#3222): a `slot="…"` value that is not a slot name any component in the installed manifest declares. Name only, never placement: see trimForEmbed's own `slot-names` branch for why there is no per-tag/nearest-ancestor check.
|
|
30644
|
+
//
|
|
30645
|
+
// severity: 'error' here governs ONLY `npm run lint`'s bare-repo-shaped
|
|
30646
|
+
// advisory bank (ADR-0040 unchanged). The lab-posture write-time hook
|
|
30647
|
+
// (packages/plugins/adia-ui-factory/scripts/lab-posture-guard.mjs,
|
|
30648
|
+
// LLD-0019 C4) does not read this field — a lab-posture write denies on
|
|
30649
|
+
// ANY finding from these same matcher functions regardless of severity
|
|
30650
|
+
// (ADR-0108 D5: "PreToolUse deny... error under the lab hook").
|
|
30651
|
+
|
|
30652
|
+
|
|
30653
|
+
const MANIFEST_SNAPSHOT = {
|
|
30654
|
+
"slotNames": [
|
|
30655
|
+
"action",
|
|
30656
|
+
"action-leading",
|
|
30657
|
+
"actions",
|
|
30658
|
+
"actions-leading",
|
|
30659
|
+
"add",
|
|
30660
|
+
"after",
|
|
30661
|
+
"after-invoice-history",
|
|
30662
|
+
"aside",
|
|
30663
|
+
"attach",
|
|
30664
|
+
"badge",
|
|
30665
|
+
"bar",
|
|
30666
|
+
"before",
|
|
30667
|
+
"before-plan-picker",
|
|
30668
|
+
"body",
|
|
30669
|
+
"breadcrumb",
|
|
30670
|
+
"canvas",
|
|
30671
|
+
"caption",
|
|
30672
|
+
"caret",
|
|
30673
|
+
"change",
|
|
30674
|
+
"chart",
|
|
30675
|
+
"charts",
|
|
30676
|
+
"chip",
|
|
30677
|
+
"chrome",
|
|
30678
|
+
"cite",
|
|
30679
|
+
"close",
|
|
30680
|
+
"complete",
|
|
30681
|
+
"content",
|
|
30682
|
+
"copy",
|
|
30683
|
+
"cursor",
|
|
30684
|
+
"customer-block",
|
|
30685
|
+
"default",
|
|
30686
|
+
"description",
|
|
30687
|
+
"digit",
|
|
30688
|
+
"empty",
|
|
30689
|
+
"error",
|
|
30690
|
+
"eyebrow",
|
|
30691
|
+
"footer",
|
|
30692
|
+
"header",
|
|
30693
|
+
"header-actions",
|
|
30694
|
+
"heading",
|
|
30695
|
+
"hint",
|
|
30696
|
+
"icon",
|
|
30697
|
+
"icon-trailing",
|
|
30698
|
+
"image",
|
|
30699
|
+
"kpis",
|
|
30700
|
+
"label",
|
|
30701
|
+
"leading",
|
|
30702
|
+
"lede",
|
|
30703
|
+
"legal",
|
|
30704
|
+
"loading",
|
|
30705
|
+
"media",
|
|
30706
|
+
"meta",
|
|
30707
|
+
"model",
|
|
30708
|
+
"name",
|
|
30709
|
+
"off",
|
|
30710
|
+
"on",
|
|
30711
|
+
"panel",
|
|
30712
|
+
"popover",
|
|
30713
|
+
"prefix",
|
|
30714
|
+
"presets",
|
|
30715
|
+
"primary",
|
|
30716
|
+
"remit-to-block",
|
|
30717
|
+
"scope",
|
|
30718
|
+
"secondary",
|
|
30719
|
+
"send",
|
|
30720
|
+
"skeleton",
|
|
30721
|
+
"status",
|
|
30722
|
+
"subtitle",
|
|
30723
|
+
"suffix",
|
|
30724
|
+
"summary",
|
|
30725
|
+
"table",
|
|
30726
|
+
"text",
|
|
30727
|
+
"time",
|
|
30728
|
+
"title",
|
|
30729
|
+
"toolbar",
|
|
30730
|
+
"track",
|
|
30731
|
+
"trailing",
|
|
30732
|
+
"trigger",
|
|
30733
|
+
"value",
|
|
30734
|
+
"zoom"
|
|
30735
|
+
]
|
|
30736
|
+
};
|
|
30737
|
+
|
|
30738
|
+
|
|
30739
|
+
RULES.push({
|
|
30740
|
+
id: "UNKNOWN-SLOT",
|
|
30741
|
+
severity: "error",
|
|
30742
|
+
scope: 'shared',
|
|
30743
|
+
fileTypes: MARKUP_EXT,
|
|
30744
|
+
match(text, path = '') {
|
|
30745
|
+
return slotNameFindings(text, MANIFEST_SNAPSHOT, path).map((f) => ({ line: f.line, snippet: f.snippet, why: f.why }));
|
|
30746
|
+
},
|
|
30747
|
+
fix: null, // a manifest-drift violation names the correction in its own diagnostic; applying it is a judgment call the agent makes, not a mechanical rewrite
|
|
30748
|
+
fixtures: {
|
|
30749
|
+
"smelly": [
|
|
30750
|
+
"<span slot=\"not-a-real-slot-name\"></span>"
|
|
30751
|
+
],
|
|
30752
|
+
"clean": [
|
|
30753
|
+
"<span slot=\"action\"></span>",
|
|
30754
|
+
"<span slot=\"${s.section}\"></span>",
|
|
30755
|
+
"<span slot=\"{s.section}\"></span>"
|
|
30756
|
+
]
|
|
30757
|
+
},
|
|
30758
|
+
});
|
|
30759
|
+
}
|
|
30760
|
+
|
|
30761
|
+
{
|
|
30762
|
+
// GENERATED, do not hand-edit. Source: packages/web-components/**/*.a2ui.json + yaml,
|
|
28967
30763
|
// packages/web-modules/**/*.a2ui.json + yaml (ADR-0108 D5 / LLD-0019 C5).
|
|
28968
30764
|
// Rebuild: node scripts/build/gen-lab-posture-rules.mjs
|
|
28969
30765
|
// Freshness gate: node scripts/verify/check-lab-posture-rules-fresh.mjs --verify
|
|
@@ -29024,10 +30820,6 @@ const MANIFEST_SNAPSHOT = {
|
|
|
29024
30820
|
"tag": "admin-roster-ui",
|
|
29025
30821
|
"attrs": []
|
|
29026
30822
|
},
|
|
29027
|
-
{
|
|
29028
|
-
"tag": "admin-scroll",
|
|
29029
|
-
"attrs": []
|
|
29030
|
-
},
|
|
29031
30823
|
{
|
|
29032
30824
|
"tag": "admin-settings-ui",
|
|
29033
30825
|
"attrs": []
|
|
@@ -30580,6 +32372,120 @@ RULES.push({
|
|
|
30580
32372
|
{
|
|
30581
32373
|
|
|
30582
32374
|
|
|
32375
|
+
// gh#3627 (follow-up to gh#3604): select-ui's avatar `<img>` shipped with no
|
|
32376
|
+
// width/height HTML attributes, sizing purely dependent on select.css's own
|
|
32377
|
+
// rule loading before first paint. select.css already carried explicit
|
|
32378
|
+
// width/height on that selector (packages/web-components/components/select/
|
|
32379
|
+
// select.css's `img[data-option-avatar]` rule), nothing was wrong with the
|
|
32380
|
+
// CSS. The gap was the OTHER half of the contract: an `<img>` stamped by a
|
|
32381
|
+
// component's own render logic needs its own width/height (or an inline
|
|
32382
|
+
// aspect-ratio) so the box is reserved from HTML parse time, independent of
|
|
32383
|
+
// when that component's stylesheet actually applies (a per-route CSS bundle
|
|
32384
|
+
// can arrive after first paint, gh#3357). gh#3604's fix added exactly that
|
|
32385
|
+
// to the three template-literal `<img>` sites in select.class.js; this rule
|
|
32386
|
+
// keeps a fourth one from shipping the same way.
|
|
32387
|
+
//
|
|
32388
|
+
// Scope, deliberately narrow: ONLY a literal `<img ...>` tag authored
|
|
32389
|
+
// inside a JS template-literal/string in packages/web-components or
|
|
32390
|
+
// packages/web-modules, the shape that actually regressed. Three things
|
|
32391
|
+
// this rule does NOT catch, on purpose:
|
|
32392
|
+
// 1. `document.createElement('img')` call sites (avatar.class.js,
|
|
32393
|
+
// image.class.js, integration-card.class.js), each of those adopts
|
|
32394
|
+
// the img into a host element that already carries its own explicit
|
|
32395
|
+
// size (avatar-ui's :host sizing tokens, image-ui's own #applySize(),
|
|
32396
|
+
// a fixed-size logo slot), so the box is reserved by the PARENT
|
|
32397
|
+
// regardless of the img's own attributes. Flagging every
|
|
32398
|
+
// createElement('img') would nag on a legitimate, already-reserved
|
|
32399
|
+
// pattern this framework uses on purpose, exactly the "sized by a
|
|
32400
|
+
// parent's grid cell" false positive this rule is written to avoid.
|
|
32401
|
+
// 2. Demo/example/gallery markup (`.html`, `.yaml` examples, `.a2ui.json`),
|
|
32402
|
+
// illustrative content already exempt from render-timing concerns
|
|
32403
|
+
// (HARDCODED-OPEN's `.examples.html` precedent is the same reasoning).
|
|
32404
|
+
// 3. `apps/`, `playgrounds/`, `catalog/`, consumer/demo surfaces, not
|
|
32405
|
+
// framework source. NO-LOCAL-ESCAPE-HTML (gh#3641/gh#3678) is the
|
|
32406
|
+
// precedent for widening a framework-scoped rule to a consumer tree
|
|
32407
|
+
// only once a ticket finds and migrates a real instance there; no such
|
|
32408
|
+
// instance exists for this rule yet.
|
|
32409
|
+
// An author who has a real reason an img here doesn't need its own box
|
|
32410
|
+
// (e.g. deliberately sized by an ancestor CSS grid/flex cell) can still
|
|
32411
|
+
// suppress a specific finding with the standard engine-wide
|
|
32412
|
+
// adia-lint-disable comment (SUPPRESS_RE/suppressionFor, primitives.mjs).
|
|
32413
|
+
//
|
|
32414
|
+
// Known imprecision (documented, not fixed here): like every other
|
|
32415
|
+
// CODE_EXT rule in this bank, comment-stripping is line-based and doesn't
|
|
32416
|
+
// understand string literals, so a hardcoded `src="https://..."` URL on
|
|
32417
|
+
// the SAME source line as `width=`/`height=` would truncate the line at
|
|
32418
|
+
// `//` and could false-positive. Every real instance in this corpus today
|
|
32419
|
+
// interpolates `src` from a variable (`src="${escapeHTML(x)}"`), not a
|
|
32420
|
+
// literal URL, so this hasn't triggered in practice; a literal `//` URL
|
|
32421
|
+
// sharing a line with the dimension attributes is the one shape to watch
|
|
32422
|
+
// for in review.
|
|
32423
|
+
//
|
|
32424
|
+
// gh#3985 (a second consequence of the same string-literal-blind gap
|
|
32425
|
+
// above): a plain JS string mentioning markup IN PROSE, not authoring it,
|
|
32426
|
+
// still satisfies `<img\b[^>]*?>`, PR #3977's own vitest-setup error
|
|
32427
|
+
// message ("...a <link>, <script> or " + "<img> src), turn that loading
|
|
32428
|
+
// off...") matched a bare, zero-attribute `<img>` and read as an
|
|
32429
|
+
// error-severity finding on a file that emits no DOM at all. Every REAL
|
|
32430
|
+
// `<img>` this rule was written to catch (gh#3604's select.class.js
|
|
32431
|
+
// sites, this corpus's only non-comment instances) sets at least one real
|
|
32432
|
+
// attribute (`src=` at minimum: an img with none renders nothing, so
|
|
32433
|
+
// hand-authored markup never omits it); a bare `<img>`/`<img >` with zero
|
|
32434
|
+
// `name=value` pairs is never genuine output markup in this corpus, only
|
|
32435
|
+
// prose describing one, so HAS_ANY_ATTR below gates the match the same
|
|
32436
|
+
// way HAS_WIDTH/HAS_HEIGHT already gate the dimension check. This is a
|
|
32437
|
+
// narrow, corpus-verified discriminator, not a full JS/HTML parse (an
|
|
32438
|
+
// attribute-bearing `<img width=100>` still mentioned in a doc comment or
|
|
32439
|
+
// prose sentence would still false-positive; none exists in this corpus
|
|
32440
|
+
// today, watch for it in review the same way the paragraph above already
|
|
32441
|
+
// asks).
|
|
32442
|
+
const IMG_TAG_RE = /<img\b[^>]*?>/gis;
|
|
32443
|
+
const HAS_WIDTH = /\bwidth\s*=/i;
|
|
32444
|
+
const HAS_HEIGHT = /\bheight\s*=/i;
|
|
32445
|
+
const HAS_ASPECT_RATIO = /aspect-ratio\s*:/i;
|
|
32446
|
+
const HAS_ANY_ATTR = /\S=/;
|
|
32447
|
+
const CORPUS_PATH_RE = /packages[\\/](web-components|web-modules)[\\/]/;
|
|
32448
|
+
|
|
32449
|
+
|
|
32450
|
+
RULES.push({
|
|
32451
|
+
id: 'IMG-DIMENSION-RESERVE',
|
|
32452
|
+
severity: 'error',
|
|
32453
|
+
scope: 'shared',
|
|
32454
|
+
fileTypes: CODE_EXT,
|
|
32455
|
+
match(text, path) {
|
|
32456
|
+
const out = [];
|
|
32457
|
+
const normalized = (path || '').replace(/\\/g, '/');
|
|
32458
|
+
if (!CORPUS_PATH_RE.test(normalized)) return out;
|
|
32459
|
+
if (normalized.endsWith('.test.js')) return out;
|
|
32460
|
+
|
|
32461
|
+
const rawLines = text.split('\n');
|
|
32462
|
+
const blanked = stripCommentLines(text, ext(path))
|
|
32463
|
+
.map((l) => l.stripped)
|
|
32464
|
+
.join('\n');
|
|
32465
|
+
|
|
32466
|
+
IMG_TAG_RE.lastIndex = 0;
|
|
32467
|
+
let m;
|
|
32468
|
+
while ((m = IMG_TAG_RE.exec(blanked))) {
|
|
32469
|
+
const tag = m[0];
|
|
32470
|
+
if (!HAS_ANY_ATTR.test(tag)) continue; // gh#3985: no attribute at all, prose mentioning <img>, not authored markup
|
|
32471
|
+
if ((HAS_WIDTH.test(tag) && HAS_HEIGHT.test(tag)) || HAS_ASPECT_RATIO.test(tag)) continue;
|
|
32472
|
+
const lineNo = lineOf(blanked, m.index);
|
|
32473
|
+
out.push({
|
|
32474
|
+
line: lineNo,
|
|
32475
|
+
snippet: (rawLines[lineNo - 1] || tag).trim().slice(0, 90),
|
|
32476
|
+
why: 'an <img> stamped by component render logic needs its own width/height (or an inline aspect-ratio) so the box is reserved before CSS applies (gh#3604 CLS)',
|
|
32477
|
+
});
|
|
32478
|
+
}
|
|
32479
|
+
return out;
|
|
32480
|
+
},
|
|
32481
|
+
});
|
|
32482
|
+
}
|
|
32483
|
+
|
|
32484
|
+
{
|
|
32485
|
+
|
|
32486
|
+
|
|
32487
|
+
const SHELLS = new Set(['admin-shell', 'chat-shell', 'editor-shell', 'app-shell-ui', 'adia-chat-ui', 'adia-editor-ui']);
|
|
32488
|
+
|
|
30583
32489
|
|
|
30584
32490
|
RULES.push({
|
|
30585
32491
|
id: 'LEGACY-SHELL',
|
|
@@ -30587,18 +32493,50 @@ RULES.push({
|
|
|
30587
32493
|
scope: 'shared',
|
|
30588
32494
|
fileTypes: [],
|
|
30589
32495
|
match(text, path) {
|
|
30590
|
-
|
|
30591
|
-
|
|
30592
|
-
|
|
30593
|
-
|
|
30594
|
-
|
|
30595
|
-
|
|
30596
|
-
|
|
30597
|
-
|
|
30598
|
-
|
|
32496
|
+
// Component yaml contains contract prose and A2UI JSON, not live HTML.
|
|
32497
|
+
// Match syntax in source rather than retirement examples or name prefixes.
|
|
32498
|
+
const fileExt = ext(path);
|
|
32499
|
+
if (YAML_EXT.includes(fileExt)) return [];
|
|
32500
|
+
const lines = stripCommentLines(text, fileExt);
|
|
32501
|
+
const source = markupScanSurface(lines.map(({ stripped }) => stripped).join('\n'));
|
|
32502
|
+
const found = new Set();
|
|
32503
|
+
for (const { attrs, tag, line } of tagOccurrences(source, path)) {
|
|
32504
|
+
if (Object.keys(attrs).some((name) => RE.LEGACY_SHELL.test(name)) ||
|
|
32505
|
+
(tag === 'dialog' && Object.hasOwn(attrs, 'data-command'))) found.add(line);
|
|
32506
|
+
}
|
|
32507
|
+
// aside-ui remains a supported in-page slot stub. Only its use as a
|
|
32508
|
+
// shell region is retired; native wrappers preserve that shell context.
|
|
32509
|
+
for (const { tag, parentTag, line } of tagTree(source, path)) {
|
|
32510
|
+
if (tag === 'aside-ui' && SHELLS.has(parentTag)) found.add(line);
|
|
32511
|
+
}
|
|
32512
|
+
const referenceSurfaces = [];
|
|
32513
|
+
if (CODE_EXT.includes(fileExt) || STYLE_EXT.includes(fileExt)) {
|
|
32514
|
+
referenceSurfaces.push({ text: source, line: 1 });
|
|
32515
|
+
} else {
|
|
32516
|
+
// Inline executable blocks need the same coverage as separate files.
|
|
32517
|
+
// Scan their bodies only, so selectors quoted in page prose stay clean.
|
|
32518
|
+
for (const block of source.matchAll(/<(script|style)\b[^>]*>([\s\S]*?)<\/\1\s*>/gi)) {
|
|
32519
|
+
const start = block.index + block[0].indexOf('>') + 1;
|
|
32520
|
+
const body = stripCommentLines(block[2], block[1].toLowerCase() === 'script' ? '.js' : '.css')
|
|
32521
|
+
.map(({ stripped }) => stripped).join('\n');
|
|
32522
|
+
referenceSurfaces.push({ text: body, line: lineOf(source, start) });
|
|
30599
32523
|
}
|
|
30600
32524
|
}
|
|
30601
|
-
|
|
32525
|
+
// Keep selector reads and DOM attribute writes covered as well as
|
|
32526
|
+
// markup. Exact attribute names preserve unrelated namespaced hooks.
|
|
32527
|
+
const references = /\[\s*([\w-]+)(?=[\s\]=~|^$*])|\b(?:setAttribute|getAttribute|hasAttribute|removeAttribute|toggleAttribute)\s*\(\s*['"]([\w-]+)['"]/g;
|
|
32528
|
+
for (const surface of referenceSurfaces) {
|
|
32529
|
+
for (const match of surface.text.matchAll(references)) {
|
|
32530
|
+
if (RE.LEGACY_SHELL.test(match[1] || match[2])) {
|
|
32531
|
+
found.add(surface.line + lineOf(surface.text, match.index) - 1);
|
|
32532
|
+
}
|
|
32533
|
+
}
|
|
32534
|
+
}
|
|
32535
|
+
return [...found].sort((a, b) => a - b).map((line) => ({
|
|
32536
|
+
line,
|
|
32537
|
+
snippet: lines[line - 1].raw.trim().slice(0, 90),
|
|
32538
|
+
why: 'retired shell shape (ADR-0024, v0.4.0): use the bespoke tag (chat-thread / chat-composer / chat-empty · admin-sidebar / admin-command · editor-canvas · pane-ui)',
|
|
32539
|
+
}));
|
|
30602
32540
|
},
|
|
30603
32541
|
});
|
|
30604
32542
|
}
|
|
@@ -30682,6 +32620,66 @@ RULES.push({
|
|
|
30682
32620
|
{
|
|
30683
32621
|
|
|
30684
32622
|
|
|
32623
|
+
// gh#3641: escapeHTML was independently defined seven times across the
|
|
32624
|
+
// framework corpus (six components plus chat-shell, one of the seven
|
|
32625
|
+
// spelled `escapeHtml`, case varies, tour.class.js, three of the seven
|
|
32626
|
+
// leaving quotes unescaped (an attribute-breakout XSS vector). The
|
|
32627
|
+
// shared, quote-safe implementation now lives at
|
|
32628
|
+
// packages/web-components/core/html-escape.js; this rule refuses a new
|
|
32629
|
+
// local `function escapeHtml(`/`escapeHTML(` (any casing) inside the
|
|
32630
|
+
// framework corpus (packages/web-components, packages/web-modules) so
|
|
32631
|
+
// the fix cannot re-fragment the way it already did once (twice: the
|
|
32632
|
+
// original 5-variant fragmentation, then a 7th instance under a
|
|
32633
|
+
// different casing that a case-sensitive first version of this very
|
|
32634
|
+
// rule could not see). Case-insensitive on purpose: the defect class is
|
|
32635
|
+
// "a local escapeHTML-shaped helper", not one exact spelling.
|
|
32636
|
+
// gh#3678: five more local copies turned up in apps/ (construct-canvas,
|
|
32637
|
+
// genui), two of them quote-unsafe, the same attribute-breakout defect
|
|
32638
|
+
// class this rule was written for. This scope note previously said
|
|
32639
|
+
// consumer app code was exempt because it "owns its own copy of a value
|
|
32640
|
+
// this small", that call was reversed by conductor ruling (gh#3678
|
|
32641
|
+
// resolution 2: migrate, not wontfix), so CORPUS_PATH_RE now also
|
|
32642
|
+
// matches apps/. playgrounds/ and catalog/ remain out of scope until a
|
|
32643
|
+
// ticket similarly finds and migrates a local copy there.
|
|
32644
|
+
// `declare function` is a .d.ts ambient signature, not a re-implementation:
|
|
32645
|
+
// html-escape.d.ts's own `export declare function escapeHTML(...)` must
|
|
32646
|
+
// not flag itself. Only a real function body is the defect this rule
|
|
32647
|
+
// exists for. The lookbehind requires `\s+` (one or more), not `\s`
|
|
32648
|
+
// (exactly one), so `declare function` (extra space) or a line break
|
|
32649
|
+
// between the two keywords still exempts the ambient signature.
|
|
32650
|
+
const LOCAL_DEF_RE = /(?<!declare\s+)\bfunction\s+escapeHtml\s*\(/i;
|
|
32651
|
+
const OWNER_PATH_RE = /packages[\\/]web-components[\\/]core[\\/]html-escape\.(js|d\.ts)$/;
|
|
32652
|
+
const CORPUS_PATH_RE = /(?:packages[\\/](web-components|web-modules)|(?:^|[\\/])apps)[\\/]/;
|
|
32653
|
+
|
|
32654
|
+
|
|
32655
|
+
RULES.push({
|
|
32656
|
+
id: 'NO-LOCAL-ESCAPE-HTML',
|
|
32657
|
+
severity: 'error',
|
|
32658
|
+
scope: 'shared',
|
|
32659
|
+
fileTypes: CODE_EXT,
|
|
32660
|
+
match(text, path) {
|
|
32661
|
+
const out = [];
|
|
32662
|
+
const normalized = path.replace(/\\/g, '/');
|
|
32663
|
+
if (!CORPUS_PATH_RE.test(normalized)) return out;
|
|
32664
|
+
if (OWNER_PATH_RE.test(normalized)) return out;
|
|
32665
|
+
for (const { lineNo, raw, stripped } of stripCommentLines(text, ext(path))) {
|
|
32666
|
+
if (!stripped.trim()) continue;
|
|
32667
|
+
if (LOCAL_DEF_RE.test(stripped)) {
|
|
32668
|
+
out.push({
|
|
32669
|
+
line: lineNo,
|
|
32670
|
+
snippet: raw.trim().slice(0, 90),
|
|
32671
|
+
why: 'do not redefine escapeHTML locally, import { escapeHTML } from the core barrel (packages/web-components/core/html-escape.js), gh#3641',
|
|
32672
|
+
});
|
|
32673
|
+
}
|
|
32674
|
+
}
|
|
32675
|
+
return out;
|
|
32676
|
+
},
|
|
32677
|
+
});
|
|
32678
|
+
}
|
|
32679
|
+
|
|
32680
|
+
{
|
|
32681
|
+
|
|
32682
|
+
|
|
30685
32683
|
// Parity with the two retired scripts: forge-lint recognized only
|
|
30686
32684
|
// `forge-lint: foundation`, adia-lint only `adia-lint: foundation` — never
|
|
30687
32685
|
// either tag under the other script. Since this rule is shared, the active
|
|
@@ -30694,6 +32692,39 @@ function optInTagsFor(scopes) {
|
|
|
30694
32692
|
return ['forge-lint', 'adia-lint'];
|
|
30695
32693
|
}
|
|
30696
32694
|
|
|
32695
|
+
// gh#3839: a `var(--token, <literal>)` fallback is still a shipped literal
|
|
32696
|
+
// whenever the named token is undefined: RAW-COLOR must see inside it.
|
|
32697
|
+
// `light-dark(<light>, <dark>)` is the one legitimate literal-pair form (both
|
|
32698
|
+
// arms are meant to be literal color values by design), so its call is
|
|
32699
|
+
// stripped out, balanced on parens, so a color function nested in either
|
|
32700
|
+
// arm (e.g. `light-dark(oklch(...), oklch(...))`) is stripped too, before
|
|
32701
|
+
// the rest of the declaration (var() fallbacks included) is scanned as
|
|
32702
|
+
// plain text. Custom-property names never match HEXCOLOR/FUNCCOLOR, so
|
|
32703
|
+
// leaving `var(` unstripped carries no risk of matching the reference
|
|
32704
|
+
// itself, only a literal actually sitting in its fallback.
|
|
32705
|
+
function stripBalancedCalls(text, fnName) {
|
|
32706
|
+
const token = `${fnName}(`;
|
|
32707
|
+
let result = '';
|
|
32708
|
+
let i = 0;
|
|
32709
|
+
while (i < text.length) {
|
|
32710
|
+
const idx = text.indexOf(token, i);
|
|
32711
|
+
if (idx === -1) {
|
|
32712
|
+
result += text.slice(i);
|
|
32713
|
+
break;
|
|
32714
|
+
}
|
|
32715
|
+
result += text.slice(i, idx);
|
|
32716
|
+
let depth = 1;
|
|
32717
|
+
let j = idx + token.length;
|
|
32718
|
+
while (j < text.length && depth > 0) {
|
|
32719
|
+
if (text[j] === '(') depth += 1;
|
|
32720
|
+
else if (text[j] === ')') depth -= 1;
|
|
32721
|
+
j += 1;
|
|
32722
|
+
}
|
|
32723
|
+
i = j;
|
|
32724
|
+
}
|
|
32725
|
+
return result;
|
|
32726
|
+
}
|
|
32727
|
+
|
|
30697
32728
|
|
|
30698
32729
|
RULES.push({
|
|
30699
32730
|
id: 'RAW-COLOR',
|
|
@@ -30709,8 +32740,8 @@ RULES.push({
|
|
|
30709
32740
|
for (const decl of stripped.split(';')) {
|
|
30710
32741
|
const d = decl.trim();
|
|
30711
32742
|
if (!d || d.startsWith('//') || d.startsWith('/*') || d.startsWith('*')) continue;
|
|
30712
|
-
|
|
30713
|
-
if (RE.HEXCOLOR.test(
|
|
32743
|
+
const scanText = decl.includes('light-dark(') ? stripBalancedCalls(decl, 'light-dark') : decl;
|
|
32744
|
+
if (RE.HEXCOLOR.test(scanText) || RE.FUNCCOLOR.test(scanText)) {
|
|
30714
32745
|
out.push({
|
|
30715
32746
|
line: lineNo,
|
|
30716
32747
|
snippet: raw.trim().slice(0, 90),
|
|
@@ -30775,20 +32806,48 @@ RULES.push({
|
|
|
30775
32806
|
|
|
30776
32807
|
|
|
30777
32808
|
|
|
32809
|
+
/**
|
|
32810
|
+
* SCOPE-EXTENT (gh#3718): error severity, with the pre-existing corpus of
|
|
32811
|
+
* findings downgraded to warn via a checked-in baseline rather than by a
|
|
32812
|
+
* blanket severity.json entry.
|
|
32813
|
+
*
|
|
32814
|
+
* The blanket downgrade is what this replaces. It made every site invisible,
|
|
32815
|
+
* including sites added after the downgrade, so the rule could not do the one
|
|
32816
|
+
* job it was written for. The baseline inverts that: known sites stay warn,
|
|
32817
|
+
* anything not in the baseline errors.
|
|
32818
|
+
*
|
|
32819
|
+
* Sites are keyed on the normalized text of the matched block, per file, as a
|
|
32820
|
+
* MULTISET, not on line numbers. A line-keyed baseline goes stale whenever an
|
|
32821
|
+
* unrelated edit shifts a selector down, which reports a pre-existing finding
|
|
32822
|
+
* as new for a reason that has nothing to do with this rule. The multiset also
|
|
32823
|
+
* keeps duplicates, so a second identical violation in an already-baselined
|
|
32824
|
+
* file exceeds its entry and errors, which a per-file count would miss.
|
|
32825
|
+
*/
|
|
32826
|
+
|
|
30778
32827
|
RULES.push({
|
|
30779
32828
|
id: 'SCOPE-EXTENT',
|
|
30780
32829
|
severity: 'error',
|
|
30781
32830
|
scope: 'shared',
|
|
30782
32831
|
fileTypes: STYLE_EXT,
|
|
30783
|
-
match(text) {
|
|
32832
|
+
match(text, path) {
|
|
30784
32833
|
const out = [];
|
|
30785
32834
|
const re = new RegExp(RE.SCOPE_EXTENT.source, 'gs');
|
|
32835
|
+
// A local copy, consumed as we go: each baselined entry excuses exactly
|
|
32836
|
+
// one finding, so the second identical violation in the same file finds
|
|
32837
|
+
// the entry already spent and reports at full severity.
|
|
32838
|
+
const remaining = [...baselineFor(path)];
|
|
30786
32839
|
let m;
|
|
30787
32840
|
while ((m = re.exec(text))) {
|
|
32841
|
+
const key = normalizeMatch(m[0]);
|
|
32842
|
+
const at = remaining.indexOf(key);
|
|
32843
|
+
const baselined = at !== -1;
|
|
32844
|
+
if (baselined) remaining.splice(at, 1);
|
|
30788
32845
|
out.push({
|
|
30789
32846
|
line: lineOf(text, m.index),
|
|
30790
32847
|
snippet: ':scope { … width/height … }',
|
|
30791
32848
|
why: "a primitive is size-agnostic — let the consumer own width/height; don't set extent on :scope",
|
|
32849
|
+
// Per-finding override; absent means the rule's own severity applies.
|
|
32850
|
+
...(baselined ? { severity: 'warn' } : {}),
|
|
30792
32851
|
});
|
|
30793
32852
|
}
|
|
30794
32853
|
return out;
|