@nextcommerce/campaigns-os 1.60.0 → 1.61.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.
Files changed (88) hide show
  1. package/CHANGELOG.md +126 -0
  2. package/README.md +5 -5
  3. package/agents/claude/CLAUDE.md +15 -0
  4. package/agents/codex/AGENTS.md +15 -0
  5. package/agents/copilot/copilot-instructions.md +15 -0
  6. package/agents/cursor/campaigns-os.mdc +15 -0
  7. package/compatibility.json +1 -1
  8. package/contracts/brand-theme-target-tokens.next-core.v0.json +95 -25
  9. package/contracts/campaign-cart-sdk-support-policy.v0.json +2 -2
  10. package/contracts/commerce-surface-catalog.json +27 -26
  11. package/contracts/release-ledger.json +768 -0
  12. package/contracts/supported-surface.json +4 -4
  13. package/contracts/template-brand-contract.shared-commerce.v0.json +1 -1
  14. package/docs/access-model.md +20 -0
  15. package/docs/brand-theme-bridge.md +62 -3
  16. package/docs/build-packet.md +28 -1
  17. package/docs/campaign-build-brief.md +16 -0
  18. package/docs/campaigns-os-build-flow.md +61 -2
  19. package/docs/campaignspec-authoring-examples.md +116 -0
  20. package/docs/design-source-package.md +46 -2
  21. package/docs/entry-points.md +188 -0
  22. package/docs/local-setup.md +1 -1
  23. package/docs/orientation-contract-reference.md +1 -1
  24. package/docs/polish-evidence.md +40 -2
  25. package/docs/qa-and-test-orders.md +50 -2
  26. package/docs/quickstart.md +438 -0
  27. package/docs/readback.md +119 -6
  28. package/docs/runtime-readiness.md +1 -1
  29. package/docs/sdk-storage-compatibility.md +3 -1
  30. package/docs/skills-revision.md +10 -10
  31. package/docs/source-adapters.md +213 -0
  32. package/package.json +10 -3
  33. package/schemas/campaign-design-source-package.v0.schema.json +8 -0
  34. package/schemas/campaigns-os-readback.v2.schema.json +177 -1
  35. package/schemas/source-html-manifest.v0.schema.json +3 -0
  36. package/skills/campaign-lifecycle-orientation/SKILL.md +3 -3
  37. package/skills/campaign-readback-classification/SKILL.md +3 -3
  38. package/skills/campaign-run-evidence/SKILL.md +3 -3
  39. package/skills/contribution-intake/SKILL.md +3 -3
  40. package/skills/next-campaigns-build/SKILL.md +4 -4
  41. package/skills/next-campaigns-os/SKILL.md +4 -3
  42. package/skills/next-campaigns-os-setup/SKILL.md +3 -3
  43. package/skills/next-campaigns-polish/SKILL.md +6 -9
  44. package/skills/next-campaigns-qa/SKILL.md +3 -3
  45. package/skills/next-campaigns-sdk-bump/SKILL.md +117 -24
  46. package/skills.json +11 -11
  47. package/src/brand-theme.mjs +413 -8
  48. package/src/brief-summary.mjs +6 -2
  49. package/src/browser-launch.mjs +2 -1
  50. package/src/build-brief.mjs +9 -2
  51. package/src/built-site-scope.mjs +2 -2
  52. package/src/cli.mjs +52 -13
  53. package/src/design-file-reference.mjs +93 -0
  54. package/src/design-source-package.mjs +55 -1
  55. package/src/doctor/checks.mjs +8 -74
  56. package/src/doctor/ci.mjs +112 -0
  57. package/src/doctor/inspect.mjs +18 -0
  58. package/src/doctor/source-provenance.mjs +74 -0
  59. package/src/evidence-debt.mjs +119 -0
  60. package/src/parity/compare.mjs +316 -0
  61. package/src/parity/design-access.mjs +54 -0
  62. package/src/parity/element-parity-record.mjs +569 -0
  63. package/src/parity/probe.mjs +205 -0
  64. package/src/parity/snapshot.mjs +110 -0
  65. package/src/png-header.mjs +87 -0
  66. package/src/polish-browser.mjs +186 -9
  67. package/src/polish-captures-record.mjs +52 -0
  68. package/src/polish-deadline.mjs +14 -0
  69. package/src/polish-gate.mjs +25 -6
  70. package/src/polish-node.mjs +81 -7
  71. package/src/polish-visual-fixtures.mjs +74 -0
  72. package/src/polish-visual.mjs +606 -0
  73. package/src/qa-analytics-correctness.mjs +14 -2
  74. package/src/qa-analytics-parity.mjs +94 -5
  75. package/src/qa-node.mjs +39 -6
  76. package/src/qc-accept.mjs +148 -6
  77. package/src/qc-check-registry.mjs +37 -1
  78. package/src/qc-results.mjs +404 -16
  79. package/src/readback.mjs +57 -13
  80. package/src/sdk-attribute-index.mjs +11 -11
  81. package/src/sdk-markup.mjs +77 -2
  82. package/src/sdk-storage-compatibility.mjs +94 -4
  83. package/src/source-html-manifest.mjs +7 -0
  84. package/src/source-html-server.mjs +129 -0
  85. package/src/stage-record.mjs +45 -7
  86. package/src/theme-gate.mjs +2 -2
  87. package/src/visual-diff.mjs +296 -0
  88. package/src/visual-reference.mjs +126 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,132 @@
2
2
 
3
3
  Notable supported-surface changes are recorded here.
4
4
 
5
+ ## [1.61.0] - 2026-10-23
6
+
7
+ ### Changed
8
+
9
+ - Publishes `1.60.0+agent.7`: installed users receive the quickstart, access, source-adapter and CampaignSpec authoring guides, and the package check verifies documentation links and headings inside the installed package.
10
+ - Publishes `1.60.0+agent.8`: readback reports when a changed build requires Polish or QA again, and `doctor --ci` reports that evidence debt for campaign pull requests. Installed agent context describes revising a live campaign and renewing its evidence (campaigns-os#695, campaigns-os#699).
11
+ - Publishes `1.60.0+agent.9`: completed Polish requires current package captures, with a captured build screenshot for every planned route; source renders are captured beside them for comparison. The review handoff includes visual reference warnings and image differences for operator review; pixel scores do not decide fidelity (campaigns-os#696).
12
+ - Publishes `1.60.0+agent.10`: the brand theme carries the design source's fonts and button radius onto commerce pages. `theme generate` writes `brand-fonts.css` beside `brand-theme.css`, and `record theme` refuses a styled commerce page that doesn't load it (campaigns-os#703).
13
+ - Intake records a manifest `design_file` as the page's authority and its HTML export as derived from that file; a Figma spec `design_source` records that lineage only with figma-sections-export provenance that passes doctor's `source_html.producer_provenance` check without a waiver. This version cannot read design files, so `design.access` reports `unexercised` with `design_access_missing` for a recorded file and explains how to continue or compare the export and file by hand; a changed design file or conflicting declaration is listed for review; an absent declaration reports `design_reference_missing`, with recovery by restoring it or rerunning intake with `--force` to drop the recorded file (campaigns-os#697).
14
+ - Polish probes the source and built renders and reports element-level differences in geometry, typography, colour and copy as warnings an operator can review and accept; they never block Polish or change readiness (campaigns-os#697).
15
+ - The readback schema now describes the optional `evidence_debt` field, its `current`, `owed` and `unknown` stage statuses, reasons and changes against the retained assembly manifest. Any owed Polish or QA stage makes `clean` false; unknown debt still needs review when `clean` is true.
16
+ - Bundled skills advance to `1.61.0+skills.1`.
17
+
18
+ ## [1.60.0+agent.10] - 2026-10-23
19
+
20
+ ### Changed
21
+
22
+ Brand theme carries the design source's type onto commerce pages, not only its colours:
23
+
24
+ - `theme inspect` / `theme generate` read the `@font-face` rules the source ships and the families its headings, body copy and buttons use, plus the button `border-radius`. `var()` references resolve through custom properties on `:root`, `html`, `body` and the class a stylesheet scopes itself under (the importer's `.cc-import`). They map to next-core's `--_text---font-family--heading`, `--_text---font-family--primary` and `--radius-size--buttons` (new `typography` block in `contracts/brand-theme-target-tokens.next-core.v0.json`). Each family is followed directly by the generic the source declared for it. A family is mapped only when the source ships a face for it; one that can't ship is a `theme.typography.face_unavailable` warning and is listed in the report's `typography.unavailable`. The radius takes `0` or one to four lengths or percentages, lists any other button radius in `typography.radius_rejected`, and is mapped only alongside a family, so a source without brand faces generates the same CSS as before.
25
+ - The font-family tokens are emitted in a `:root, body` block, because next-core re-declares them on `body` at its 991, 767 and 479px breakpoints and a `:root`-only value held on desktop alone. `validateGeneratedCss` accepts that block.
26
+ - `theme generate` writes `.campaign-runtime/theme/brand-fonts.css` beside `brand-theme.css`: only `@font-face` rules for the mapped families, always with `font-display: swap`, every format of a face kept, and URLs relative to `assets/css/`. Remote, `data:`, root-relative, missing, or outside-root face files (checked on real paths, so symlinks out are caught) are left out with `theme.typography.face_src_dropped`. The theme report gains `typography`, and `generated.fonts_css_path` names the file.
27
+ - `record theme` refuses a styled commerce page that doesn't load a copy of the generated `brand-fonts.css` (found through the Build Context's `theme.generated.fonts_css_path`) from inside the built site, identical to the generated file, naming the page. The theme gate's generate/apply actions, the build guidance, `docs/brand-theme-bridge.md`, and the build (1.0.50) and polish (1.1.50) skills say to copy and load it. Polish now checks font parity at a mobile width as well as desktop.
28
+ - The skills bundle revision advances to `1.60.0+skills.5`, and every bundled skill moves one patch version.
29
+
30
+ ## [1.60.0+agent.9] - 2026-10-23
31
+
32
+ ### Changed
33
+
34
+ `polish capture` now takes its own full-page captures of each mapped page and of the page's source HTML at desktop and mobile widths, verifies the source screenshots recorded in the Design Source Package, and compares compatible pairs section by section as a review diagnostic with a heatmap. `record polish` now requires these package captures for a completed Polish, including at least one rendered build cell with a captured actual shot for every planned route. Agent-written screenshot paths no longer satisfy the screenshot check for a new record, so run `polish capture` again after upgrading. Polish records written before this version are read as before. The source HTML render runs offline: it reaches only a local read-only server, and requests, WebSocket connections and host-name lookups to anything else are blocked. Source screenshots or pages that are the build's own output are reported as self-referential warnings. Width or pixel-ratio mismatches are reported as unsupported, never resized. The comparison never passes, fails or blocks anything. `pngjs` and `pixelmatch` are new optional dependencies; without them captures are still taken and the comparison is listed as unavailable. Capture images are kept out of the repository by a `.gitignore` inside each capture folder.
35
+
36
+ The Polish skill is 1.1.49, bundle `1.60.0+skills.4`.
37
+
38
+ ## [1.60.0+agent.8] - 2026-10-23
39
+
40
+ ### Added
41
+
42
+ Readback's additive `evidence_debt` field and text section show whether Polish and QA bind to the build on disk: `current`, `owed`, or `unknown`. Changed pages and other changed files are listed against the retained assembly manifest. An empty page list does not clear an owed stage. Missing or unreadable output or a missing assembly fingerprint leaves stage debt unknown. Otherwise a lifecycle-recorded `required` stage is owed (reason `stage_required_by_build`, `stage_required_by_brief`, or `stage_required_by_spec` from `required_by`, and `stage_required` for an absent or unrecognized source), even without a stage fingerprint; other missing stage fingerprints leave debt unknown. A missing or unusable manifest leaves only page changes unknown; matching stage bindings remain current unless required, and differing bindings remain owed. This build comparison is independent of readback's time-based staleness. Either owed stage makes `clean` false (campaigns-os#699).
43
+
44
+ `doctor --ci --packet <packet> --no-live-refs` reports the same evidence debt as Markdown for a PR comment, or under `ci` with `--json`. It exits 0 when both stages are current, 3 when either is owed, 4 when debt cannot be determined, and 2 when the packet is missing or unreadable. Other doctor findings remain visible without changing the CI exit code. The check does not renew evidence or deploy (campaigns-os#695).
45
+
46
+ The workflow example at `docs/examples/campaign-repo-evidence-check.yml` installs locked dependencies, builds the campaign, runs the check and posts or updates one PR comment. Evidence findings are report-only by default; set the repository Actions variable `CAMPAIGNS_OS_EVIDENCE_CHECK` to `fail` to enforce them. Install and build failures still fail normally and replace the comment with a fixed "build failed; evidence not evaluated" message when doctor did not run. A comment-permission failure leaves the report in the job log (campaigns-os#695).
47
+
48
+ ### Changed
49
+
50
+ The installed agent context for all four supported harnesses gains a live-campaign revision section: read readback and `next` before editing, follow the Design Source Package, rebuild and record the build before capturing and recording Polish, run QA when owed, and show each changed page's design reference beside its preview in the PR. `install-agent-context --dry-run` previews each destination and its full content without writing files; `--json` carries the same preview (campaigns-os#699).
51
+
52
+ ## [1.60.0+agent.7] - 2026-10-22
53
+
54
+ ### Fixed
55
+
56
+ The installed package now includes the existing quickstart, access model, entry-point, source-adapter and CampaignSpec authoring guides. Links from the Build Packet and README continue inside the package; repository-only evaluation, architecture and case-study references point to GitHub. The authoring guide links the shipped v5 schema and public multi-step examples, which remain repository test data.
57
+
58
+ The package check follows relative documentation links and checks destination headings against the extracted tarball, so a source-only guide or renamed anchor cannot leave installed users at a dead end. It ignores illustrative code and does not fetch external links. Runtime requirements and campaign behavior are unchanged.
59
+
60
+ ## [1.60.0+agent.6] - 2026-10-22
61
+
62
+ ### Changed
63
+
64
+ `sdk storage-check` output, from Sam's findings on campaigns-os#683:
65
+
66
+ - When `--target-sdk` is outside the manifest's supported range, the human report's first line reads `checked against SDK <range>, not the requested target <x.y.z>`, the next line says the report does not speak for that target, and the count line repeats it. The result is still `unknown` and the exit status still 2. `--json` adds `targetCovered`.
67
+ - An unknown `dynamic-key`, `unsupported-storage-method` or `storage-object-escape` line inside a loop that matches the keys it reads from storage by a scoped SDK key's prefix (`k.indexOf('next-cart-state') === 0`, `k.startsWith(...)`) ends in `[prefix loop: <prefix>]`, and `--json` adds `prefixScan` to the finding. A key read from storage is a `k = sessionStorage.key(i)` variable, a for-of over `Object.keys(sessionStorage)` or for-in over `sessionStorage`, or the element parameter (the second for `reduce`) of a callback chained on `Object.keys(sessionStorage)`. Only the line where that key came from, or a line that reads that key by name, is marked; other storage use in the loop, such as passing `sessionStorage` to a function, is not. One note under the findings explains them: the loop survives the scope suffix, but on a shared origin the prefix also matches another campaign's copy, so the lines stay unknown. Where the manifest names a public store for the key, the note names it.
68
+
69
+ ## [1.60.0+agent.5] - 2026-10-22
70
+
71
+ ### Changed
72
+
73
+ `qa run`'s test customer and shipping address flags are now documented and supported (campaigns-os#683 review). The order runner has always read them; none was in the usage text or the QA docs. `--test-first-name`, `--test-last-name`, `--test-phone`, `--test-country`, `--test-address1`, `--test-city`, `--test-province` and `--test-postal` are listed in `qa help` with their defaults (a US address in Mountain View, CA), and `docs/qa-and-test-orders.md` gains a "Test customer and shipping address" section with a non-US example. The province select is a required step, so a checkout with no province select for the chosen country fails at that field; those orders are placed by hand.
74
+
75
+ A non-USD `--currency` on a `qa run` that places orders, with no `--test-country`, now prints a warning on stderr naming the address flags. The run is not refused. Only the missing flag is checked, since a currency such as EUR has many markets.
76
+
77
+ `qa run --site` lists `--currency <code>` in its usage line, and a test now proves it: the slug's entry page is fetched with `?currency=<CODE>` and the verdict records `evidence.currency` on that page's `http:` row.
78
+
79
+ The `next-campaigns-sdk-bump` skill (1.0.3, bundle `1.60.0+skills.3`) names the address flags in step 6 as the way to run non-US orders through the runner, with ordering by hand as the fallback.
80
+
81
+ ## [1.60.0+agent.4] - 2026-10-22
82
+
83
+ ### Changed
84
+
85
+ The `next-campaigns-sdk-bump` skill (1.0.2, bundle `1.60.0+skills.2`) takes the second-run findings on campaigns-os#683 and a review of them:
86
+
87
+ - Step 1 reads each slug's live or retired status from the target repository's `CLAUDE.md`, root first. A missing or unclear status is never read as live or retired: the skill lists those slugs and asks. Before any order, it shows the developer the live slugs and the orders planned on each, and orders only on the list they confirm.
88
+ - The reload bar in step 6 is one fresh load and five cached reloads of every SDK page, upsells included, with the counts in the hand-back. The receipt, and any page with a hand-wired purchase push or `order:completed` listener, is left out of the cached reloads, because upsell pages reload the order and can resend a real purchase on each load; purchase events are counted across the run.
89
+ - The first page carries `?currency=<main>&country=<main>`. The SDK picks the market by IP and never reads browser geolocation, so the geolocation step is gone. The skill says `?country=` needs `currencyBehavior: auto`, and that an unsupported value falls back without failing, so the shown market is confirmed before the first order. `qa run` takes `--currency <main>`, which pins only each funnel's entry page.
90
+ - `qa run`'s own test orders use a US shipping address by default, so for a non-US main market the orders are placed by hand, with both parameters on the first page of every new tab.
91
+ - Test orders send real purchase events to every analytics vendor the campaign configures unless beacons are blocked at the network, and `qa run` does not block them yet. The vendors, read from the slug's `_data/campaigns.json` ids and `config.js` on Page Kit or the page's inline config on a static funnel, are named in the test-order question, with a note that GTM-fired tags, hand-wired pixels and server-side conversions may also receive them, and again in the hand-back. `?ignore=true` is ruled out: it turns off the SDK's analytics, `dl_*` included, for the rest of the session.
92
+ - The install-browser, `--browser` and local-only answers are asked up front, so a no-packet bump does not skip the `qa run --browser` pass by default. `doctor --built` runs once per bumped slug and `qa run --site` once per live slug. `--family` must exactly match a template brand contract shipped in the package or a private family in `contracts/private-template-sources.json` (which needs its repository checked out or `PRIVATE_TEMPLATE_SOURCES_ROOT`), and `--slug` a key in `_data/campaigns.json`; otherwise the skill asks.
93
+ - Step 3 lists payment and express methods the range adds (0.4.43 adds Shop Pay), and step 6 starts and cancels each one the campaign offers.
94
+ - The skill asks before the first project-local install, pins a reviewed version whose bundle revision matches the skill, and says to expect and commit the `devDependencies` and `package-lock.json` change. In a static repo it never installs into the publish root. `tooling status` only reads the pin.
95
+
96
+ Doctor's SDK attribute index now names Campaign Cart v0.4.43 (`docs/build-packet.md` says so). Regenerated from the source at that tag, it has the same 149 `data-next-*` names as v0.4.42. The cart placeholder renderers are unchanged too, so pages pinned to 0.4.43 pass the placeholder check instead of reading unexercised.
97
+
98
+ ## [1.60.0+agent.3] - 2026-10-21
99
+
100
+ ### Added
101
+
102
+ Doctor's SDK markup check gains two advisories about the page type (campaigns-os#683), on both `doctor --built` and packet doctor:
103
+
104
+ - `PAGE_TYPE_ATTRIBUTE`: a page sets `data-next-page-type` but has no `<meta name="next-page-type">`. The SDK never reads the attribute, so the page runs as the default `product` step, and an upsell page records no upsell page view. The message names the meta value to add, `upsell` on a page with an upsell offer, and never a page type the SDK does not have. Before, the attribute only appeared in the list of `data-next-*` names the SDK does not read.
105
+ - `UPSELL_PAGE_TYPE_MISSING`: a page with a `data-next-upsell` offer whose `next-page-type` meta is missing or is not `upsell`. The SDK records the upsell page view only from `<meta name="next-page-type" content="upsell">` and has no `downsell` page type, so reports showed the purchase with no upsell view before it.
106
+
107
+ Both are warnings; neither blocks. The certified templates raise neither.
108
+
109
+ ### Changed
110
+
111
+ When `tooling status` asks for a skills refresh on some installed harnesses only, the action now names them (for example "for Codex and Shared agent skills; not needed in a session that uses another harness"), so a session in another harness does not take it as its own step (campaigns-os#683).
112
+
113
+ ## [1.60.0+agent.2] - 2026-10-21
114
+
115
+ ### Fixed
116
+
117
+ `analytics-correctness:tag:meta` now passes when the declared Meta pixel initialises and tracks in the page, even if the browser never requests `facebook.com/tr` (campaigns-os#686). Headless Chromium can run `fbq('init')` and `fbq('track')` with fbevents.js loaded and still send no pixel request, so `qa run --browser` blocked campaigns whose pixel works in real browsers. QA now also watches `fbq` calls in the page: a pixel id counts once it is initialised and a track call follows on the same page.
118
+
119
+ If page code replaces `window.fbq` so QA can no longer see its calls, and no matching pixel request was seen, the row still fails but now says `unmeasured` and carries `evidence.reason: fbq_observer_disarmed`, instead of reporting a clean absence.
120
+
121
+ These are unchanged:
122
+ - A pixel that initialises but never tracks, or a different pixel id, still fails the row.
123
+ - An in-page `fbq('track', 'Purchase')` is not a Meta Purchase fire and supplies no CAPI dedup key; both still need the pixel request.
124
+
125
+ ## [1.60.0+agent.1] - 2026-10-20
126
+
127
+ ### Fixed
128
+
129
+ `qa run --site <repo> --base-url <site origin> --slug <slug>` now requests the campaign's pages under `/<slug>/` (campaigns-os#683). Before, it joined each page route straight onto `--base-url`, so it requested `/checkout/` rather than `/<slug>/checkout/` and every page returned 404. The slug is added the same way packet QA adds it: a base URL that already ends in the slug is used as given, and a slug found from the single campaign under `_site/` is added too.
130
+
5
131
  ## [1.60.0] - 2026-10-20
6
132
 
7
133
  ### Changed
package/README.md CHANGED
@@ -423,17 +423,17 @@ See [`campaign-spec/README.md`](campaign-spec/README.md).
423
423
  - [Campaign Standardization Report](docs/campaign-standardization-report.md)
424
424
  - [Entry Points](docs/entry-points.md) — five intake shapes (template-stock, Figma-driven, AI-generated, hand-authored, mixed) and which producer / manifest each one ships with
425
425
  - [Source Adapters](docs/source-adapters.md)
426
- - [Setup Profile Parity](docs/setup-profile-parity.md)
427
- - [Developer Evaluation](docs/developer-evaluation.md)
426
+ - [Setup Profile Parity](https://github.com/NextCommerceCo/campaigns-os/blob/main/docs/setup-profile-parity.md)
427
+ - [Developer Evaluation](https://github.com/NextCommerceCo/campaigns-os/blob/main/docs/developer-evaluation.md)
428
428
  - [QA And Test Orders](docs/qa-and-test-orders.md)
429
429
  - [Run-Artifact Readback](docs/readback.md) — `campaigns-os readback`: a read-only projection of one run's emitted artifacts, with per-artifact freshness against the checkout and a versioned JSON contract to gate on
430
430
  - [Declared Command Effects](docs/effects.md) — what every supported invocation writes and sends, one row per command and effect-changing flag, each row proved by a test that runs the real CLI in a disposable target
431
431
  - [Legacy Migration Contract](docs/legacy-migration.md) — pure inventory, preview-plan, receipt, Offer request/readback, and token-free evidence helpers for bounded SDK 0.3.x shadow migrations
432
- - [Template Family vs Figma-extraction vs Hybrid](docs/template-vs-extraction-decision.md) — when to mint a template family, when to extract a bespoke design, and when to do both
433
- - [Small PR Review Path](docs/small-pr-review-path.md)
432
+ - [Template Family vs Figma-extraction vs Hybrid](https://github.com/NextCommerceCo/campaigns-os/blob/main/docs/template-vs-extraction-decision.md) — when to mint a template family, when to extract a bespoke design, and when to do both
433
+ - [Small PR Review Path](https://github.com/NextCommerceCo/campaigns-os/blob/main/docs/small-pr-review-path.md)
434
434
  - [Run Telemetry](docs/workflow-findings-sidecar.md) — per-run Run Record (system signal + workflow findings) tagged by improvement surface; captured locally always, remitted to Next Commerce only with up-front opt-out consent
435
435
  - [Versioning](docs/versioning.md)
436
- - [ADR 0002: One shipping path](docs/adr/0002-one-shipping-path-campaigns-agent-fold.md) — decides that the agent surface (skills, charter, declared effects, readback) lives in this repository; Campaigns Agent folds in
436
+ - [ADR 0002: One shipping path](https://github.com/NextCommerceCo/campaigns-os/blob/main/docs/adr/0002-one-shipping-path-campaigns-agent-fold.md) — decides that the agent surface (skills, charter, declared effects, readback) lives in this repository; Campaigns Agent folds in
437
437
 
438
438
  ## Status
439
439
 
@@ -39,3 +39,18 @@ Core rules:
39
39
  - Campaigns OS proof is not merchant launch readiness. Before launch, confirm production storefront URL, live payment methods, shipping markets, legal/support URLs, analytics expectations, and merchant-side configuration.
40
40
 
41
41
  Current source adapter: prepared HTML/assets (`html_funnel`).
42
+
43
+ ## Revising a live campaign
44
+
45
+ 1. Before editing, run `npx --no-install campaigns-os readback .` and
46
+ `npx --no-install campaigns-os next --packet campaign-runtime.build.json`.
47
+ Readback's `evidence_debt` compares the build on disk with the builds Polish and QA were recorded for.
48
+ Changed pages are listed against the recorded assembly build manifest; an owed stage with an empty page list still means evidence is owed.
49
+ 2. For pages built from a provided design, the Design Source Package is the authority, not the punch list's wording.
50
+ 3. Before opening the pull request, after the final edit, rebuild, then run `npx --no-install campaigns-os record build --packet campaign-runtime.build.json`,
51
+ `npx --no-install campaigns-os polish capture --packet campaign-runtime.build.json --base-url <served-current-build-url>` for the whole route,
52
+ and `npx --no-install campaigns-os record polish --packet campaign-runtime.build.json --evidence <polish-evidence.json>`, in that order.
53
+ When QA is owed, run `npx --no-install campaigns-os qa run --packet campaign-runtime.build.json` against that build.
54
+ 4. In the pull request body, put the design reference and the preview of each changed page side by side.
55
+
56
+ The standing pull-request check is `npx --no-install campaigns-os doctor --ci --packet campaign-runtime.build.json --no-live-refs`, report-only unless the repo opts in.
@@ -29,3 +29,18 @@ A NEXT campaign is one connected commerce journey: the pages the CampaignSpec de
29
29
  - Do not use `next.getCartData().cartLines` as cart-populated proof; use typed-card order read-back, `cart:updated` payload `items` / `summary.lines`, and rendered bundle DOM evidence.
30
30
  - Campaigns OS proof is not merchant launch readiness. Before launch, confirm production storefront URL, live payment methods, shipping markets, legal/support URLs, analytics expectations, and merchant-side configuration.
31
31
  - This is not full automated readiness. QA remains a separate gate.
32
+
33
+ ## Revising a live campaign
34
+
35
+ 1. Before editing, run `npx --no-install campaigns-os readback .` and
36
+ `npx --no-install campaigns-os next --packet campaign-runtime.build.json`.
37
+ Readback's `evidence_debt` compares the build on disk with the builds Polish and QA were recorded for.
38
+ Changed pages are listed against the recorded assembly build manifest; an owed stage with an empty page list still means evidence is owed.
39
+ 2. For pages built from a provided design, the Design Source Package is the authority, not the punch list's wording.
40
+ 3. Before opening the pull request, after the final edit, rebuild, then run `npx --no-install campaigns-os record build --packet campaign-runtime.build.json`,
41
+ `npx --no-install campaigns-os polish capture --packet campaign-runtime.build.json --base-url <served-current-build-url>` for the whole route,
42
+ and `npx --no-install campaigns-os record polish --packet campaign-runtime.build.json --evidence <polish-evidence.json>`, in that order.
43
+ When QA is owed, run `npx --no-install campaigns-os qa run --packet campaign-runtime.build.json` against that build.
44
+ 4. In the pull request body, put the design reference and the preview of each changed page side by side.
45
+
46
+ The standing pull-request check is `npx --no-install campaigns-os doctor --ci --packet campaign-runtime.build.json --no-live-refs`, report-only unless the repo opts in.
@@ -15,3 +15,18 @@ CampaignSpec validation is owned by the public `@nextcommerce/campaigns-os/campa
15
15
  Preserve Campaign Cart SDK-owned commerce surfaces. Replace starter demo refs from CampaignSpec/API. Prepared AI/exported HTML must be converted into page-kit-ready source first: keep page-owned body markup, strip document wrappers, add YAML frontmatter, move shared CSS/assets into the campaign structure, and use Liquid helpers only for page-kit links/assets/includes. Landing/presell pages can preserve source design; checkout/upsell/downsell/receipt should use starter-template commerce surfaces as SDK contract references while campaign/source owns visual chrome. Reproduce the source design's own proof and urgency elements as designed (reviews, ratings, stock counters, countdowns, guarantees). They are the merchant's content; Campaigns OS does not review them, so do not remove, soften or flag them. Copy starter template families atomically with dependent pages, `_includes/`, `_layouts/`, `assets/css/`, and `assets/js/`; do not copy only checkout/receipt pages. Do not claim launch readiness until build, polish, deploy, and QA evidence are recorded.
16
16
 
17
17
  Before Polish becomes terminal or hands off to deploy/QA, install the package-owned Playwright browser with `npm run qa:install-browser`, serve the current build, and run `npx --no-install campaigns-os polish capture --packet campaign-runtime.build.json --base-url <served-current-build-url>`. After that checkpoint clears, QA must use the Campaigns OS Node/npm runner: run `npx --no-install campaigns-os qa resolve`, then run `npx --no-install campaigns-os qa run --browser --test-order common` against the tested URL. Typed-card test-order proof must use `npx --no-install campaigns-os qa run --test-order <common|checkout|decline|accept|both|full|explicit-path>` through the tested checkout and rendered upsell controls. `qa run` has no permission flag: coverage is its only control. Test orders still land in the store as real orders (global test cards: no charge, no transaction) that someone may have to cancel. Unless the operator has already said test orders are fine for this campaign, ask once, up front in your first turn with your other setup questions, so the answer covers the whole build and QA and neither stops for it later. `common` runs every actual terminal path when they fit under the flood cap (`--max-test-orders`, 6 by default); above the cap it runs the checkout baseline, first-offer accept and decline, and a deduplicated shortest real receipt path, then adds one decline path per offer or downsell page not yet declined, up to the cap, and names any page left out. A page counts as covered only when an order clicks its decline; the `browser-test-order:upsell-action-coverage` verdict row warns naming each page whose decline no order clicked. `full` walks every actual terminal path in the selected checkout topology; cycles, missing routes, and reachable nonterminals block exhaustive proof before browser launch. The accidental-flood cap remains `6`, and an overflow names the exact explicit `--max-test-orders` raise. Analytics correctness is two-phase: the campaign-root visit inventories declared providers/tags only, and the same canonical typed-card run proves Purchase only from the topology-recognized final receipt document after `--analytics-settle`. Missing/unrecognized receipts are manual-review warnings; recognized receipt no-signal and capture/settle errors block. Only the genuine recognized-receipt/no-signal failure is waivable; capture/settle errors are not. Checkout/upsell signals remain whole-journey parity evidence and cannot satisfy a silent receipt. Do not use `next.getCartData().cartLines` as cart-populated proof; use typed-card order read-back, `cart:updated` payload `items` / `summary.lines`, and rendered bundle DOM evidence. Localhost on any port is a Campaigns App Development domain for SDK QA with analytics suppressed; non-localhost preview/production origins still need SDK origin allowlist confirmation. Do not use external browser skills, SDK test-mode events, or direct backend orders as launch proof. Campaigns OS proof is not merchant launch readiness; before launch, confirm production storefront URL, live payment methods, shipping markets, legal/support URLs, analytics expectations, and merchant-side configuration.
18
+
19
+ ## Revising a live campaign
20
+
21
+ 1. Before editing, run `npx --no-install campaigns-os readback .` and
22
+ `npx --no-install campaigns-os next --packet campaign-runtime.build.json`.
23
+ Readback's `evidence_debt` compares the build on disk with the builds Polish and QA were recorded for.
24
+ Changed pages are listed against the recorded assembly build manifest; an owed stage with an empty page list still means evidence is owed.
25
+ 2. For pages built from a provided design, the Design Source Package is the authority, not the punch list's wording.
26
+ 3. Before opening the pull request, after the final edit, rebuild, then run `npx --no-install campaigns-os record build --packet campaign-runtime.build.json`,
27
+ `npx --no-install campaigns-os polish capture --packet campaign-runtime.build.json --base-url <served-current-build-url>` for the whole route,
28
+ and `npx --no-install campaigns-os record polish --packet campaign-runtime.build.json --evidence <polish-evidence.json>`, in that order.
29
+ When QA is owed, run `npx --no-install campaigns-os qa run --packet campaign-runtime.build.json` against that build.
30
+ 4. In the pull request body, put the design reference and the preview of each changed page side by side.
31
+
32
+ The standing pull-request check is `npx --no-install campaigns-os doctor --ci --packet campaign-runtime.build.json --no-live-refs`, report-only unless the repo opts in.
@@ -13,3 +13,18 @@ A NEXT campaign is one connected commerce journey: the pages the CampaignSpec de
13
13
  Do not carry over demo package, shipping, voucher, payment, tracking, footer, or SEO values. Prepared AI/exported HTML must be converted into page-kit-ready source first: keep page-owned body markup, strip document wrappers, add YAML frontmatter, move shared CSS/assets into the campaign structure, and use Liquid helpers only for page-kit links/assets/includes. Preserve prepared landing/presell source HTML when it is a real standalone design. For checkout/upsell/downsell/receipt, use starter-template commerce surfaces as SDK contract references while campaign/source owns visual chrome. Reproduce the source design's own proof and urgency elements as designed (reviews, ratings, stock counters, countdowns, guarantees). They are the merchant's content; Campaigns OS does not review them, so do not remove, soften or flag them. Copy starter template families atomically with dependent pages, `_includes/`, `_layouts/`, `assets/css/`, and `assets/js/`; do not copy only checkout/receipt pages. Emit SDK routing meta tags as campaign-root paths such as `/campaign-slug/upsell/`. Preserve SDK-owned checkout/cart/upsell/receipt surfaces. For `shop-three-step`, shipping is dynamic via `window.next.getShippingMethods()`.
14
14
 
15
15
  Before Polish becomes terminal or hands off to deploy/QA, install the package-owned Playwright browser with `npm run qa:install-browser`, serve the current build, and run `npx --no-install campaigns-os polish capture --packet campaign-runtime.build.json --base-url <served-current-build-url>`. After that checkpoint clears, QA uses the Campaigns OS Node/npm runner: `npx --no-install campaigns-os qa resolve`, then `npx --no-install campaigns-os qa run --browser --test-order common` against the tested URL. Test-order proof uses `npx --no-install campaigns-os qa run --test-order <common|checkout|decline|accept|both|full|explicit-path>` through the tested checkout and rendered upsell controls. `qa run` has no permission flag: coverage is its only control. Test orders still land in the store as real orders (global test cards: no charge, no transaction) that someone may have to cancel. Unless the operator has already said test orders are fine for this campaign, ask once, up front in your first turn with your other setup questions, so the answer covers the whole build and QA and neither stops for it later. `common` runs every actual terminal path when they fit under the flood cap (`--max-test-orders`, 6 by default); above the cap it runs the checkout baseline, first-offer accept and decline, and a deduplicated shortest real receipt path, then adds one decline path per offer or downsell page not yet declined, up to the cap, and names any page left out. A page counts as covered only when an order clicks its decline; the `browser-test-order:upsell-action-coverage` verdict row warns naming each page whose decline no order clicked. `full` walks every actual terminal path in the selected checkout topology; cycles, missing routes, and reachable nonterminals block exhaustive proof before browser launch. The accidental-flood cap remains `6`, and an overflow names the exact explicit `--max-test-orders` raise. Analytics correctness is two-phase: the campaign-root visit inventories declared providers/tags only, and the same canonical typed-card run proves Purchase only from the topology-recognized final receipt document after `--analytics-settle`. Missing/unrecognized receipts are manual-review warnings; recognized receipt no-signal and capture/settle errors block. Only the genuine recognized-receipt/no-signal failure is waivable; capture/settle errors are not. Checkout/upsell signals remain whole-journey parity evidence and cannot satisfy a silent receipt. Do not use `next.getCartData().cartLines` as cart-populated proof; use typed-card order read-back, `cart:updated` payload `items` / `summary.lines`, and rendered bundle DOM evidence. Localhost on any port is a Campaigns App Development domain for SDK QA with analytics suppressed; non-localhost preview/production origins still need SDK origin allowlist confirmation. External browser skills, SDK test-mode events, and direct backend orders are not launch proof. Campaigns OS proof is not merchant launch readiness; before launch, confirm production storefront URL, live payment methods, shipping markets, legal/support URLs, analytics expectations, and merchant-side configuration.
16
+
17
+ ## Revising a live campaign
18
+
19
+ 1. Before editing, run `npx --no-install campaigns-os readback .` and
20
+ `npx --no-install campaigns-os next --packet campaign-runtime.build.json`.
21
+ Readback's `evidence_debt` compares the build on disk with the builds Polish and QA were recorded for.
22
+ Changed pages are listed against the recorded assembly build manifest; an owed stage with an empty page list still means evidence is owed.
23
+ 2. For pages built from a provided design, the Design Source Package is the authority, not the punch list's wording.
24
+ 3. Before opening the pull request, after the final edit, rebuild, then run `npx --no-install campaigns-os record build --packet campaign-runtime.build.json`,
25
+ `npx --no-install campaigns-os polish capture --packet campaign-runtime.build.json --base-url <served-current-build-url>` for the whole route,
26
+ and `npx --no-install campaigns-os record polish --packet campaign-runtime.build.json --evidence <polish-evidence.json>`, in that order.
27
+ When QA is owed, run `npx --no-install campaigns-os qa run --packet campaign-runtime.build.json` against that build.
28
+ 4. In the pull request body, put the design reference and the preview of each changed page side by side.
29
+
30
+ The standing pull-request check is `npx --no-install campaigns-os doctor --ci --packet campaign-runtime.build.json --no-live-refs`, report-only unless the repo opts in.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "package": "@nextcommerce/campaigns-os",
3
- "version": "1.60.0",
3
+ "version": "1.61.0",
4
4
  "status": "developer-preview",
5
5
  "contracts": {
6
6
  "campaign_spec": "4.2-5.0",
@@ -24,42 +24,112 @@
24
24
  "--brand--color--rating-star",
25
25
  "--component--color--outline",
26
26
  "--system-colors--success",
27
- "--system-colors--destructive"
27
+ "--system-colors--destructive",
28
+ "--_text---font-family--heading",
29
+ "--_text---font-family--primary",
30
+ "--radius-size--buttons"
28
31
  ],
29
32
  "source_mappings": {
30
- "--brand-primary": ["--brand--color--primary"],
31
- "--brand-accent": ["--brand--color--accent"],
32
- "--brand-secondary": ["--brand--color--secondary"],
33
- "--surface-bg": ["--brand--color--background"],
34
- "--surface-card": ["--brand--color--surface"],
35
- "--text-primary": ["--brand--color--text-primary", "--brand--color--foreground"],
36
- "--text-secondary": ["--brand--color--text-secondary"],
37
- "--border-default": ["--brand--color--border", "--component--color--outline"],
38
- "--rating-star": ["--brand--color--rating-star"],
39
- "--state-success": ["--system-colors--success"],
40
- "--ui-success": ["--system-colors--success"],
41
- "--state-error": ["--system-colors--destructive"],
42
- "--ui-danger": ["--system-colors--destructive"],
43
- "--brand-cta": ["--brand--color--cta-primary"],
44
- "--cta-primary": ["--brand--color--cta-primary"],
45
- "--button-primary-bg": ["--brand--color--cta-primary"]
33
+ "--brand-primary": [
34
+ "--brand--color--primary"
35
+ ],
36
+ "--brand-accent": [
37
+ "--brand--color--accent"
38
+ ],
39
+ "--brand-secondary": [
40
+ "--brand--color--secondary"
41
+ ],
42
+ "--surface-bg": [
43
+ "--brand--color--background"
44
+ ],
45
+ "--surface-card": [
46
+ "--brand--color--surface"
47
+ ],
48
+ "--text-primary": [
49
+ "--brand--color--text-primary",
50
+ "--brand--color--foreground"
51
+ ],
52
+ "--text-secondary": [
53
+ "--brand--color--text-secondary"
54
+ ],
55
+ "--border-default": [
56
+ "--brand--color--border",
57
+ "--component--color--outline"
58
+ ],
59
+ "--rating-star": [
60
+ "--brand--color--rating-star"
61
+ ],
62
+ "--state-success": [
63
+ "--system-colors--success"
64
+ ],
65
+ "--ui-success": [
66
+ "--system-colors--success"
67
+ ],
68
+ "--state-error": [
69
+ "--system-colors--destructive"
70
+ ],
71
+ "--ui-danger": [
72
+ "--system-colors--destructive"
73
+ ],
74
+ "--brand-cta": [
75
+ "--brand--color--cta-primary"
76
+ ],
77
+ "--cta-primary": [
78
+ "--brand--color--cta-primary"
79
+ ],
80
+ "--button-primary-bg": [
81
+ "--brand--color--cta-primary"
82
+ ]
46
83
  },
47
84
  "derived_mappings": {
48
85
  "--brand-primary": {
49
- "--brand--color--primary-dark": { "method": "mix-black", "amount": 0.18 },
50
- "--brand--color--primary-light": { "method": "mix-white", "amount": 0.2 },
51
- "--brand--color--primary-lighter": { "method": "mix-white", "amount": 0.86 }
86
+ "--brand--color--primary-dark": {
87
+ "method": "mix-black",
88
+ "amount": 0.18
89
+ },
90
+ "--brand--color--primary-light": {
91
+ "method": "mix-white",
92
+ "amount": 0.2
93
+ },
94
+ "--brand--color--primary-lighter": {
95
+ "method": "mix-white",
96
+ "amount": 0.86
97
+ }
52
98
  }
53
99
  },
54
100
  "foreground_derivations": {
55
101
  "description": "Foreground/on-color tokens are derived from the luminance of the background they sit on, never copied blindly from a source --text-inverse token (which defaults to white and renders illegible on a light brand, e.g. white-on-yellow CTAs). Each foreground target picks the first paired background that was mapped and emits the readable choice from foreground_choices. next-core .button/.submit-button render their label with --brand--color--text-inverse, so text-inverse pairs with the CTA background first.",
56
- "foreground_choices": { "dark": "#0a0a0a", "light": "#ffffff" },
102
+ "foreground_choices": {
103
+ "dark": "#0a0a0a",
104
+ "light": "#ffffff"
105
+ },
57
106
  "min_contrast_ratio": 4.5,
58
107
  "derivations": {
59
- "--brand--color--cta-foreground": ["--brand--color--cta-primary"],
60
- "--brand--color--text-inverse": ["--brand--color--cta-primary", "--brand--color--primary"],
61
- "--brand--color--primary-foreground": ["--brand--color--primary"],
62
- "--brand--color--accent-foreground": ["--brand--color--accent"]
108
+ "--brand--color--cta-foreground": [
109
+ "--brand--color--cta-primary"
110
+ ],
111
+ "--brand--color--text-inverse": [
112
+ "--brand--color--cta-primary",
113
+ "--brand--color--primary"
114
+ ],
115
+ "--brand--color--primary-foreground": [
116
+ "--brand--color--primary"
117
+ ],
118
+ "--brand--color--accent-foreground": [
119
+ "--brand--color--accent"
120
+ ]
63
121
  }
122
+ },
123
+ "typography": {
124
+ "description": "Typography targets. Font families are mapped only when the design source ships an @font-face for the family; the faces are written to brand-fonts.css beside brand-theme.css. next-core re-declares the font-family tokens on body inside its 991px, 767px and 479px media queries, so those tokens are emitted on `:root, body` to hold at every width.",
125
+ "targets": {
126
+ "heading_family": "--_text---font-family--heading",
127
+ "body_family": "--_text---font-family--primary",
128
+ "button_radius": "--radius-size--buttons"
129
+ },
130
+ "body_scoped_tokens": [
131
+ "--_text---font-family--heading",
132
+ "--_text---font-family--primary"
133
+ ]
64
134
  }
65
135
  }
@@ -2,8 +2,8 @@
2
2
  "schema_version": "campaign-cart-sdk-support-policy/v0",
3
3
  "provenance": {
4
4
  "source": "NextCommerceCo/campaign-cart release tags",
5
- "latest_known_release": "0.4.42",
6
- "captured_at": "2026-10-09"
5
+ "latest_known_release": "0.4.43",
6
+ "captured_at": "2026-10-22"
7
7
  },
8
8
  "source": "contracts/campaign-cart-sdk-support-policy.v0.json",
9
9
  "minimum_supported": "0.4.20",
@@ -259,6 +259,7 @@
259
259
  "show_apple_pay",
260
260
  "show_google_pay",
261
261
  "show_link",
262
+ "show_shop_pay",
262
263
  "show_affirm",
263
264
  "show_twint",
264
265
  "show_bancontact",
@@ -848,9 +849,9 @@
848
849
  }
849
850
  },
850
851
  "verification": {
851
- "sdk_version": "0.4.42",
852
- "verified_at": "2026-10-16T23:13:26Z",
853
- "evidence": "sdk-0.4.42-2026-10-16.2",
852
+ "sdk_version": "0.4.43",
853
+ "verified_at": "2026-10-21T04:05:46Z",
854
+ "evidence": "sdk-0.4.43-2026-10-21.2",
854
855
  "status": "certified",
855
856
  "source": "template-verification.json"
856
857
  }
@@ -861,7 +862,7 @@
861
862
  "id": "template-reference-apollo",
862
863
  "family": "apollo",
863
864
  "version": "sdk-0.4.38-composable-upsells-2026-09-25",
864
- "source_commit": "ac529485f0a728cf9c6ac8dbcde81041bd1c6ba8",
865
+ "source_commit": "03f5982d703e07f8dc6beaedc121d55093373e4d",
865
866
  "provenance_url": "https://raw.githubusercontent.com/NextCommerceCo/campaign-cart-starter-templates/main/docs/template-references/apollo/README.md",
866
867
  "contract_path": "contracts/commerce-surface-catalog.json",
867
868
  "standard_viewport_refs": [
@@ -1272,9 +1273,9 @@
1272
1273
  }
1273
1274
  },
1274
1275
  "verification": {
1275
- "sdk_version": "0.4.42",
1276
- "verified_at": "2026-10-16T23:13:26Z",
1277
- "evidence": "sdk-0.4.42-2026-10-16.2",
1276
+ "sdk_version": "0.4.43",
1277
+ "verified_at": "2026-10-21T04:05:46Z",
1278
+ "evidence": "sdk-0.4.43-2026-10-21.2",
1278
1279
  "status": "certified",
1279
1280
  "source": "template-verification.json"
1280
1281
  }
@@ -1583,9 +1584,9 @@
1583
1584
  }
1584
1585
  },
1585
1586
  "verification": {
1586
- "sdk_version": "0.4.42",
1587
- "verified_at": "2026-10-16T23:13:26Z",
1588
- "evidence": "sdk-0.4.42-2026-10-16.2",
1587
+ "sdk_version": "0.4.43",
1588
+ "verified_at": "2026-10-21T04:05:46Z",
1589
+ "evidence": "sdk-0.4.43-2026-10-21.2",
1589
1590
  "status": "certified",
1590
1591
  "source": "template-verification.json"
1591
1592
  }
@@ -1886,9 +1887,9 @@
1886
1887
  }
1887
1888
  },
1888
1889
  "verification": {
1889
- "sdk_version": "0.4.42",
1890
- "verified_at": "2026-10-16T23:13:26Z",
1891
- "evidence": "sdk-0.4.42-2026-10-16.2",
1890
+ "sdk_version": "0.4.43",
1891
+ "verified_at": "2026-10-21T04:05:46Z",
1892
+ "evidence": "sdk-0.4.43-2026-10-21.2",
1892
1893
  "status": "certified",
1893
1894
  "source": "template-verification.json"
1894
1895
  }
@@ -2227,9 +2228,9 @@
2227
2228
  }
2228
2229
  },
2229
2230
  "verification": {
2230
- "sdk_version": "0.4.42",
2231
- "verified_at": "2026-10-16T23:13:26Z",
2232
- "evidence": "sdk-0.4.42-2026-10-16.2",
2231
+ "sdk_version": "0.4.43",
2232
+ "verified_at": "2026-10-21T04:05:46Z",
2233
+ "evidence": "sdk-0.4.43-2026-10-21.2",
2233
2234
  "status": "certified",
2234
2235
  "source": "template-verification.json"
2235
2236
  }
@@ -2666,9 +2667,9 @@
2666
2667
  }
2667
2668
  },
2668
2669
  "verification": {
2669
- "sdk_version": "0.4.42",
2670
- "verified_at": "2026-10-16T23:13:26Z",
2671
- "evidence": "sdk-0.4.42-2026-10-16.2",
2670
+ "sdk_version": "0.4.43",
2671
+ "verified_at": "2026-10-21T04:05:46Z",
2672
+ "evidence": "sdk-0.4.43-2026-10-21.2",
2672
2673
  "status": "certified",
2673
2674
  "source": "template-verification.json"
2674
2675
  }
@@ -3022,9 +3023,9 @@
3022
3023
  }
3023
3024
  },
3024
3025
  "verification": {
3025
- "sdk_version": "0.4.42",
3026
- "verified_at": "2026-10-16T23:13:26Z",
3027
- "evidence": "sdk-0.4.42-2026-10-16.2",
3026
+ "sdk_version": "0.4.43",
3027
+ "verified_at": "2026-10-21T04:05:46Z",
3028
+ "evidence": "sdk-0.4.43-2026-10-21.2",
3028
3029
  "status": "certified",
3029
3030
  "source": "template-verification.json"
3030
3031
  }
@@ -3312,9 +3313,9 @@
3312
3313
  }
3313
3314
  },
3314
3315
  "verification": {
3315
- "sdk_version": "0.4.42",
3316
- "verified_at": "2026-10-16T23:13:26Z",
3317
- "evidence": "sdk-0.4.42-2026-10-16.2",
3316
+ "sdk_version": "0.4.43",
3317
+ "verified_at": "2026-10-21T04:05:46Z",
3318
+ "evidence": "sdk-0.4.43-2026-10-21.2",
3318
3319
  "status": "certified",
3319
3320
  "source": "template-verification.json"
3320
3321
  }
@@ -3504,5 +3505,5 @@
3504
3505
  },
3505
3506
  "_synced_from_repo": "NextCommerceCo/campaign-cart-starter-templates",
3506
3507
  "_synced_from_ref": "main",
3507
- "_synced_from_sha": "3987b18a356cb961b06c94b2035622bafe938316"
3508
+ "_synced_from_sha": "b38343e85a05ec2fe949e13e783057d4c717a8d6"
3508
3509
  }