@invarn/cibuild 2.3.6 → 2.3.7

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.
@@ -529,6 +529,7 @@ describe('render script runtime', () => {
529
529
  screen: 'HomeView',
530
530
  status: 'rendered',
531
531
  error: null,
532
+ copy_advisory: null,
532
533
  reference_image_path: 'ui-fidelity/references/HomeView.png',
533
534
  rendered_image_path: 'ui-fidelity/rendered/HomeView.png',
534
535
  source_digest: expect.stringMatching(/^[0-9a-f]{64}$/),
@@ -537,6 +538,7 @@ describe('render script runtime', () => {
537
538
  screen: 'SettingsView',
538
539
  status: 'rendered',
539
540
  error: null,
541
+ copy_advisory: null,
540
542
  reference_image_path: 'ui-fidelity/references/SettingsView.png',
541
543
  rendered_image_path: 'ui-fidelity/rendered/SettingsView.png',
542
544
  source_digest: expect.stringMatching(/^[0-9a-f]{64}$/),
@@ -927,6 +929,7 @@ describe('render script runtime (package_source: repo)', () => {
927
929
  screen: 'HomeView',
928
930
  status: 'rendered',
929
931
  error: null,
932
+ copy_advisory: null,
930
933
  reference_image_path: 'ui-fidelity/references/HomeView.png',
931
934
  rendered_image_path: 'ui-fidelity/rendered/HomeView.png',
932
935
  source_digest: expect.stringMatching(/^[0-9a-f]{64}$/),
@@ -1107,6 +1110,7 @@ describe('render script runtime (package_source: inputs)', () => {
1107
1110
  screen: 'HomeView',
1108
1111
  status: 'rendered',
1109
1112
  error: null,
1113
+ copy_advisory: null,
1110
1114
  reference_image_path: 'ui-fidelity/references/HomeView.png',
1111
1115
  rendered_image_path: 'ui-fidelity/rendered/HomeView.png',
1112
1116
  source_digest: expect.stringMatching(/^[0-9a-f]{64}$/),
@@ -1121,6 +1125,7 @@ describe('render script runtime (package_source: inputs)', () => {
1121
1125
  screen: 'SettingsView',
1122
1126
  status: 'rendered',
1123
1127
  error: null,
1128
+ copy_advisory: null,
1124
1129
  reference_image_path: 'ui-fidelity/references/SettingsView.png',
1125
1130
  rendered_image_path: 'ui-fidelity/rendered/SettingsView.png',
1126
1131
  source_digest: expect.stringMatching(/^[0-9a-f]{64}$/),
@@ -1580,4 +1585,121 @@ describe('reference_source: repo', () => {
1580
1585
  expect(ghost?.error?.code).toBe('REFERENCE_MISSING');
1581
1586
  });
1582
1587
  });
1588
+ describe('render script runtime — reference provenance', () => {
1589
+ const GOOD_PROV = {
1590
+ figmaNode: '12:345',
1591
+ locale: 'en',
1592
+ resolved: true,
1593
+ exportedAt: '2026-06-18T10:00:00Z',
1594
+ };
1595
+ test('a placeholder reference (resolved=false) renders and downgrades only the copy channel', async () => {
1596
+ const project = makeProject({
1597
+ screens: { HomeView: 'home.png' },
1598
+ render_locale: 'en',
1599
+ provenance: { HomeView: { ...GOOD_PROV, resolved: false } },
1600
+ });
1601
+ writeReference(project, 'home.png');
1602
+ const run = runScript(project, await buildScript(project));
1603
+ expect(run.status).toBe(0);
1604
+ const home = readResult(project).screens[0];
1605
+ expect(home.status).toBe('rendered');
1606
+ expect(home.error).toBeNull();
1607
+ expect(home.copy_advisory?.code).toBe('copy_unverifiable');
1608
+ expect(home.copy_advisory?.reason).toBe('unresolved_placeholders');
1609
+ });
1610
+ test('the placeholder downgrade is identical without a render_locale (same input, same verdict)', async () => {
1611
+ const project = makeProject({
1612
+ screens: { HomeView: 'home.png' },
1613
+ provenance: { HomeView: { ...GOOD_PROV, resolved: false } },
1614
+ });
1615
+ writeReference(project, 'home.png');
1616
+ const run = runScript(project, await buildScript(project));
1617
+ expect(run.status).toBe(0);
1618
+ const home = readResult(project).screens[0];
1619
+ expect(home.status).toBe('rendered');
1620
+ expect(home.copy_advisory?.reason).toBe('unresolved_placeholders');
1621
+ });
1622
+ test('an Italian reference against an English render downgrades the copy channel', async () => {
1623
+ const project = makeProject({
1624
+ screens: { HomeView: 'home.png' },
1625
+ render_locale: 'en',
1626
+ provenance: { HomeView: { ...GOOD_PROV, locale: 'it' } },
1627
+ });
1628
+ writeReference(project, 'home.png');
1629
+ const run = runScript(project, await buildScript(project));
1630
+ expect(run.status).toBe(0);
1631
+ const home = readResult(project).screens[0];
1632
+ expect(home.status).toBe('rendered');
1633
+ expect(home.copy_advisory?.reason).toBe('locale_mismatch');
1634
+ });
1635
+ test('locale comparison requires a declared render_locale — its absence skips only that', async () => {
1636
+ const project = makeProject({
1637
+ screens: { HomeView: 'home.png' },
1638
+ provenance: { HomeView: { ...GOOD_PROV, locale: 'it' } },
1639
+ });
1640
+ writeReference(project, 'home.png');
1641
+ const run = runScript(project, await buildScript(project));
1642
+ expect(run.status).toBe(0);
1643
+ const home = readResult(project).screens[0];
1644
+ expect(home.status).toBe('rendered');
1645
+ expect(home.copy_advisory ?? null).toBeNull();
1646
+ });
1647
+ test('an absent reference with provenance is fatal (REFERENCE_ABSENT, unverifiable)', async () => {
1648
+ const project = makeProject({
1649
+ screens: { HomeView: 'home.png' },
1650
+ provenance: { HomeView: GOOD_PROV },
1651
+ });
1652
+ // No writeReference — the file is absent.
1653
+ const run = runScript(project, await buildScript(project));
1654
+ expect(run.status).not.toBe(0);
1655
+ const home = readResult(project).screens[0];
1656
+ expect(home.status).toBe('unverifiable');
1657
+ expect(home.error?.code).toBe('REFERENCE_ABSENT');
1658
+ });
1659
+ test('a clean provenanced reference renders with no copy advisory', async () => {
1660
+ const project = makeProject({
1661
+ screens: { HomeView: 'home.png' },
1662
+ render_locale: 'en',
1663
+ provenance: { HomeView: GOOD_PROV },
1664
+ });
1665
+ writeReference(project, 'home.png');
1666
+ const run = runScript(project, await buildScript(project));
1667
+ expect(run.status).toBe(0);
1668
+ const home = readResult(project).screens[0];
1669
+ expect(home.status).toBe('rendered');
1670
+ expect(home.copy_advisory ?? null).toBeNull();
1671
+ });
1672
+ test('an unprovenanced screen keeps its legacy behaviour even with a render_locale (no NO_PROVENANCE arming on iOS)', async () => {
1673
+ // NO_PROVENANCE hard-arming is Android-legacy only; the iOS step never
1674
+ // refused unprovenanced screens and must not start now.
1675
+ const project = makeProject({
1676
+ screens: { HomeView: 'home.png' },
1677
+ render_locale: 'en',
1678
+ provenance: {},
1679
+ });
1680
+ writeReference(project, 'home.png');
1681
+ const run = runScript(project, await buildScript(project));
1682
+ expect(run.status).toBe(0);
1683
+ const home = readResult(project).screens[0];
1684
+ expect(home.status).toBe('rendered');
1685
+ expect(home.copy_advisory ?? null).toBeNull();
1686
+ });
1687
+ test('independent verdicts: a clean sibling carries no advisory while the placeholder state does', async () => {
1688
+ const project = makeProject({
1689
+ screens: { HomeView: 'home.png', SettingsView: 'settings.png' },
1690
+ provenance: {
1691
+ HomeView: GOOD_PROV,
1692
+ SettingsView: { ...GOOD_PROV, resolved: false },
1693
+ },
1694
+ });
1695
+ writeReference(project, 'home.png');
1696
+ writeReference(project, 'settings.png');
1697
+ const run = runScript(project, await buildScript(project));
1698
+ expect(run.status).toBe(0);
1699
+ const [home, settings] = readResult(project).screens;
1700
+ expect(home.copy_advisory ?? null).toBeNull();
1701
+ expect(settings.status).toBe('rendered');
1702
+ expect(settings.copy_advisory?.reason).toBe('unresolved_placeholders');
1703
+ });
1704
+ });
1583
1705
  //# sourceMappingURL=ui-fidelity-render.test.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@invarn/cibuild",
3
- "version": "2.3.6",
3
+ "version": "2.3.7",
4
4
  "description": "CI Build CLI — local pipeline orchestration and validation",
5
5
  "type": "module",
6
6
  "main": "dist/cli.cjs",