@invarn/cibuild 2.5.0 → 2.5.2

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.
@@ -51,6 +51,17 @@ export interface LayoutNode {
51
51
  fillAlpha?: number;
52
52
  /** Text alpha 0..1 (issue 14b), same convention as `fillAlpha`. */
53
53
  textAlpha?: number;
54
+ /** Border (ring) colour, hex — the design's `stroke` (property-recognizer 01),
55
+ * read from the layout node's `Modifier.border(...)` element. Absent when the
56
+ * node has no border OR has one this read cannot measure (a gradient brush),
57
+ * so absence alone is not "no border" — that is what `styleChannels` on the
58
+ * dump is for. */
59
+ borderColor?: string;
60
+ /** Border thickness in DP (the harness reads `Dp.value`), so unlike `bounds`
61
+ * it is NOT divided by density. Emitted together with `borderColor` or not at
62
+ * all: half a measurement compared against a whole design value is how a
63
+ * wrong number ships. */
64
+ borderWidth?: number;
54
65
  /** AnnotatedString background-span extents (issue 16): each range of the
55
66
  * node's text drawn with a specified span background — the highlighted
56
67
  * substrings. Offsets index into `text`. Absent in dumps from packages
@@ -142,6 +153,14 @@ export interface LayoutDump {
142
153
  * "no color span rendered", so the span compare only derives color-span
143
154
  * facts when the marker includes "color". */
144
155
  spanChannels?: string[];
156
+ /** The STYLE channels this dump's emitter can report ("border").
157
+ * Absent in dumps emitted before border capture existed, and load-bearing in
158
+ * that case: their silence means "cannot see a border", NOT "the render has no
159
+ * border". The border compare therefore withholds the ABSENCE case entirely
160
+ * without this marker and the caller advises "not checked" — reading it the
161
+ * other way would put a finding on every stroked design in the catalogue
162
+ * (property-recognizer 01). */
163
+ styleChannels?: string[];
145
164
  }
146
165
  export type Edge = 'left' | 'top' | 'right' | 'bottom';
147
166
  export type StructuralFact = {
@@ -329,7 +348,7 @@ export interface StructuralOverhang {
329
348
  }
330
349
  export interface StructuralGeometryElement {
331
350
  id: string;
332
- rendered: {
351
+ rendered?: {
333
352
  w: number;
334
353
  h: number;
335
354
  x: number;
@@ -412,6 +431,33 @@ export type AppearanceFact = {
412
431
  channel: 'fill' | 'text';
413
432
  rendered: number;
414
433
  reference: number;
434
+ }
435
+ /** The design declares a STROKE the render drew no border for at all
436
+ * (property-recognizer 01). The motivating case: an 18dp badge with a 4dp
437
+ * white ring inside it, rendered as a plain green blob, about which the gate
438
+ * said nothing because no harness captured a border. Emitted ONLY from a dump
439
+ * that declares border capability (`styleChannels`) — an older emitter's
440
+ * silence is "cannot see a border", never "no border was drawn". */
441
+ | {
442
+ kind: 'border_missing';
443
+ elementId: string;
444
+ reference: string;
445
+ referenceWidth?: number;
446
+ }
447
+ /** A drawn border whose COLOUR differs from the design's stroke. */
448
+ | {
449
+ kind: 'border';
450
+ elementId: string;
451
+ rendered: string;
452
+ reference: string;
453
+ }
454
+ /** A drawn border of the right colour and the wrong THICKNESS, in dp. Its own
455
+ * kind so a correctly-coloured ring is never reported as a colour problem. */
456
+ | {
457
+ kind: 'border_width';
458
+ elementId: string;
459
+ rendered: number;
460
+ reference: number;
415
461
  } | {
416
462
  kind: 'text_mismatch';
417
463
  elementId: string;
@@ -696,6 +742,15 @@ export interface ElementColors {
696
742
  /** Per-channel alpha 0..1 (issue 14b), present only when translucent. */
697
743
  fillAlpha?: number;
698
744
  textAlpha?: number;
745
+ /** The BORDER colour (property-recognizer 01) — the design calls this a
746
+ * `stroke`, and both sides use that name so they line up. On the reference
747
+ * side it comes from `colors[key].stroke`; on the rendered side from the
748
+ * dump's `borderColor`. */
749
+ stroke?: string;
750
+ /** Border thickness in DP on both sides — the harness reads `Dp.value` and the
751
+ * design's `strokeWeight` is in design units, so unlike bounds this is never
752
+ * divided by density. */
753
+ strokeWeight?: number;
699
754
  }
700
755
  export type ColorSource = Record<string, ElementColors>;
701
756
  /**
@@ -710,6 +765,33 @@ export declare function hexToLab(hex: string): Lab;
710
765
  * test data. Pure and symmetric; identical colours give 0.
711
766
  */
712
767
  export declare function ciede2000(lab1: Lab, lab2: Lab): number;
768
+ /**
769
+ * Border facts (property-recognizer 01) — the design's `stroke` against the
770
+ * render's captured border. THE case this exists for: an 18dp badge with a 4dp
771
+ * white ring inside it rendered as a plain green blob, about which the gate said
772
+ * nothing at all, because the design's stroke lived in an authoring hint and the
773
+ * dump captured no border. Nothing compared, so an unmeasured property read as a
774
+ * pass.
775
+ *
776
+ * The DESIGN is the only side that raises the question, exactly as with alpha: an
777
+ * entry with no declared `stroke` is skipped, so a wrapper adding a ring the
778
+ * design never asked for is not something this calls wrong.
779
+ *
780
+ * Three kinds, because they are three different fixes — absent / wrong colour /
781
+ * wrong thickness. Folding width into `border` would report "the ring is the
782
+ * wrong colour" about a ring whose colour is exactly right.
783
+ *
784
+ * `capable` gates the ABSENCE case only, and both directions of that gate are
785
+ * wrong in a way worth naming: without it, a border-blind dump would fire
786
+ * `border_missing` on every stroked design in the catalogue; with it applied too
787
+ * broadly, a real divergence on a capable dump would go unreported. A colour or
788
+ * width difference is a genuine measurement either way — only "I saw no border"
789
+ * depends on being able to see borders at all.
790
+ *
791
+ * Pure and platform-agnostic; deterministic (sorted by element id). Mirrors the
792
+ * CLI preview twin in `packages/cli/lib/fidelity-structural.mjs`.
793
+ */
794
+ export declare function deriveBorderFacts(rendered: ColorSource, reference: ColorSource, capable: boolean): AppearanceFact[];
713
795
  /**
714
796
  * Color facts from the per-element, per-channel comparison of rendered vs
715
797
  * reference color, keyed on the stable element id shared with Signal B. For each
@@ -1 +1 @@
1
- {"version":3,"file":"structural-facts.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/structural-facts.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"structural-facts.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/structural-facts.ts"],"names":[],"mappings":"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"}
@@ -661,6 +661,71 @@ function hueDeg(b, a) {
661
661
  const deg = rad2deg(Math.atan2(b, a));
662
662
  return deg >= 0 ? deg : deg + 360;
663
663
  }
664
+ /**
665
+ * Border facts (property-recognizer 01) — the design's `stroke` against the
666
+ * render's captured border. THE case this exists for: an 18dp badge with a 4dp
667
+ * white ring inside it rendered as a plain green blob, about which the gate said
668
+ * nothing at all, because the design's stroke lived in an authoring hint and the
669
+ * dump captured no border. Nothing compared, so an unmeasured property read as a
670
+ * pass.
671
+ *
672
+ * The DESIGN is the only side that raises the question, exactly as with alpha: an
673
+ * entry with no declared `stroke` is skipped, so a wrapper adding a ring the
674
+ * design never asked for is not something this calls wrong.
675
+ *
676
+ * Three kinds, because they are three different fixes — absent / wrong colour /
677
+ * wrong thickness. Folding width into `border` would report "the ring is the
678
+ * wrong colour" about a ring whose colour is exactly right.
679
+ *
680
+ * `capable` gates the ABSENCE case only, and both directions of that gate are
681
+ * wrong in a way worth naming: without it, a border-blind dump would fire
682
+ * `border_missing` on every stroked design in the catalogue; with it applied too
683
+ * broadly, a real divergence on a capable dump would go unreported. A colour or
684
+ * width difference is a genuine measurement either way — only "I saw no border"
685
+ * depends on being able to see borders at all.
686
+ *
687
+ * Pure and platform-agnostic; deterministic (sorted by element id). Mirrors the
688
+ * CLI preview twin in `packages/cli/lib/fidelity-structural.mjs`.
689
+ */
690
+ export function deriveBorderFacts(rendered, reference, capable) {
691
+ const facts = [];
692
+ for (const elementId of Object.keys(reference).sort()) {
693
+ const ref = reference[elementId];
694
+ if (!ref || !hasText(ref.stroke))
695
+ continue;
696
+ const ren = rendered[elementId];
697
+ const renderedStroke = ren ? ren.stroke : undefined;
698
+ if (!hasText(renderedStroke)) {
699
+ if (capable) {
700
+ const width = ref.strokeWeight;
701
+ facts.push({
702
+ kind: 'border_missing',
703
+ elementId,
704
+ reference: ref.stroke,
705
+ ...(typeof width === 'number' ? { referenceWidth: width } : {}),
706
+ });
707
+ }
708
+ continue;
709
+ }
710
+ if (renderedStroke.toLowerCase() !== ref.stroke.toLowerCase()) {
711
+ facts.push({
712
+ kind: 'border',
713
+ elementId,
714
+ rendered: renderedStroke,
715
+ reference: ref.stroke,
716
+ });
717
+ }
718
+ // Width only when the DESIGN states one — an undeclared weight says nothing
719
+ // about thickness, the same asymmetry alpha uses. 0.5dp is the floor below
720
+ // which two rings are the same ring.
721
+ const refW = ref.strokeWeight;
722
+ const renW = ren ? ren.strokeWeight : undefined;
723
+ if (typeof refW === 'number' && typeof renW === 'number' && Math.abs(refW - renW) > 0.5) {
724
+ facts.push({ kind: 'border_width', elementId, rendered: renW, reference: refW });
725
+ }
726
+ }
727
+ return facts;
728
+ }
664
729
  /**
665
730
  * Color facts from the per-element, per-channel comparison of rendered vs
666
731
  * reference color, keyed on the stable element id shared with Signal B. For each
@@ -1142,8 +1207,24 @@ export function buildStructuralBlock(dump, referenceGeometry, density, options =
1142
1207
  continue;
1143
1208
  const g = generated[id];
1144
1209
  const r = ref[id];
1145
- if (!g || !r)
1210
+ if (!r)
1211
+ continue;
1212
+ if (!g) {
1213
+ // Declared but absent from the render. Persist the design box alone —
1214
+ // the same field, built the same way as the compared path below — so
1215
+ // the absence keeps the design's record of WHERE instead of taking it
1216
+ // down with the element.
1217
+ const design = {
1218
+ w: Number.isNaN(r.width) ? undefined : r.width,
1219
+ h: Number.isNaN(r.height) ? undefined : r.height,
1220
+ };
1221
+ if (typeof r.x === 'number')
1222
+ design.x = r.x;
1223
+ if (typeof r.y === 'number')
1224
+ design.y = r.y;
1225
+ elements.push({ id, design });
1146
1226
  continue;
1227
+ }
1147
1228
  const rawDeltas = deltasByElement.get(id) ?? [];
1148
1229
  const deltas = [];
1149
1230
  // Text-aware significance band (line-box residue): the deltas below stay
@@ -1331,8 +1412,15 @@ export function buildStructuralBlock(dump, referenceGeometry, density, options =
1331
1412
  colors.fillAlpha = node.fillAlpha;
1332
1413
  if (typeof node.textAlpha === 'number')
1333
1414
  colors.textAlpha = node.textAlpha;
1334
- if (colors.fill !== undefined || colors.text !== undefined)
1415
+ // The rendered border (property-recognizer 01), keyed as `stroke` so the
1416
+ // design and render sides line up. `borderWidth` is already DP.
1417
+ if (typeof node.borderColor === 'string')
1418
+ colors.stroke = node.borderColor;
1419
+ if (typeof node.borderWidth === 'number')
1420
+ colors.strokeWeight = node.borderWidth;
1421
+ if (colors.fill !== undefined || colors.text !== undefined || colors.stroke !== undefined) {
1335
1422
  renderedColor[node.id] = colors;
1423
+ }
1336
1424
  // The resolved-typeface enrichment (issue 03): the font that actually painted.
1337
1425
  const tf = node.resolvedTypeface;
1338
1426
  if (tf && typeof tf.family === 'string' && tf.family.length > 0) {
@@ -1390,6 +1478,26 @@ export function buildStructuralBlock(dump, referenceGeometry, density, options =
1390
1478
  appearanceFacts.push(...deriveTypefaceFacts(renderedTypeface, appearanceReference.typeface));
1391
1479
  }
1392
1480
  }
1481
+ // Border facts (property-recognizer 01). `styleChannels` is the emitter's own
1482
+ // declaration that it can see borders; a package predating border capture
1483
+ // lacks it, and that silence is "cannot see a border", never "no border was
1484
+ // drawn". The advisory NAMES the elements — an unnamed "not checked" is a
1485
+ // statement nobody can act on, which is the same silence in a new place.
1486
+ if (appearanceReference.color) {
1487
+ const borderCapable = Array.isArray(dump.styleChannels) && dump.styleChannels.includes('border');
1488
+ appearanceFacts.push(...deriveBorderFacts(renderedColor, appearanceReference.color, borderCapable));
1489
+ if (!borderCapable) {
1490
+ const declared = Object.keys(appearanceReference.color)
1491
+ .filter((key) => hasText(appearanceReference.color?.[key]?.stroke))
1492
+ .sort();
1493
+ if (declared.length > 0) {
1494
+ advisories.push('border check requires a render package that captures one; this proof declared no ' +
1495
+ 'style channels (an older package) — the design stroke on ' +
1496
+ declared.join(', ') +
1497
+ ' was not checked, not passing');
1498
+ }
1499
+ }
1500
+ }
1393
1501
  const rendered = { elementIds: [...renderedIds].sort() };
1394
1502
  if (Object.keys(renderedText).length > 0)
1395
1503
  rendered.text = renderedText;
@@ -1447,15 +1555,17 @@ function clipDeltaText(overhang, element) {
1447
1555
  const causes = [];
1448
1556
  if (overhang.sizeDriven) {
1449
1557
  // Report only the dimensions whose size actually differs from design.
1450
- // (An overhang exists only on a reference-compared element, so design is
1451
- // present here at runtime; the optional chaining is for the type.)
1558
+ // (An overhang exists only on a reference-compared element, so design AND
1559
+ // rendered are present here at runtime; the null checks are for the type.)
1452
1560
  const sizeParts = [];
1453
1561
  const designW = element.design?.w;
1454
1562
  const designH = element.design?.h;
1455
- if (designW != null && element.rendered.w !== designW)
1456
- sizeParts.push(`w ${element.rendered.w} vs ${designW}dp`);
1457
- if (designH != null && element.rendered.h !== designH)
1458
- sizeParts.push(`h ${element.rendered.h} vs ${designH}dp`);
1563
+ const renderedW = element.rendered?.w;
1564
+ const renderedH = element.rendered?.h;
1565
+ if (designW != null && renderedW != null && renderedW !== designW)
1566
+ sizeParts.push(`w ${renderedW} vs ${designW}dp`);
1567
+ if (designH != null && renderedH != null && renderedH !== designH)
1568
+ sizeParts.push(`h ${renderedH} vs ${designH}dp`);
1459
1569
  const sizeText = sizeParts.join(', ');
1460
1570
  const frameSuffix = overhang.frameRelative ? ' tracking the frame (parent-relative)' : '';
1461
1571
  causes.push(sizeText ? `the element's own size (${sizeText})${frameSuffix}` : `the element's own size${frameSuffix}`);
@@ -1509,11 +1619,12 @@ export function buildReviewScaffold(structural) {
1509
1619
  for (const el of geometry ? geometry.elements : []) {
1510
1620
  let flagged = false;
1511
1621
  if (el.sizeFlag) {
1512
- // A size flag exists only on a reference-compared element, so design is
1513
- // present here at runtime; the optional chaining is for the type.
1622
+ // A size flag exists only on a reference-compared element, so design and
1623
+ // rendered are present here at runtime; the optional chaining is for the
1624
+ // type.
1514
1625
  rows.push({
1515
1626
  element: el.id,
1516
- rendered: `${el.rendered.w}×${el.rendered.h}dp`,
1627
+ rendered: `${el.rendered?.w}×${el.rendered?.h}dp`,
1517
1628
  design: `${el.design?.w}×${el.design?.h}dp`,
1518
1629
  fact: sizeDeltaText(el),
1519
1630
  verdict: null,
@@ -2218,6 +2329,44 @@ function deriveColorFacts(rendered, reference) {
2218
2329
  return facts;
2219
2330
  }
2220
2331
 
2332
+ // Border facts (property-recognizer 01) — the runner twin of deriveBorderFacts.
2333
+ // The design's stroke against the render's captured border; the DESIGN is the
2334
+ // only side that raises the question, and "capable" gates the ABSENCE case only,
2335
+ // because a border-blind dump cannot tell "no ring drawn" from "I cannot see
2336
+ // rings". Patching only the typed copy would make the local preview and the real
2337
+ // gate disagree, silently.
2338
+ function deriveBorderFacts(rendered, reference, capable) {
2339
+ var facts = [];
2340
+ var ids = Object.keys(reference).sort();
2341
+ for (var i = 0; i < ids.length; i++) {
2342
+ var elementId = ids[i];
2343
+ var ref = reference[elementId];
2344
+ if (!ref || !copyHasText(ref.stroke)) continue;
2345
+ var ren = rendered[elementId];
2346
+ var renderedStroke = ren ? ren.stroke : undefined;
2347
+ if (!copyHasText(renderedStroke)) {
2348
+ if (capable) {
2349
+ var missing = { kind: 'border_missing', elementId: elementId, reference: ref.stroke };
2350
+ if (typeof ref.strokeWeight === 'number') missing.referenceWidth = ref.strokeWeight;
2351
+ facts.push(missing);
2352
+ }
2353
+ continue;
2354
+ }
2355
+ if (renderedStroke.toLowerCase() !== ref.stroke.toLowerCase()) {
2356
+ facts.push({
2357
+ kind: 'border', elementId: elementId,
2358
+ rendered: renderedStroke, reference: ref.stroke,
2359
+ });
2360
+ }
2361
+ var refW = ref.strokeWeight;
2362
+ var renW = ren ? ren.strokeWeight : undefined;
2363
+ if (typeof refW === 'number' && typeof renW === 'number' && Math.abs(refW - renW) > 0.5) {
2364
+ facts.push({ kind: 'border_width', elementId: elementId, rendered: renW, reference: refW });
2365
+ }
2366
+ }
2367
+ return facts;
2368
+ }
2369
+
2221
2370
  // Signal C: typeface facts (issue 03) — the RESOLVED (painted, post-fallback)
2222
2371
  // font vs the reference font. Mirrors the typed normalizeTypeface /
2223
2372
  // deriveTypefaceFacts: a weight-name suffix on the family is stripped and, when
@@ -2447,7 +2596,17 @@ function buildStructuralBlock(dump, referenceGeometry, density, options, appeara
2447
2596
  if (dupCounts[id] > 1) continue;
2448
2597
  var g = generated[id];
2449
2598
  var r = ref[id];
2450
- if (!g || !r) continue;
2599
+ if (!r) continue;
2600
+ if (!g) {
2601
+ // Declared but absent from the render: persist the design box alone,
2602
+ // so the absence keeps the design's record of WHERE instead of taking
2603
+ // it down with the element.
2604
+ var absentDesign = { w: isNaN(r.width) ? undefined : r.width, h: isNaN(r.height) ? undefined : r.height };
2605
+ if (typeof r.x === 'number') absentDesign.x = r.x;
2606
+ if (typeof r.y === 'number') absentDesign.y = r.y;
2607
+ elements.push({ id: id, design: absentDesign });
2608
+ continue;
2609
+ }
2451
2610
  var rawDeltas = deltasByElement[id] || [];
2452
2611
  var deltas = [];
2453
2612
  // Text-aware significance band (line-box residue): deltas stay exact;
@@ -2530,7 +2689,7 @@ function buildStructuralBlock(dump, referenceGeometry, density, options, appeara
2530
2689
  maxSizeDeltaDp = 0;
2531
2690
  maxClipDeltaDp = 0;
2532
2691
  for (var e = 0; e < geometry.elements.length; e++) {
2533
- var els = geometry.elements[e].deltas;
2692
+ var els = geometry.elements[e].deltas || [];
2534
2693
  for (var di = 0; di < els.length; di++) {
2535
2694
  if (els[di].dimension !== 'w' && els[di].dimension !== 'h') continue;
2536
2695
  var abs = Math.abs(els[di].delta);
@@ -2633,6 +2792,12 @@ function buildStructuralBlock(dump, referenceGeometry, density, options, appeara
2633
2792
  if (typeof rnode.textColor === 'string') { colors.text = rnode.textColor; hasColor = true; }
2634
2793
  if (typeof rnode.fillAlpha === 'number') { colors.fillAlpha = rnode.fillAlpha; }
2635
2794
  if (typeof rnode.textAlpha === 'number') { colors.textAlpha = rnode.textAlpha; }
2795
+ // The rendered border (property-recognizer 01), keyed as "stroke" to match
2796
+ // the design side. borderWidth is already DP — never divided by density.
2797
+ // hasColor flips here too: a ring is the element's only paint on a
2798
+ // stroke-only rule, and dropping the entry would lose the comparison.
2799
+ if (typeof rnode.borderColor === 'string') { colors.stroke = rnode.borderColor; hasColor = true; }
2800
+ if (typeof rnode.borderWidth === 'number') { colors.strokeWeight = rnode.borderWidth; }
2636
2801
  if (hasColor) renderedColor[rnode.id] = colors;
2637
2802
  // The resolved-typeface enrichment (issue 03): the font that actually painted.
2638
2803
  var rtf = rnode.resolvedTypeface;
@@ -2690,6 +2855,30 @@ function buildStructuralBlock(dump, referenceGeometry, density, options, appeara
2690
2855
  for (var tff = 0; tff < typefaceFacts.length; tff++) appearanceFacts.push(typefaceFacts[tff]);
2691
2856
  }
2692
2857
  }
2858
+ // Border facts (property-recognizer 01). styleChannels is the emitter's own
2859
+ // declaration that it can see borders; a package predating border capture
2860
+ // lacks it, and that silence is "cannot see a border", never "no border was
2861
+ // drawn". The advisory NAMES the elements — an unnamed "not checked" is a
2862
+ // statement nobody can act on.
2863
+ if (appearanceReference.color) {
2864
+ var borderCapable = Array.isArray(dump.styleChannels) &&
2865
+ dump.styleChannels.indexOf('border') !== -1;
2866
+ var borderFacts = deriveBorderFacts(renderedColor, appearanceReference.color, borderCapable);
2867
+ for (var bf = 0; bf < borderFacts.length; bf++) appearanceFacts.push(borderFacts[bf]);
2868
+ if (!borderCapable) {
2869
+ var strokeKeys = Object.keys(appearanceReference.color).filter(function (k) {
2870
+ return copyHasText(appearanceReference.color[k] && appearanceReference.color[k].stroke);
2871
+ }).sort();
2872
+ if (strokeKeys.length > 0) {
2873
+ appearanceAdvisories.push(
2874
+ 'border check requires a render package that captures one; this proof declared no ' +
2875
+ 'style channels (an older package) — the design stroke on ' +
2876
+ strokeKeys.join(', ') +
2877
+ ' was not checked, not passing'
2878
+ );
2879
+ }
2880
+ }
2881
+ }
2693
2882
  var sortedIds = renderedIds.slice().sort();
2694
2883
  var rendered = { elementIds: sortedIds };
2695
2884
  if (Object.keys(renderedText).length > 0) rendered.text = renderedText;
@@ -8,7 +8,7 @@
8
8
  * overflowing voucher tag; the deriver must surface the bottom clip as a
9
9
  * fact so it is never again skipped by eye.
10
10
  */
11
- import { deriveStructuralFacts, derivePresenceFacts, deriveCopyFacts, deriveSpanFacts, deriveLineFacts, deriveColorFacts, deriveTypefaceFacts, ciede2000, hexToLab, diffKeyGeometry, buildStructuralBlock, buildReviewScaffold, appearanceReferenceFromPreviousRender, buildAppearanceReferenceFromParams, getStructuralFactsStageInternals, getGeometryStageInternals, } from './structural-facts.js';
11
+ import { deriveStructuralFacts, derivePresenceFacts, deriveCopyFacts, deriveSpanFacts, deriveLineFacts, deriveColorFacts, deriveBorderFacts, deriveTypefaceFacts, ciede2000, hexToLab, diffKeyGeometry, buildStructuralBlock, buildReviewScaffold, appearanceReferenceFromPreviousRender, buildAppearanceReferenceFromParams, getStructuralFactsStageInternals, getGeometryStageInternals, } from './structural-facts.js';
12
12
  // 200x400 canvas in px for all fixtures unless noted.
13
13
  const CANVAS = { left: 0, top: 0, right: 200, bottom: 400 };
14
14
  describe('deriveStructuralFacts — containment', () => {
@@ -486,6 +486,45 @@ describe('buildStructuralBlock — with reference geometry (Signal B)', () => {
486
486
  expect(banner?.sizeFlag).toBe(true);
487
487
  expect(banner?.deltas).toContainEqual({ dimension: 'h', delta: 24 });
488
488
  });
489
+ test('a declared tag absent from the render persists its design box alone', () => {
490
+ // The absence itself is reported by the presence channel (element_missing);
491
+ // this is the BOX that lets that report's evidence point at the region the
492
+ // design reserved. Design-only: no rendered half, no comparison fields
493
+ // (there is nothing to compare), no ancestry (there is no node to chain
494
+ // from). Exhaustive on purpose, like the voucher assertion above.
495
+ const reference = { ...HUB_PROMO_REFERENCE, cta: { w: 112, h: 36, x: 16, y: 200 } };
496
+ const block = buildStructuralBlock(HUB_PROMO_DUMP, reference, 2);
497
+ expect(block.geometry?.elements.find((e) => e.id === 'cta')).toEqual({
498
+ id: 'cta',
499
+ design: { w: 112, h: 36, x: 16, y: 200 },
500
+ });
501
+ // The summary must not move: the deltas and flags that drive it exist only
502
+ // on compared elements, and an element that rendered nothing compares to
503
+ // nothing. Byte-identical to the same dump judged without the absent tag.
504
+ expect(block.summary).toEqual(buildStructuralBlock(HUB_PROMO_DUMP, HUB_PROMO_REFERENCE, 2).summary);
505
+ });
506
+ test('a w/h-only declared tag absent from the render stays w/h — x/y are never invented', () => {
507
+ const reference = { ...HUB_PROMO_REFERENCE, chip: { w: 40, h: 20 } };
508
+ const block = buildStructuralBlock(HUB_PROMO_DUMP, reference, 2);
509
+ expect(block.geometry?.elements.find((e) => e.id === 'chip')).toEqual({
510
+ id: 'chip',
511
+ design: { w: 40, h: 20 },
512
+ });
513
+ });
514
+ test('a duplicated declared tag emits nothing — it rendered (twice); last-wins is ambiguous', () => {
515
+ const dump = {
516
+ canvas: { left: 0, top: 0, right: 200, bottom: 400 },
517
+ nodes: [
518
+ { id: 'node-1', bounds: { left: 0, top: 0, right: 200, bottom: 400 }, parentId: null, clipsChildren: false },
519
+ { id: 'chip', bounds: { left: 0, top: 0, right: 40, bottom: 20 }, parentId: 'node-1', clipsChildren: false },
520
+ { id: 'chip', bounds: { left: 60, top: 0, right: 100, bottom: 20 }, parentId: 'node-1', clipsChildren: false },
521
+ ],
522
+ };
523
+ const block = buildStructuralBlock(dump, { chip: { w: 20, h: 10, x: 0, y: 0 } }, 2);
524
+ // Not a pair, and not a design-only entry either: the tag DID render, so
525
+ // "absent" would be a lie; the duplicate_tag fact carries the collision.
526
+ expect(block.geometry?.elements.find((e) => e.id === 'chip')).toBeUndefined();
527
+ });
489
528
  test('authored elements outside the reference ride along as rendered-only boxes', () => {
490
529
  const block = buildStructuralBlock(HUB_PROMO_DUMP, HUB_PROMO_REFERENCE, 2);
491
530
  // The reference declares voucher+banner; `copy` is authored but undeclared,
@@ -1201,6 +1240,11 @@ describe('buildStructuralBlock — appearance container (Signal C, additive)', (
1201
1240
  const embedded = getGeometryStageInternals();
1202
1241
  expect(embedded.buildStructuralBlock(NESTED_DUMP, NESTED_REFERENCE, 2)).toEqual(buildStructuralBlock(NESTED_DUMP, NESTED_REFERENCE, 2));
1203
1242
  });
1243
+ test('embedded stage matches the module for a declared tag absent from the render (parity)', () => {
1244
+ const embedded = getGeometryStageInternals();
1245
+ const reference = { ...HUB_PROMO_REFERENCE, cta: { w: 112, h: 36, x: 16, y: 200 } };
1246
+ expect(embedded.buildStructuralBlock(HUB_PROMO_DUMP, reference, 2)).toEqual(buildStructuralBlock(HUB_PROMO_DUMP, reference, 2));
1247
+ });
1204
1248
  test('embedded stage matches the module for the figma missing-element case (parity, issue 03)', () => {
1205
1249
  const embedded = getGeometryStageInternals();
1206
1250
  const reference = {
@@ -2822,4 +2866,47 @@ describe('embedded geometry stage parity', () => {
2822
2866
  expect(embedded.buildStructuralBlock(dump, ref, 1, undefined, undefined, frame)).toEqual(buildStructuralBlock(dump, ref, 1, undefined, undefined, frame));
2823
2867
  });
2824
2868
  });
2869
+ // ─── Border facts (property-recognizer 01) ───────────────────────────────────
2870
+ // The runner half of the comparison that finally makes a missing ring visible.
2871
+ // These lock the TYPED copy; the ES5 runner twin is exercised through the
2872
+ // generated-script tests, and the two must not drift — patching one only is a
2873
+ // silent asymmetry between the local preview and the real gate.
2874
+ describe('deriveBorderFacts — the design stroke vs the rendered border', () => {
2875
+ const REF = { badge: { fill: '#3ca000', stroke: '#ffffff', strokeWeight: 4 } };
2876
+ test('THE motivating case: a declared ring the render never drew', () => {
2877
+ expect(deriveBorderFacts({ badge: { fill: '#3ca000' } }, REF, true)).toEqual([
2878
+ { kind: 'border_missing', elementId: 'badge', reference: '#ffffff', referenceWidth: 4 },
2879
+ ]);
2880
+ });
2881
+ test('a border-blind dump states NOTHING — silence is "cannot see", not "absent"', () => {
2882
+ // Without this gate every stroked design in the catalogue gains a finding on
2883
+ // the strength of a blindness. The caller raises a not-checked advisory.
2884
+ expect(deriveBorderFacts({ badge: { fill: '#3ca000' } }, REF, false)).toEqual([]);
2885
+ });
2886
+ test('a ring in the wrong colour is a border fact', () => {
2887
+ expect(deriveBorderFacts({ badge: { stroke: '#cccccc', strokeWeight: 4 } }, REF, true)).toEqual([{ kind: 'border', elementId: 'badge', rendered: '#cccccc', reference: '#ffffff' }]);
2888
+ });
2889
+ test('a ring of the right colour and the wrong thickness is its own fact', () => {
2890
+ expect(deriveBorderFacts({ badge: { stroke: '#ffffff', strokeWeight: 1 } }, REF, true)).toEqual([{ kind: 'border_width', elementId: 'badge', rendered: 1, reference: 4 }]);
2891
+ });
2892
+ test('hex case never matters, and a matching ring yields nothing', () => {
2893
+ expect(deriveBorderFacts({ badge: { stroke: '#FFFFFF', strokeWeight: 4 } }, REF, true)).toEqual([]);
2894
+ });
2895
+ test('sub-half-dp width differences are the same ring', () => {
2896
+ expect(deriveBorderFacts({ badge: { stroke: '#ffffff', strokeWeight: 4.4 } }, REF, true)).toEqual([]);
2897
+ });
2898
+ test('a design with no declared stroke says nothing about a rendered ring', () => {
2899
+ // The design is the only side that can raise the question — the same
2900
+ // asymmetry alpha uses. A wrapper adding an unasked-for ring is not a defect
2901
+ // this comparison can name.
2902
+ expect(deriveBorderFacts({ badge: { stroke: '#ffffff', strokeWeight: 4 } }, { badge: { fill: '#3ca000' } }, true)).toEqual([]);
2903
+ });
2904
+ test('an undeclared design WIDTH grades colour only, never thickness', () => {
2905
+ expect(deriveBorderFacts({ badge: { stroke: '#ffffff', strokeWeight: 9 } }, { badge: { stroke: '#ffffff' } }, true)).toEqual([]);
2906
+ // ...and a missing ring still states the colour, without inventing a width.
2907
+ expect(deriveBorderFacts({}, { badge: { stroke: '#ffffff' } }, true)).toEqual([
2908
+ { kind: 'border_missing', elementId: 'badge', reference: '#ffffff' },
2909
+ ]);
2910
+ });
2911
+ });
2825
2912
  //# sourceMappingURL=structural-facts.test.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@invarn/cibuild",
3
- "version": "2.5.0",
3
+ "version": "2.5.2",
4
4
  "description": "CI Build CLI — local pipeline orchestration and validation",
5
5
  "type": "module",
6
6
  "main": "dist/cli.cjs",