@invarn/cibuild 2.2.8 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -45,6 +45,21 @@ export interface LayoutNode {
45
45
  fillColor?: string;
46
46
  /** Text (foreground) color, hex. */
47
47
  textColor?: string;
48
+ /** AnnotatedString background-span extents (issue 16): each range of the
49
+ * node's text drawn with a specified span background — the highlighted
50
+ * substrings. Offsets index into `text`. Absent in dumps from packages
51
+ * generated before the emitter tracked spans, and on spanless text — no
52
+ * signal, never a divergence. */
53
+ textSpans?: TextSpan[];
54
+ }
55
+ /** One highlighted extent of a text node (an AnnotatedString span style with a
56
+ * specified background). */
57
+ export interface TextSpan {
58
+ start: number;
59
+ end: number;
60
+ text: string;
61
+ /** Span background color, hex. */
62
+ background?: string;
48
63
  }
49
64
  export interface LayoutDump {
50
65
  /** The captured canvas / root bounds in px. */
@@ -77,7 +92,71 @@ export type StructuralFact = {
77
92
  height: number;
78
93
  };
79
94
  ratio: number;
95
+ } | {
96
+ /** Composition runs only (design-frame anchor): the captured wrapper
97
+ * root's dp size differs from the declared design frame — an authoring
98
+ * problem with the wrapper, never a defect of the screen. While this
99
+ * fact is present, placement facts are withheld for the State
100
+ * (`StructuralBlock.placement`), so a mis-sized root can never
101
+ * masquerade as placement drift. */
102
+ kind: 'frame_mismatch';
103
+ declared: {
104
+ w: number;
105
+ h: number;
106
+ };
107
+ captured: {
108
+ w: number;
109
+ h: number;
110
+ };
111
+ deltas: Array<{
112
+ dimension: 'w' | 'h';
113
+ delta: number;
114
+ }>;
80
115
  };
116
+ /** The declared design frame for one screen (design px, treated 1:1 with dp —
117
+ * same convention as `ReferenceGeometry`). Composition runs declare one per
118
+ * State via `params.reference_frame`; component runs never pass it. */
119
+ export interface ReferenceFrame {
120
+ w: number;
121
+ h: number;
122
+ }
123
+ /** One member root whose position on the surface diverges from the design
124
+ * frame beyond tolerance (composition runs only): `expected` is the declared
125
+ * design x/y (design px, 1:1 dp), `actual` the rendered root-space dp —
126
+ * directly comparable because the root is frame-sized (asserted). Only the
127
+ * out-of-tolerance dimensions appear in `deltas`. */
128
+ export interface PlacementFact {
129
+ elementId: string;
130
+ expected: {
131
+ x: number;
132
+ y: number;
133
+ };
134
+ actual: {
135
+ x: number;
136
+ y: number;
137
+ };
138
+ deltas: Array<{
139
+ dimension: 'x' | 'y';
140
+ delta: number;
141
+ }>;
142
+ }
143
+ /** Placement drift at or below this many dp is sub-pixel/rounding noise, not
144
+ * a misplacement — same reasoning as the size-delta floor. */
145
+ export declare const DEFAULT_PLACEMENT_TOLERANCE_DP = 2;
146
+ /** Placement-fact gate for one State (composition runs only): present when a
147
+ * design frame was declared and asserted against the captured root. When the
148
+ * root mis-matches the frame, placement facts are WITHHELD (`withheld: true`,
149
+ * with the reason, no `facts`) — the placement deriver must not compute drift
150
+ * against a wrongly-sized canvas. When the root matches, `facts` carries the
151
+ * tolerance-banded member-root x/y divergences (empty = placement holds). */
152
+ export interface StructuralPlacement {
153
+ withheld: boolean;
154
+ reason?: 'frame_mismatch';
155
+ facts?: PlacementFact[];
156
+ }
157
+ /** Captured-root vs declared-frame tolerance (dp): sub-pixel rounding must not
158
+ * read as a mis-sized wrapper root. */
159
+ export declare const DEFAULT_FRAME_TOLERANCE_DP = 1;
81
160
  export interface DeriveStructuralFactsOptions {
82
161
  /** Edge excesses / overlaps at or below this many px are ignored, so that
83
162
  * exact-touching layout edges don't read as overflow or overlap. */
@@ -192,6 +271,8 @@ export interface StructuralBlock {
192
271
  facts: StructuralFact[];
193
272
  geometry?: StructuralGeometry;
194
273
  appearance?: StructuralAppearance;
274
+ /** Composition runs only — see `StructuralPlacement`. */
275
+ placement?: StructuralPlacement;
195
276
  }
196
277
  /** Which reference the appearance facts were diffed against. `previous_render`
197
278
  * facts are regressions/drift, NOT design divergences (the no-Figma path). */
@@ -214,6 +295,16 @@ export type AppearanceFact = {
214
295
  elementId: string;
215
296
  reference: string;
216
297
  }
298
+ /** The highlighted extent (an AnnotatedString background span) differs from
299
+ * the declared reference span (issue 16). `rendered` is what the render
300
+ * actually highlighted (all span extents, comma-joined); `reference` the
301
+ * substring the design highlights. */
302
+ | {
303
+ kind: 'span_mismatch';
304
+ elementId: string;
305
+ rendered: string;
306
+ reference: string;
307
+ }
217
308
  /** In the reference, not rendered. */
218
309
  | {
219
310
  kind: 'element_missing';
@@ -262,6 +353,11 @@ export interface AppearanceReference {
262
353
  * baseline; the previous render's colors on `previous_render`). When supplied,
263
354
  * color facts are derived against the render's per-node colors. */
264
355
  color?: ColorSource;
356
+ /** Declared highlight extents per element id (issue 16): the substring the
357
+ * design highlights on that text element (and optionally its background).
358
+ * When supplied, span facts are derived against the render's per-node
359
+ * `textSpans`. */
360
+ spans?: SpanSource;
265
361
  }
266
362
  /** The per-screen reference params the runner assembles an `AppearanceReference`
267
363
  * from (the slices of `params.reference_*` for one screen). */
@@ -273,6 +369,8 @@ export interface AppearanceReferenceParams {
273
369
  refText?: TextSource | null;
274
370
  /** Per-screen `reference_color` (fill/text color per element id). */
275
371
  refColor?: ColorSource | null;
372
+ /** Per-screen `reference_spans` (declared highlight extents per element id). */
373
+ refSpans?: SpanSource | null;
276
374
  baseline: AppearanceBaseline;
277
375
  }
278
376
  /**
@@ -336,6 +434,33 @@ export type TextSource = Record<string, string | undefined>;
336
434
  * separately-wired concern.
337
435
  */
338
436
  export declare function deriveCopyFacts(rendered: TextSource, reference: TextSource): AppearanceFact[];
437
+ /** Declared highlight extent per element id: the substring the design
438
+ * highlights on that text element (an AnnotatedString background span),
439
+ * optionally with its background color. A missing/empty `text` is "no span
440
+ * signal for that element" — never a divergence. */
441
+ export type SpanSource = Record<string, {
442
+ text?: string;
443
+ background?: string;
444
+ } | undefined>;
445
+ /** The rendered highlight extents per element id — each node's `textSpans`
446
+ * from the layout dump. `undefined` for a node that emitted no spans (an
447
+ * old package, or a spanless text): no signal, never a divergence. */
448
+ export type RenderedSpans = Record<string, TextSpan[] | undefined>;
449
+ /**
450
+ * Span facts (issue 16) from the per-element comparison of rendered highlight
451
+ * extents vs the declared reference span, keyed on the stable element id. For
452
+ * each element the REFERENCE declares a span for: a rendered span whose text
453
+ * equals the declared substring → no fact; rendered spans present but none
454
+ * matching → `span_mismatch` (all rendered extents comma-joined vs the declared
455
+ * substring). An element whose node emitted NO spans produces no fact — old
456
+ * committed packages don't emit `textSpans`, and absence of a signal is never
457
+ * reported as a divergence (regenerating the package picks the signal up).
458
+ *
459
+ * Pure and platform-agnostic; order-independent and deterministic (output
460
+ * sorted by element id). The deriver reports facts only; significance is a
461
+ * later, separately-wired concern.
462
+ */
463
+ export declare function deriveSpanFacts(rendered: RenderedSpans, reference: SpanSource): AppearanceFact[];
339
464
  /** CIELAB triple [L, a, b]. */
340
465
  export type Lab = [number, number, number];
341
466
  /** One element's rendered/reference colors, by channel. A missing channel is
@@ -381,7 +506,7 @@ export declare function deriveColorFacts(rendered: ColorSource, reference: Color
381
506
  export declare function buildStructuralBlock(dump: LayoutDump, referenceGeometry?: ReferenceGeometry | null, density?: number, options?: {
382
507
  sizeTolerancePx?: number;
383
508
  overhangTolerancePx?: number;
384
- }, appearanceReference?: AppearanceReference | null): StructuralBlock;
509
+ }, appearanceReference?: AppearanceReference | null, referenceFrame?: ReferenceFrame | null): StructuralBlock;
385
510
  export interface ReviewRow {
386
511
  element: string;
387
512
  rendered: string | null;
@@ -451,13 +576,14 @@ export declare function getGeometryStageInternals(): {
451
576
  buildStructuralBlock: (dump: LayoutDump, referenceGeometry?: ReferenceGeometry | null, density?: number, options?: {
452
577
  sizeTolerancePx?: number;
453
578
  overhangTolerancePx?: number;
454
- }, appearanceReference?: AppearanceReference | null) => StructuralBlock;
579
+ }, appearanceReference?: AppearanceReference | null, referenceFrame?: ReferenceFrame | null) => StructuralBlock;
455
580
  buildReviewScaffold: (structural: {
456
581
  facts?: StructuralFact[];
457
582
  geometry?: StructuralGeometry | null;
458
583
  }) => ReviewScaffold;
459
584
  derivePresenceFacts: (renderedIds: Iterable<string>, referenceIds: Iterable<string>) => AppearanceFact[];
460
585
  deriveCopyFacts: (rendered: TextSource, reference: TextSource) => AppearanceFact[];
586
+ deriveSpanFacts: (rendered: RenderedSpans, reference: SpanSource) => AppearanceFact[];
461
587
  deriveColorFacts: (rendered: ColorSource, reference: ColorSource) => AppearanceFact[];
462
588
  buildAppearanceReferenceFromParams: (params: AppearanceReferenceParams) => AppearanceReference | null;
463
589
  ciede2000: (lab1: Lab, lab2: Lab) => number;
@@ -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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"}
@@ -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, deriveColorFacts, ciede2000, hexToLab, diffKeyGeometry, buildStructuralBlock, buildReviewScaffold, appearanceReferenceFromPreviousRender, buildAppearanceReferenceFromParams, getStructuralFactsStageInternals, getGeometryStageInternals, } from './structural-facts.js';
11
+ import { deriveStructuralFacts, derivePresenceFacts, deriveCopyFacts, deriveSpanFacts, deriveColorFacts, 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', () => {
@@ -637,6 +637,57 @@ describe('deriveCopyFacts — rendered vs reference text per element', () => {
637
637
  ]);
638
638
  });
639
639
  });
640
+ describe('deriveSpanFacts — declared highlight extents vs rendered background spans', () => {
641
+ test('a rendered span matching the declared extent produces no fact', () => {
642
+ expect(deriveSpanFacts({ discountText: [{ start: 4, end: 13, text: '5 EUR off', background: '#ffe45e' }] }, { discountText: { text: '5 EUR off' } })).toEqual([]);
643
+ });
644
+ test('a rendered span chipping the wrong extent yields span_mismatch with both strings', () => {
645
+ // The motivating case: the design chips the full phrase, the wrapper
646
+ // highlighted only the amount.
647
+ expect(deriveSpanFacts({ discountText: [{ start: 4, end: 9, text: '5 EUR', background: '#ffe45e' }] }, { discountText: { text: '5 EUR off' } })).toEqual([
648
+ { kind: 'span_mismatch', elementId: 'discountText', rendered: '5 EUR', reference: '5 EUR off' },
649
+ ]);
650
+ });
651
+ test('a node that emitted no spans produces no fact (old packages degrade gracefully)', () => {
652
+ // An older committed package's dump has no textSpans field at all — the
653
+ // declared expectation must stay silent, not fire a false missing-span.
654
+ expect(deriveSpanFacts({}, { discountText: { text: '5 EUR off' } })).toEqual([]);
655
+ });
656
+ test('any one of several rendered spans matching the declared extent passes', () => {
657
+ expect(deriveSpanFacts({
658
+ discountText: [
659
+ { start: 0, end: 3, text: 'Get', background: '#eeeeee' },
660
+ { start: 4, end: 13, text: '5 EUR off', background: '#ffe45e' },
661
+ ],
662
+ }, { discountText: { text: '5 EUR off' } })).toEqual([]);
663
+ });
664
+ test('several wrong spans report all their extents in one fact', () => {
665
+ expect(deriveSpanFacts({
666
+ discountText: [
667
+ { start: 0, end: 3, text: 'Get', background: '#eeeeee' },
668
+ { start: 4, end: 9, text: '5 EUR', background: '#ffe45e' },
669
+ ],
670
+ }, { discountText: { text: '5 EUR off' } })).toEqual([
671
+ { kind: 'span_mismatch', elementId: 'discountText', rendered: 'Get, 5 EUR', reference: '5 EUR off' },
672
+ ]);
673
+ });
674
+ test('no declared entry / empty declared text produces no fact (absence of signal is not a divergence)', () => {
675
+ expect(deriveSpanFacts({ discountText: [{ start: 0, end: 3, text: 'Get' }] }, {})).toEqual([]);
676
+ expect(deriveSpanFacts({ discountText: [{ start: 0, end: 3, text: 'Get' }] }, { discountText: { text: '' } })).toEqual([]);
677
+ });
678
+ test('result is order-independent and deterministic (sorted by element id)', () => {
679
+ const rendered = {
680
+ b: [{ start: 0, end: 1, text: 'x' }],
681
+ a: [{ start: 0, end: 1, text: 'y' }],
682
+ };
683
+ const a = deriveSpanFacts(rendered, { a: { text: 'right' }, b: { text: 'x' } });
684
+ const b = deriveSpanFacts(rendered, { b: { text: 'x' }, a: { text: 'right' } });
685
+ expect(a).toEqual(b);
686
+ expect(a).toEqual([
687
+ { kind: 'span_mismatch', elementId: 'a', rendered: 'y', reference: 'right' },
688
+ ]);
689
+ });
690
+ });
640
691
  describe('buildStructuralBlock — appearance container (Signal C, additive)', () => {
641
692
  test('no appearanceReference → no appearance container; facts + geometry unchanged', () => {
642
693
  const withC = buildStructuralBlock(HUB_PROMO_DUMP, HUB_PROMO_REFERENCE, 2);
@@ -1128,9 +1179,70 @@ describe('buildAppearanceReferenceFromParams — union of geometry/text/color id
1128
1179
  color: { banner: { fill: '#fff0ee' } },
1129
1180
  });
1130
1181
  });
1182
+ test('spans only (no geometry/text/color) → a reference carrying spans, ids from the span keys (issue 16)', () => {
1183
+ const ref = buildAppearanceReferenceFromParams({
1184
+ refSpans: { discountText: { text: '5 EUR off', background: '#ffe45e' } },
1185
+ baseline: 'figma',
1186
+ });
1187
+ expect(ref).toEqual({
1188
+ baseline: 'figma',
1189
+ elementIds: ['discountText'],
1190
+ spans: { discountText: { text: '5 EUR off', background: '#ffe45e' } },
1191
+ });
1192
+ });
1131
1193
  test('none present → null (no appearance container)', () => {
1132
1194
  expect(buildAppearanceReferenceFromParams({ baseline: 'figma' })).toBeNull();
1133
- expect(buildAppearanceReferenceFromParams({ baseline: 'figma', refGeom: {}, refColor: {}, refText: {} })).toBeNull();
1195
+ expect(buildAppearanceReferenceFromParams({ baseline: 'figma', refGeom: {}, refColor: {}, refText: {}, refSpans: {} })).toBeNull();
1196
+ });
1197
+ test('fed into buildStructuralBlock, a spans-only reference emits exactly one span_mismatch for the wrong extent (issue 16)', () => {
1198
+ const dump = {
1199
+ canvas: { left: 0, top: 0, right: 686, bottom: 282 },
1200
+ nodes: [
1201
+ {
1202
+ id: 'discountText',
1203
+ bounds: { left: 0, top: 0, right: 300, bottom: 40 },
1204
+ parentId: null,
1205
+ clipsChildren: false,
1206
+ text: 'Get 5 EUR off',
1207
+ textSpans: [{ start: 4, end: 9, text: '5 EUR', background: '#ffe45e' }],
1208
+ },
1209
+ // A node that never emitted spans (old package) — the declared
1210
+ // expectation for it must stay silent.
1211
+ { id: 'legacyText', bounds: { left: 0, top: 50, right: 300, bottom: 90 }, parentId: null, clipsChildren: false, text: 'Free delivery' },
1212
+ ],
1213
+ };
1214
+ const ref = buildAppearanceReferenceFromParams({
1215
+ refSpans: {
1216
+ discountText: { text: '5 EUR off', background: '#ffe45e' },
1217
+ legacyText: { text: 'Free' },
1218
+ },
1219
+ baseline: 'figma',
1220
+ });
1221
+ const block = buildStructuralBlock(dump, null, 2, undefined, ref);
1222
+ expect(block.appearance?.facts).toEqual([
1223
+ { kind: 'span_mismatch', elementId: 'discountText', rendered: '5 EUR', reference: '5 EUR off' },
1224
+ ]);
1225
+ });
1226
+ test('a matching extent yields a container with zero facts (the fixed wrapper is clean)', () => {
1227
+ const dump = {
1228
+ canvas: { left: 0, top: 0, right: 686, bottom: 282 },
1229
+ nodes: [
1230
+ {
1231
+ id: 'discountText',
1232
+ bounds: { left: 0, top: 0, right: 300, bottom: 40 },
1233
+ parentId: null,
1234
+ clipsChildren: false,
1235
+ text: 'Get 5 EUR off',
1236
+ textSpans: [{ start: 4, end: 13, text: '5 EUR off', background: '#ffe45e' }],
1237
+ },
1238
+ ],
1239
+ };
1240
+ const ref = buildAppearanceReferenceFromParams({
1241
+ refSpans: { discountText: { text: '5 EUR off' } },
1242
+ baseline: 'figma',
1243
+ });
1244
+ const block = buildStructuralBlock(dump, null, 2, undefined, ref);
1245
+ expect(block.appearance?.facts).toEqual([]);
1134
1246
  });
1135
1247
  test('fed into buildStructuralBlock, a color-only reference still emits the color fact', () => {
1136
1248
  const dump = {
@@ -1156,6 +1268,139 @@ describe('buildAppearanceReferenceFromParams — union of geometry/text/color id
1156
1268
  ]);
1157
1269
  });
1158
1270
  });
1271
+ describe('buildStructuralBlock — design-frame anchor (composition runs)', () => {
1272
+ // 686x384px at density 2 → a 343×192dp captured root.
1273
+ const FRAME_DUMP = {
1274
+ canvas: { left: 0, top: 0, right: 686, bottom: 384 },
1275
+ nodes: [
1276
+ { id: 'voucher', bounds: { left: 32, top: 48, right: 194, bottom: 210 }, parentId: null, clipsChildren: false },
1277
+ ],
1278
+ };
1279
+ const GEOM = { voucher: { w: 81, h: 81, x: 16, y: 24 } };
1280
+ test('root ≈ declared frame → no mismatch fact, placement is not withheld', () => {
1281
+ const block = buildStructuralBlock(FRAME_DUMP, GEOM, 2, undefined, undefined, { w: 343, h: 192 });
1282
+ expect(block.facts.filter((f) => f.kind === 'frame_mismatch')).toEqual([]);
1283
+ expect(block.placement).toEqual({ withheld: false, facts: [] });
1284
+ });
1285
+ test('sub-tolerance drift (≤1dp) does not read as a mismatch', () => {
1286
+ const block = buildStructuralBlock(FRAME_DUMP, GEOM, 2, undefined, undefined, { w: 342.5, h: 192.5 });
1287
+ expect(block.facts.filter((f) => f.kind === 'frame_mismatch')).toEqual([]);
1288
+ expect(block.placement).toEqual({ withheld: false, facts: [] });
1289
+ });
1290
+ test('a mis-sized root → frame_mismatch fact with declared/captured dims, placement withheld', () => {
1291
+ const block = buildStructuralBlock(FRAME_DUMP, GEOM, 2, undefined, undefined, { w: 343, h: 100 });
1292
+ const mismatches = block.facts.filter((f) => f.kind === 'frame_mismatch');
1293
+ expect(mismatches).toEqual([
1294
+ {
1295
+ kind: 'frame_mismatch',
1296
+ declared: { w: 343, h: 100 },
1297
+ captured: { w: 343, h: 192 },
1298
+ deltas: [{ dimension: 'h', delta: 92 }],
1299
+ },
1300
+ ]);
1301
+ expect(block.placement).toEqual({ withheld: true, reason: 'frame_mismatch' });
1302
+ // A mis-sized wrapper root is not a clean render.
1303
+ expect(block.summary.clean).toBe(false);
1304
+ });
1305
+ test('the mismatch review row reads as a mis-sized wrapper root, never a screen defect', () => {
1306
+ const block = buildStructuralBlock(FRAME_DUMP, GEOM, 2, undefined, undefined, { w: 343, h: 100 });
1307
+ const scaffold = buildReviewScaffold(block);
1308
+ const row = scaffold.rows.find((r) => r.fact.includes('wrapper root'));
1309
+ expect(row).toBeDefined();
1310
+ expect(row.fact).toContain('343×192');
1311
+ expect(row.fact).toContain('343×100');
1312
+ expect(row.fact.toLowerCase()).toContain('size the wrapper root');
1313
+ });
1314
+ test('no declared frame → no placement container, block unchanged from today', () => {
1315
+ const withoutFrame = buildStructuralBlock(FRAME_DUMP, GEOM, 2);
1316
+ expect(withoutFrame.placement).toBeUndefined();
1317
+ expect(buildStructuralBlock(FRAME_DUMP, GEOM, 2, undefined, undefined, null)).toEqual(withoutFrame);
1318
+ });
1319
+ test('embedded stage matches the module for match and mismatch alike (parity)', () => {
1320
+ const embedded = getGeometryStageInternals();
1321
+ for (const frame of [{ w: 343, h: 192 }, { w: 343, h: 100 }, null]) {
1322
+ expect(embedded.buildStructuralBlock(FRAME_DUMP, GEOM, 2, undefined, undefined, frame)).toEqual(buildStructuralBlock(FRAME_DUMP, GEOM, 2, undefined, undefined, frame));
1323
+ }
1324
+ });
1325
+ });
1326
+ describe('buildStructuralBlock — placement facts (composition runs)', () => {
1327
+ // 686x384px at density 2 → a 343×192dp captured root; frame matches.
1328
+ const FRAME = { w: 343, h: 192 };
1329
+ // voucher: design places it at (16, 24); rendered root-space (unclipped)
1330
+ // bounds put it at (16, 24) → in place, or shifted for the drift cases.
1331
+ function dumpWithVoucherAt(leftPx, topPx) {
1332
+ return {
1333
+ canvas: { left: 0, top: 0, right: 686, bottom: 384 },
1334
+ nodes: [
1335
+ {
1336
+ id: 'voucher',
1337
+ bounds: { left: leftPx, top: topPx, right: leftPx + 162, bottom: topPx + 162 },
1338
+ unclippedBounds: { left: leftPx, top: topPx, right: leftPx + 162, bottom: topPx + 162 },
1339
+ parentId: null,
1340
+ clipsChildren: false,
1341
+ },
1342
+ ],
1343
+ };
1344
+ }
1345
+ const GEOM = { voucher: { w: 81, h: 81, x: 16, y: 24 } };
1346
+ test('a member root shifted beyond tolerance → a placement fact with expected/actual/delta', () => {
1347
+ // Rendered at (20, 100)dp = (40, 200)px — design says (16, 24)dp.
1348
+ const block = buildStructuralBlock(dumpWithVoucherAt(40, 200), GEOM, 2, undefined, undefined, FRAME);
1349
+ expect(block.placement).toEqual({
1350
+ withheld: false,
1351
+ facts: [
1352
+ {
1353
+ elementId: 'voucher',
1354
+ expected: { x: 16, y: 24 },
1355
+ actual: { x: 20, y: 100 },
1356
+ deltas: [
1357
+ { dimension: 'x', delta: 4 },
1358
+ { dimension: 'y', delta: 76 },
1359
+ ],
1360
+ },
1361
+ ],
1362
+ });
1363
+ // Placement drift is load-bearing on a composition State — not clean.
1364
+ expect(block.summary.clean).toBe(false);
1365
+ });
1366
+ test('within tolerance (≤2dp) → measured but no fact, still clean', () => {
1367
+ // Rendered at (17, 25)dp = (34, 50)px — 1dp off design (16, 24).
1368
+ const block = buildStructuralBlock(dumpWithVoucherAt(34, 50), GEOM, 2, undefined, undefined, FRAME);
1369
+ expect(block.placement).toEqual({ withheld: false, facts: [] });
1370
+ expect(block.summary.clean).toBe(true);
1371
+ });
1372
+ test('an element without design x/y contributes no placement fact', () => {
1373
+ const geomNoXY = { voucher: { w: 81, h: 81 } };
1374
+ const block = buildStructuralBlock(dumpWithVoucherAt(40, 200), geomNoXY, 2, undefined, undefined, FRAME);
1375
+ expect(block.placement).toEqual({ withheld: false, facts: [] });
1376
+ });
1377
+ test('frame mismatch → placement facts withheld with the reason, none computed', () => {
1378
+ const block = buildStructuralBlock(dumpWithVoucherAt(40, 200), GEOM, 2, undefined, undefined, { w: 343, h: 100 });
1379
+ expect(block.placement).toEqual({ withheld: true, reason: 'frame_mismatch' });
1380
+ expect(block.placement && 'facts' in block.placement).toBe(false);
1381
+ });
1382
+ test('no declared frame (component runs) → no placement facts, identical deltas stay advisory', () => {
1383
+ const block = buildStructuralBlock(dumpWithVoucherAt(40, 200), GEOM, 2);
1384
+ expect(block.placement).toBeUndefined();
1385
+ // x/y deltas still reported (advisory) on the geometry element, unflagged.
1386
+ const el = block.geometry.elements.find((e) => e.id === 'voucher');
1387
+ expect(el.deltas.some((d) => d.dimension === 'x' || d.dimension === 'y')).toBe(true);
1388
+ expect(el.sizeFlag).toBe(false);
1389
+ expect(block.summary.clean).toBe(true);
1390
+ });
1391
+ test('embedded stage matches the module for drift, clean, and withheld (parity)', () => {
1392
+ const embedded = getGeometryStageInternals();
1393
+ const cases = [
1394
+ [dumpWithVoucherAt(40, 200), FRAME],
1395
+ [dumpWithVoucherAt(34, 50), FRAME],
1396
+ [dumpWithVoucherAt(40, 200), { w: 343, h: 100 }],
1397
+ [dumpWithVoucherAt(40, 200), null],
1398
+ ];
1399
+ for (const [dump, frame] of cases) {
1400
+ expect(embedded.buildStructuralBlock(dump, GEOM, 2, undefined, undefined, frame)).toEqual(buildStructuralBlock(dump, GEOM, 2, undefined, undefined, frame));
1401
+ }
1402
+ });
1403
+ });
1159
1404
  describe('embedded geometry stage parity', () => {
1160
1405
  // The render ships a JS-source port of the differ + assembler. It must produce
1161
1406
  // byte-identical blocks to the canonical typed module, or run-side structural
@@ -1183,6 +1428,47 @@ describe('embedded geometry stage parity', () => {
1183
1428
  const appearanceReference = { baseline: 'figma', elementIds: ['banner', 'voucher'] };
1184
1429
  expect(embedded.buildStructuralBlock(HUB_PROMO_DUMP, HUB_PROMO_REFERENCE, 2, undefined, appearanceReference)).toEqual(buildStructuralBlock(HUB_PROMO_DUMP, HUB_PROMO_REFERENCE, 2, undefined, appearanceReference));
1185
1430
  });
1431
+ test('embedded deriveSpanFacts matches the module (Signal C, issue 16)', () => {
1432
+ const cases = [
1433
+ [{ discountText: [{ start: 4, end: 13, text: '5 EUR off' }] }, { discountText: { text: '5 EUR off' } }],
1434
+ [{ discountText: [{ start: 4, end: 9, text: '5 EUR' }] }, { discountText: { text: '5 EUR off' } }],
1435
+ [{}, { discountText: { text: '5 EUR off' } }],
1436
+ [{ discountText: [{ start: 0, end: 3, text: 'Get' }, { start: 4, end: 9, text: '5 EUR' }] }, { discountText: { text: '5 EUR off' } }],
1437
+ [{ b: [{ start: 0, end: 1, text: 'x' }], a: [{ start: 0, end: 1, text: 'y' }] }, { a: { text: 'right' }, b: { text: 'x' } }],
1438
+ [{ discountText: [{ start: 0, end: 3, text: 'Get' }] }, { discountText: { text: '' } }],
1439
+ ];
1440
+ for (const [rendered, reference] of cases) {
1441
+ expect(embedded.deriveSpanFacts(rendered, reference)).toEqual(deriveSpanFacts(rendered, reference));
1442
+ }
1443
+ });
1444
+ test('embedded buildStructuralBlock matches the module with an appearanceReference carrying spans (issue 16)', () => {
1445
+ const dumpWithSpans = {
1446
+ canvas: { left: 0, top: 0, right: 200, bottom: 400 },
1447
+ nodes: [
1448
+ {
1449
+ id: 'discountText',
1450
+ bounds: { left: 0, top: 0, right: 100, bottom: 20 },
1451
+ parentId: null,
1452
+ clipsChildren: false,
1453
+ text: 'Get 5 EUR off',
1454
+ textSpans: [{ start: 4, end: 9, text: '5 EUR', background: '#ffe45e' }],
1455
+ },
1456
+ ],
1457
+ };
1458
+ const appearanceReference = {
1459
+ baseline: 'figma',
1460
+ elementIds: ['discountText'],
1461
+ spans: { discountText: { text: '5 EUR off', background: '#ffe45e' } },
1462
+ };
1463
+ expect(embedded.buildStructuralBlock(dumpWithSpans, null, 2, undefined, appearanceReference)).toEqual(buildStructuralBlock(dumpWithSpans, null, 2, undefined, appearanceReference));
1464
+ });
1465
+ test('embedded buildAppearanceReferenceFromParams matches the module for a spans declaration (issue 16)', () => {
1466
+ const params = {
1467
+ refSpans: { discountText: { text: '5 EUR off', background: '#ffe45e' } },
1468
+ baseline: 'figma',
1469
+ };
1470
+ expect(embedded.buildAppearanceReferenceFromParams(params)).toEqual(buildAppearanceReferenceFromParams(params));
1471
+ });
1186
1472
  test('embedded deriveCopyFacts matches the module (Signal C)', () => {
1187
1473
  const cases = [
1188
1474
  [{ title: 'a' }, { title: 'a' }],
@@ -1 +1 @@
1
- {"version":3,"file":"ui-fidelity-render-android.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/ui-fidelity-render-android.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAMpE,sDAAsD;AACtD,MAAM,WAAW,6BAA6B;IAC5C;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,yBAAyB,CAAC;AAE1D,iDAAiD;AACjD,eAAO,MAAM,eAAe,6BAA8B,CAAC;AAC3D,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7D;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,EAAE,aAAwB,CAAC;AAE9D,mDAAmD;AACnD,eAAO,MAAM,iBAAiB,6BAA8B,CAAC;AAC7D,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjE;;;GAGG;AACH,eAAO,MAAM,wBAAwB,EAAE,eAA0B,CAAC;AAElE,gFAAgF;AAChF,eAAO,MAAM,wBAAwB,mBAAmB,CAAC;AAEzD,4DAA4D;AAC5D,eAAO,MAAM,gBAAgB,0BAA0B,CAAC;AAExD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,8EAA8E;AAC9E,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC;AA26BD;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,yBAAyB,GAAG,MAAM,CAqBrF;AAED;;;GAGG;AACH,qBAAa,mCAAoC,SAAQ,gBAAgB;IACvE,yBAAyB,CACvB,OAAO,EAAE,6BAA6B,EACtC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,OAAO,EAAE,QAAQ,GAChB,qBAAqB,EAAE;IAepB,OAAO,CACX,MAAM,EAAE,6BAA6B,EACrC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,OAAO,EAAE,QAAQ,GAChB,OAAO,CAAC,OAAO,CAAC;CA0EpB"}
1
+ {"version":3,"file":"ui-fidelity-render-android.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/ui-fidelity-render-android.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAMpE,sDAAsD;AACtD,MAAM,WAAW,6BAA6B;IAC5C;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,yBAAyB,CAAC;AAE1D,iDAAiD;AACjD,eAAO,MAAM,eAAe,6BAA8B,CAAC;AAC3D,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7D;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,EAAE,aAAwB,CAAC;AAE9D,mDAAmD;AACnD,eAAO,MAAM,iBAAiB,6BAA8B,CAAC;AAC7D,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjE;;;GAGG;AACH,eAAO,MAAM,wBAAwB,EAAE,eAA0B,CAAC;AAElE,gFAAgF;AAChF,eAAO,MAAM,wBAAwB,mBAAmB,CAAC;AAEzD,4DAA4D;AAC5D,eAAO,MAAM,gBAAgB,0BAA0B,CAAC;AAExD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,8EAA8E;AAC9E,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC;AAy8BD;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,yBAAyB,GAAG,MAAM,CAqBrF;AAED;;;GAGG;AACH,qBAAa,mCAAoC,SAAQ,gBAAgB;IACvE,yBAAyB,CACvB,OAAO,EAAE,6BAA6B,EACtC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,OAAO,EAAE,QAAQ,GAChB,qBAAqB,EAAE;IAepB,OAAO,CACX,MAAM,EAAE,6BAA6B,EACrC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,OAAO,EAAE,QAAQ,GAChB,OAAO,CAAC,OAAO,CAAC;CA0EpB"}
@@ -119,10 +119,22 @@ var referenceText = null;
119
119
  // { fill, text } hex), set in main() and read by the structural assembler. Null
120
120
  // when none declared → no color facts.
121
121
  var referenceColor = null;
122
+ // params.reference_spans (Signal C span facts, issue 16: the declared highlight
123
+ // extent per element id per screen, as { text, background }), set in main() and
124
+ // read by the structural assembler. Null when none declared → no span facts.
125
+ var referenceSpans = null;
122
126
  // params.reference_baseline (Signal C: 'figma' (default) or 'previous_render').
123
127
  // Marks whether the appearance reference is the design (divergences) or the
124
128
  // previous catalog render (regressions/drift, the no-Figma path).
125
129
  var referenceBaseline = null;
130
+ // params.reference_frame (composition runs: the design frame's { w, h } per
131
+ // screen, design px treated 1:1 with dp), set in main() and read by the
132
+ // structural assembler, which asserts the captured root against it. Null when
133
+ // none declared → no frame assertion, no placement gate.
134
+ var referenceFrame = null;
135
+ // params.proof_kind ('component' default | 'composition'), set in main(). The
136
+ // frame assertion and the placement gate only apply to composition runs.
137
+ var proofKind = 'component';
126
138
 
127
139
  function log(message) {
128
140
  console.log('[ui-fidelity-render-android] ' + message);
@@ -657,7 +669,7 @@ function renderScreens(renderable, projectRoot) {
657
669
  // geometry deltas vs reference_geometry) onto the screen entry, so the
658
670
  // judge reads the signals from protocol-result.json without fetching
659
671
  // artifacts. CONFIG.scale is the render density (dp = px / scale).
660
- assembleStructural(entry, layoutSource, referenceGeometry, CONFIG.scale, referenceText, referenceColor, referenceBaseline);
672
+ assembleStructural(entry, layoutSource, referenceGeometry, CONFIG.scale, referenceText, referenceColor, referenceBaseline, referenceFrame, proofKind, referenceSpans);
661
673
  }
662
674
  });
663
675
  } finally {
@@ -739,10 +751,28 @@ function main() {
739
751
  !Array.isArray(params.reference_color)
740
752
  ? params.reference_color
741
753
  : null;
754
+ // Signal-C span reference (issue 16): { "<Screen>": { "<elementId>":
755
+ // { text, background } } } — the substring the design highlights on that
756
+ // text element. Absent → no span facts.
757
+ referenceSpans =
758
+ params.reference_spans &&
759
+ typeof params.reference_spans === 'object' &&
760
+ !Array.isArray(params.reference_spans)
761
+ ? params.reference_spans
762
+ : null;
742
763
  // Signal-C baseline marker: 'previous_render' when the appearance reference was
743
764
  // sourced from the previous catalog render (no-Figma drift path), else 'figma'.
744
765
  referenceBaseline =
745
766
  params.reference_baseline === 'previous_render' ? 'previous_render' : 'figma';
767
+ // Composition-run inputs: the declared kind gates the frame assertion; the
768
+ // per-screen design frame is what the captured root is asserted against.
769
+ proofKind = params.proof_kind === 'composition' ? 'composition' : 'component';
770
+ referenceFrame =
771
+ params.reference_frame &&
772
+ typeof params.reference_frame === 'object' &&
773
+ !Array.isArray(params.reference_frame)
774
+ ? params.reference_frame
775
+ : null;
746
776
 
747
777
  var screens = Object.keys(params.screens);
748
778
  currentEntries = screens.map(function (screen) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@invarn/cibuild",
3
- "version": "2.2.8",
3
+ "version": "2.3.0",
4
4
  "description": "CI Build CLI — local pipeline orchestration and validation",
5
5
  "type": "module",
6
6
  "main": "dist/cli.cjs",