@nextcommerce/campaigns-os 1.47.0 → 1.48.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 (44) hide show
  1. package/CHANGELOG.md +194 -0
  2. package/README.md +30 -3
  3. package/agents/claude/CLAUDE.md +2 -0
  4. package/agents/codex/AGENTS.md +1 -0
  5. package/agents/copilot/copilot-instructions.md +1 -0
  6. package/agents/cursor/campaigns-os.mdc +1 -1
  7. package/compatibility.json +1 -1
  8. package/contracts/commerce-surface-catalog.json +17 -17
  9. package/contracts/release-ledger.json +465 -0
  10. package/contracts/supported-surface.json +1 -1
  11. package/contracts/template-brand-contract.shared-commerce.v0.json +1 -1
  12. package/docs/build-packet.md +1 -1
  13. package/docs/campaign-build-brief.md +25 -28
  14. package/docs/local-setup.md +7 -2
  15. package/docs/orientation-contract-reference.md +1 -1
  16. package/docs/qa-and-test-orders.md +49 -2
  17. package/docs/runtime-readiness.md +1 -1
  18. package/docs/skills-revision.md +10 -10
  19. package/package.json +1 -1
  20. package/skills/campaign-lifecycle-orientation/SKILL.md +3 -3
  21. package/skills/campaign-readback-classification/SKILL.md +3 -3
  22. package/skills/campaign-run-evidence/SKILL.md +9 -4
  23. package/skills/contribution-intake/SKILL.md +3 -3
  24. package/skills/next-campaigns-build/SKILL.md +4 -3
  25. package/skills/next-campaigns-os/SKILL.md +3 -3
  26. package/skills/next-campaigns-os-setup/SKILL.md +3 -3
  27. package/skills/next-campaigns-polish/SKILL.md +4 -4
  28. package/skills/next-campaigns-qa/SKILL.md +3 -3
  29. package/skills.json +10 -10
  30. package/src/cli.mjs +6 -3
  31. package/src/content-residue.mjs +18 -90
  32. package/src/doctor/checks.mjs +21 -29
  33. package/src/doctor/inspect.mjs +13 -3
  34. package/src/doctor/next-step.mjs +4 -0
  35. package/src/gate-actions.mjs +8 -0
  36. package/src/local-preview-policy.mjs +92 -0
  37. package/src/page-kit-sdk-version.mjs +8 -1
  38. package/src/polish-node.mjs +26 -2
  39. package/src/progress-node.mjs +5 -1
  40. package/src/qa-binding-evidence.mjs +1 -1
  41. package/src/qa-browser.mjs +62 -13
  42. package/src/qa-node.mjs +33 -4
  43. package/src/readback.mjs +19 -10
  44. package/src/source-prep.mjs +1 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,200 @@
2
2
 
3
3
  Notable supported-surface changes are recorded here.
4
4
 
5
+ ## [1.48.0] - 2026-10-02
6
+
7
+ ### Changed
8
+
9
+ - The supported surface advances to 1.48.0 and ships the same-surface
10
+ changes recorded since 1.47.0, each described in its own section below:
11
+ the local setup command starts with `npm init -y` (`+agent.1`); the
12
+ `start`, `prepare-build` and `build` usage lines list
13
+ `--deploy-target`, `--preview-url` and `--production-url` (`+agent.6`);
14
+ doctor no longer scans built pages for proof and urgency copy
15
+ (`+agent.7`); QA stops failing the checkout price check on a checkout whose
16
+ cart is filled on an earlier page, and recognises the starter templates'
17
+ SDK loader (`+agent.8`); `readback` shows `warn` and `manual_review` rows as
18
+ themselves, and the agent context sends a resumed session to `readback`
19
+ and `next` first (`+agent.9`); a test order refused as a duplicate says so
20
+ (`+agent.10`); doctor's missing SDK pin message names the SDK the template
21
+ family was verified against (`+agent.11`); the local preview carries
22
+ missing polish and page-load evidence forward as warnings, so a campaign
23
+ built from a starter template can reach a test order (`+agent.12`); and the
24
+ vendored starter-template catalog is pinned to
25
+ campaign-cart-starter-templates `37a8d94` (`+agent.13`).
26
+ - The bundled SDK support policy's `latest_known_release` returns to 0.4.38,
27
+ the value 1.47.0 shipped; `+agent.11` had moved it to 0.4.40. The policy
28
+ line only feeds template freshness, where the catalog's verification
29
+ records already name 0.4.40 as the current SDK, so freshness results and
30
+ doctor's missing SDK pin message are unchanged.
31
+ - Bundled skills carry revision `1.48.0+skills.1`, with each skill version
32
+ advanced one patch, and the local setup install command pins the 1.48.0
33
+ package. The skill text is unchanged.
34
+
35
+ ## [1.47.0+agent.13] - 2026-10-02
36
+
37
+ ### Changed
38
+
39
+ - The vendored starter-template catalog is re-synced to
40
+ campaign-cart-starter-templates `37a8d94` (was `3793b1d`). That brings in
41
+ the single-offer upsell copy priced outside the offer, order bumps that hide
42
+ their savings line and badge when the package has no discount, the
43
+ `is_upsell` wording for order reports, and refreshed template verification
44
+ evidence for Campaign Cart SDK 0.4.40. The verified SDK and the SDK support
45
+ policy are unchanged.
46
+ - `fixtures/certified-families` is regenerated at the new pin, and the shared
47
+ commerce brand contract's payment-chrome `asset_pin` moves with it. The
48
+ shipped asset bytes are unchanged.
49
+
50
+ ## [1.47.0+agent.12] - 2026-10-01
51
+
52
+ ### Changed
53
+
54
+ - On the local preview (a `local-serve` packet served from a loopback host),
55
+ missing polish and page-load evidence no longer stops the loop before a
56
+ typed-card order. One policy, `src/local-preview-policy.mjs`, carries
57
+ forward `polish.evidence_missing` / `polish.report_missing`, a page-load
58
+ checkpoint with no capture recorded, and the new
59
+ `polish.hidden_eager_media.no_capturable_routes` (every mapped page is
60
+ template stock). It also makes starter-template residue a warning when the
61
+ theme gate finds nothing generatable. Doctor reports these as warnings,
62
+ `next` moves past polish, and QA records `warn` rows, so the verdict is at
63
+ best `ready_with_exceptions`. A campaign built from a starter template with
64
+ no design can now reach a toolkit test order locally. Hosted preview and
65
+ production packets, other checks, `record polish` and the waiver commands
66
+ are unchanged. `docs/qa-and-test-orders.md` lists the carried-forward
67
+ checks.
68
+ - An all-template-stock packet's page-load checkpoint now reports
69
+ `polish.hidden_eager_media.no_capturable_routes` instead of the
70
+ malformed-authority `capture_malformed`, and `polish capture` says why it
71
+ has nothing to capture. It still blocks off the local preview, with one
72
+ action: map a page to its design source, or prove on the local preview.
73
+
74
+ ## [1.47.0+agent.11] - 2026-10-01
75
+
76
+ ### Changed
77
+
78
+ - `doctor`'s `page_kit.sdk_version.spec_missing` now names the SDK the
79
+ selected certified template family was last verified against (for
80
+ example `The "apollo" template family was last verified against
81
+ 0.4.40.`), so the CampaignSpec pin is not chosen by searching docs. The
82
+ bundled SDK support policy's `latest_known_release` moves from 0.4.38 to
83
+ 0.4.40, which the catalog's verification records already named.
84
+ - `source_html.prep.document_wrapper` names the two ways to record a
85
+ standalone page as whole: `--wrapper-policy preserve_document_wrappers`
86
+ on `start` or `prepare-build`, or `wrapper_policy` in the source-html
87
+ manifest.
88
+ - `source_html.pages.source_hash` now says the hash it compares is the one
89
+ intake recorded in the Build Packet, that re-running intake with
90
+ `--force` refreshes it (and clears recorded stage evidence), and that
91
+ editing the manifest alone does not. It no longer points at a producer
92
+ script. `docs/build-packet.md` says the same, and that a revision made
93
+ after build belongs under `src/<route>/`.
94
+
95
+ ## [1.47.0+agent.10] - 2026-10-01
96
+
97
+ ### Fixed
98
+
99
+ - A test order the platform refuses as a duplicate now says so. The order
100
+ API puts the reason in `payment_details`, which QA's response capture
101
+ dropped, so the `browser-test-order` row read only
102
+ `order create rejected: HTTP 400`. The capture now keeps a string
103
+ `payment_details` on an error response, and a duplicate-order refusal adds `duplicate_order`
104
+ with the remedy: re-run with a different `--test-email-prefix` (or
105
+ `--test-email`), or wait up to 30 minutes. `docs/qa-and-test-orders.md`
106
+ explains what the platform matches on and why concurrent runs collide.
107
+
108
+ ## [1.47.0+agent.9] - 2026-10-01
109
+
110
+ ### Changed
111
+
112
+ - The agent context `install-agent-context` writes (`agents/claude/CLAUDE.md`,
113
+ `agents/codex/AGENTS.md`, `agents/copilot/copilot-instructions.md`,
114
+ `agents/cursor/campaigns-os.mdc`) now tells a session picking up an
115
+ existing campaign to run `readback` and `next` before reading artifacts by
116
+ hand. It also says the committed `.campaign-runtime/qa-verdict.json` keeps
117
+ no order records or URLs, so its `browser-test-order:<path>` assertions are
118
+ the typed-card proof. A resumed session had read the sidecar's empty
119
+ `test_orders` as "no test orders" after five verified orders.
120
+ - The `campaign-run-evidence` skill says the same: the sidecar always
121
+ empties `test_orders` and the URL fields, so an empty `test_orders` there
122
+ says nothing about ordering. Bundled skills carry revision
123
+ `1.47.0+skills.3`, with each skill version advanced two patches from
124
+ `1.47.0+skills.1`.
125
+
126
+ ### Fixed
127
+
128
+ - `readback` shows `warn` and `manual_review` assertions as the verdict
129
+ statuses they are, with their severity, recorded `actual` and evidence
130
+ problems (as it does for `fail` rows), instead of counting them as
131
+ "unrecognized status".
132
+
133
+ ## [1.47.0+agent.8] - 2026-10-01
134
+
135
+ ### Fixed
136
+
137
+ - `qa run` no longer fails `pricing.checkout_price_visible` on a checkout
138
+ whose cart is filled on an earlier page. When QA opens such a checkout
139
+ directly, the SDK cart is empty and the page has no package selection of its
140
+ own, so no price can show. The row is now `skipped` with that reason and
141
+ records `cart_count` and `checkout_selection_surface`. The test order
142
+ already enters that cart from the landing page. A checkout with its own
143
+ package selection, or a filled cart, still fails when no price shows.
144
+ - The page-binding check recognises `campaign-cart@<tag>/dist/loader.js`, the
145
+ SDK loader the starter templates use, and no longer tries to fetch it as a
146
+ cross-origin config script. Starter-template pages now report
147
+ `dynamic_unresolved` instead of `script_unavailable_or_limit`; they still
148
+ need manual review, because the static reader cannot prove a binding on a
149
+ page that runs other scripts.
150
+
151
+ ## [1.47.0+agent.7] - 2026-10-01
152
+
153
+ ### Removed
154
+
155
+ - `doctor` no longer scans built pages for proof and urgency copy. The
156
+ `content_residue.anti_pattern` warning (review counts, "Verified Purchase"
157
+ labels, stock and sell-out lines, expert and press mentions) is gone, and so
158
+ is `content_residue.urgency_unattested`, which asked a campaign without a
159
+ brief payload to confirm its countdown was real. That copy belongs to the
160
+ merchant, and agents read the warnings as a reason to strip it from the
161
+ merchant's own designs. Template demo residue, the needs-merchant-input
162
+ marker, the discount-claim warnings and the brief-backed urgency and proof
163
+ attestation gates are unchanged.
164
+
165
+ ### Changed
166
+
167
+ - The `next-campaigns-build` and `next-campaigns-polish` skills now say to
168
+ reproduce the source design's own proof and urgency elements (reviews,
169
+ "Verified Purchase" labels, recent-purchase popups, stock counters,
170
+ countdowns, guarantees) as designed, and not to record them as polish
171
+ issues. `docs/campaign-build-brief.md` says the same. Bundled skills carry
172
+ revision `1.47.0+skills.2`, with each skill version advanced one patch.
173
+
174
+ ## [1.47.0+agent.6] - 2026-10-01
175
+
176
+ ### Changed
177
+
178
+ - The usage lines for `start`, `prepare-build` and `build` now list
179
+ `--deploy-target <target>`, `--preview-url <url>` and
180
+ `--production-url <url>`. Intake has always written them to the Build
181
+ Packet's `deploy` block (`deploy.target` defaults to `unknown`), and
182
+ `docs/build-packet.md`, the README and the Start page already pass
183
+ `--deploy-target local-serve` to `start`, but the help text left them out,
184
+ so an agent checking that command against the help read it as
185
+ unsupported. Behaviour is unchanged.
186
+
187
+ ## [1.47.0+agent.1] - 2026-10-01
188
+
189
+ ### Fixed
190
+
191
+ - The one-line setup command in `docs/local-setup.md` now starts with
192
+ `npm init -y`. Without a `package.json` in the campaign folder, npm installs
193
+ into the nearest parent folder that has a `package.json` or `node_modules`,
194
+ so a campaign folder created inside another project added page-kit and the
195
+ toolkit to that project instead of the campaign. The README and quickstart
196
+ installs already started with `npm init -y`; a test now holds all three to
197
+ it.
198
+
5
199
  ## [1.47.0] - 2026-10-01
6
200
 
7
201
  ### Changed
package/README.md CHANGED
@@ -11,8 +11,8 @@ This toolkit gives campaign developers and AI coding tools a clear path for asse
11
11
  5. Provide or generate a [Campaign Build Brief](./docs/campaign-build-brief.md) for merchandising/design presentation decisions.
12
12
  6. Create and doctor a Build Packet.
13
13
  7. Hand off to `next-campaigns-build`.
14
- 8. Run build/lint, then install the Campaigns OS Playwright browser once with `campaigns-os qa install-browser`.
15
- 9. Run `next-campaigns-polish`, serve the current build, and run the mandatory `campaigns-os polish capture` producer before marking Polish complete.
14
+ 8. Run build/lint and record the build with `campaigns-os record build`, then install the Campaigns OS Playwright browser once with `campaigns-os qa install-browser`.
15
+ 9. Run `next-campaigns-polish`, serve the current build, run the mandatory `campaigns-os polish capture` producer, then record Polish with `campaigns-os record polish --evidence <file>`.
16
16
  10. Deploy a preview.
17
17
  11. Run `next-campaigns-qa` against the tested URL.
18
18
  12. Record launch blockers and follow-up work.
@@ -53,6 +53,15 @@ npx --no-install campaigns-os install-skills --platform claude
53
53
  mkdir -p source
54
54
  ```
55
55
 
56
+ With Claude Code, [local setup](docs/local-setup.md) replaces the last two
57
+ lines with one: `npx --no-install campaigns-os tooling setup --target .
58
+ --platform claude` installs the QA browser, the skills and the project
59
+ context, and keeps existing pages and instructions. It does not scaffold
60
+ pages; the agent chooses the template at intake. Codex, Cursor and other
61
+ agents keep the separate steps: `install-skills --platform codex` (or
62
+ `--platform agents`), `install-agent-context --target .` and
63
+ `qa install-browser`.
64
+
56
65
  The toolkit is also published to npm as `@nextcommerce/campaigns-os`, so the
57
66
  CLI can be installed once, globally, instead of pinned per campaign:
58
67
 
@@ -126,7 +135,10 @@ npx --no-install campaigns-os next --packet ./campaign-runtime.build.json --json
126
135
  `--proxy-base <origin>` when the map was saved on a non-production map store);
127
136
  `--spec <campaignspec.json>` starts from a local export or an agent-authored
128
137
  [local spec](docs/build-packet.md#local-spec-entry) instead. Local-spec identity
129
- requires a reviewed 1.43.0-or-later release. `--source` is
138
+ requires a reviewed 1.43.0-or-later release. To prove the campaign on
139
+ localhost before a preview deploy, add `--deploy-target local-serve` (and
140
+ `--preview-url http://localhost:<port>/`); `qa policy set --deploy-target <target>`
141
+ changes it later. `--source` is
130
142
  always required: the folder of prepared HTML/CSS/assets for the pages you are
131
143
  building, with a source manifest that carries desktop and mobile screenshot
132
144
  proof for each designed page
@@ -267,21 +279,28 @@ Before an SDK bump, scan explicitly scoped tracked merchant HTML/JS with [SDK st
267
279
 
268
280
  ```bash
269
281
  npm run campaigns-os -- tooling status
282
+ npm run campaigns-os -- tooling setup --target <page-kit-repo> --platform claude --dry-run --json
270
283
  npm run campaigns-os -- install-skills --dry-run
271
284
  npm run campaigns-os -- install-skills --platform codex --dry-run
285
+ npm run campaigns-os -- install-agent-context --target <page-kit-repo> --dry-run
272
286
  npm run campaigns-os -- qa install-browser
273
287
  npm run skills -- status
274
288
  npm run campaigns-os -- prepare-build --spec <spec.json> --source <html-dir> --target <page-kit-repo> --template-family <family> --brief <campaign-build-brief.yaml>
275
289
  npm run campaigns-os -- doctor --packet <page-kit-repo>/campaign-runtime.build.json
290
+ npm run campaigns-os -- page-kit sync --packet <page-kit-repo>/campaign-runtime.build.json --dry-run
291
+ npm run campaigns-os -- checkpoint waive --packet <packet.json> --gate source_html.producer_provenance --page <page_id> --reason "<why>" --waived-by "<named human>" --review-condition "<trigger>" --dry-run
276
292
  npm run campaigns-os -- sdk storage-check --target <campaign-git-root> --target-sdk 0.4.38 --manifest <sdk-storage-manifest.json> --scope <campaign,shared> --json
277
293
  npm run campaigns-os -- standardize --target <page-kit-repo-or-cpk-repo> --json
278
294
  npm run campaigns-os -- theme inspect --packet <page-kit-repo>/campaign-runtime.build.json --json
279
295
  npm run campaigns-os -- theme generate --packet <page-kit-repo>/campaign-runtime.build.json --json
280
296
  npm run campaigns-os -- next setup --packet <page-kit-repo>/campaign-runtime.build.json
281
297
  npm run campaigns-os -- next build --packet <page-kit-repo>/campaign-runtime.build.json
298
+ npm run campaigns-os -- record setup --packet <page-kit-repo>/campaign-runtime.build.json
299
+ npm run campaigns-os -- record build --packet <page-kit-repo>/campaign-runtime.build.json
282
300
  npm run qa:install-browser
283
301
  npm run campaigns-os -- next polish --packet <packet.json> --report <assembly-report.json>
284
302
  npm run campaigns-os -- polish capture --packet <packet.json> --base-url <served-current-build-url>
303
+ npm run campaigns-os -- record polish --packet <packet.json> --evidence <polish-evidence.json>
285
304
  npm run campaigns-os -- next qa --packet <packet.json> --report <assembly-report.json>
286
305
  npm run campaigns-os -- qa resolve --packet <packet.json>
287
306
  npm run campaigns-os -- qa run --packet <packet.json> --base-url <preview-url> --browser --test-order common
@@ -298,6 +317,14 @@ only when deliberately recording a new doctor stage. `--no-write` overrides
298
317
  `--write`. A custom `--doctor-out <path>` also requires `--write`; naming an
299
318
  output path alone does not create or refresh the file. Build/QA producer
300
319
  commands continue to record their own stages.
320
+
321
+ Record a stage's completion with `record setup`, `record build` (after every
322
+ rebuild) and `record polish --evidence <file>` rather than hand-editing
323
+ `.campaign-runtime/build-context.json` or `.campaign-runtime/assembly-report.json`.
324
+ Each validates what it would write, refuses a stage `next` has not reached, and
325
+ writes nothing on failure; `--dry-run` runs the checks without writing. See
326
+ [Build Packet](docs/build-packet.md) and [Polish evidence](docs/polish-evidence.md).
327
+
301
328
  Do not use `prepare-build --force` merely to refresh a catalog path: doctor
302
329
  already resolves the running toolkit's catalog, and force clears stage evidence.
303
330
 
@@ -6,6 +6,8 @@ Packet exists, read it and follow `next`. Check the loaded skill's bundle
6
6
  revision and restart the session if it differs from the
7
7
  project copy. Do not use private runtime source as the campaign's starting point.
8
8
 
9
+ To pick up an existing campaign, run `campaigns-os readback .` and `campaigns-os next --packet campaign-runtime.build.json` before reading artifacts by hand; `next` blocks polish and QA again whenever the built output changes. The committed `.campaign-runtime/qa-verdict.json` keeps no order records or URLs: its `browser-test-order:<path>` assertions are the typed-card proof, and the full verdict is under `qa-output/`.
10
+
9
11
  Core rules:
10
12
 
11
13
  - Treat CampaignSpec as campaign intent and the Campaigns API as live commerce truth.
@@ -3,6 +3,7 @@
3
3
  Use this context when working in a target campaign repo with Campaigns OS artifacts.
4
4
 
5
5
  - Read `campaign-runtime.build.json` first.
6
+ - To pick up an existing campaign, run `campaigns-os readback .` and `campaigns-os next --packet campaign-runtime.build.json` before reading artifacts by hand; `next` blocks polish and QA again whenever the built output changes. The committed `.campaign-runtime/qa-verdict.json` keeps no order records or URLs: its `browser-test-order:<path>` assertions are the typed-card proof, and the full verdict is under `qa-output/`.
6
7
  - If `.campaign-runtime/build-context.json` or `.campaign-runtime/assembly-report.json` exists, read them before editing campaign files.
7
8
  - Run `campaigns-os doctor --packet campaign-runtime.build.json` before build work.
8
9
  - Treat CampaignSpec validation as owned by the public `@nextcommerce/campaigns-os/campaign-spec` rules surfaced through doctor `spec.validation` findings; use structured rule/path detail when available.
@@ -5,6 +5,7 @@ When this repository contains Campaigns OS artifacts, use them as the build hand
5
5
  - `campaign-runtime.build.json` defines the CampaignSpec, source adapter, target output, template family, deploy target, SDK origin state, and QA proof depth.
6
6
  - `.campaign-runtime/build-context.json` records page mappings and setup/build handoff details.
7
7
  - `.campaign-runtime/assembly-report.json` records stage evidence and blockers.
8
+ - To pick up an existing campaign, run `campaigns-os readback .` and `campaigns-os next --packet campaign-runtime.build.json` before reading artifacts by hand; `next` blocks polish and QA again whenever the built output changes. The committed `.campaign-runtime/qa-verdict.json` keeps no order records or URLs: its `browser-test-order:<path>` assertions are the typed-card proof, and the full verdict is under `qa-output/`.
8
9
  - `.campaign-runtime/theme/theme-report.json`, when present, is optional brand-theme evidence. Generated `brand-theme.css` must load after `next-core.css`; missing or low-confidence theme is a warning/skipped reason, not permission to edit SDK-owned runtime surfaces.
9
10
 
10
11
  CampaignSpec validation is owned by the public `@nextcommerce/campaigns-os/campaign-spec` rules surfaced through doctor `spec.validation` findings; use structured rule/path detail when available.
@@ -6,7 +6,7 @@ globs:
6
6
  alwaysApply: false
7
7
  ---
8
8
 
9
- Read Campaigns OS artifacts before editing campaign pages. Treat CampaignSpec/API values as live commerce truth, starter-template contracts as SDK surface truth, and designed HTML/assets as visual/content intent. Treat CampaignSpec validation as owned by the public `@nextcommerce/campaigns-os/campaign-spec` rules surfaced through doctor `spec.validation` findings; use structured rule/path detail when available. If `context.theme` or `.campaign-runtime/theme/theme-report.json` exists, use it as optional brand-theme evidence; generated `brand-theme.css` must load after `next-core.css`, and missing/low-confidence theme is a warning or skipped reason, not permission to edit SDK-owned runtime surfaces.
9
+ Read Campaigns OS artifacts before editing campaign pages. To pick up an existing campaign, run `campaigns-os readback .` and `campaigns-os next --packet campaign-runtime.build.json` before reading artifacts by hand; `next` blocks polish and QA again whenever the built output changes. The committed `.campaign-runtime/qa-verdict.json` keeps no order records or URLs: its `browser-test-order:<path>` assertions are the typed-card proof, and the full verdict is under `qa-output/`. Treat CampaignSpec/API values as live commerce truth, starter-template contracts as SDK surface truth, and designed HTML/assets as visual/content intent. Treat CampaignSpec validation as owned by the public `@nextcommerce/campaigns-os/campaign-spec` rules surfaced through doctor `spec.validation` findings; use structured rule/path detail when available. If `context.theme` or `.campaign-runtime/theme/theme-report.json` exists, use it as optional brand-theme evidence; generated `brand-theme.css` must load after `next-core.css`, and missing/low-confidence theme is a warning or skipped reason, not permission to edit SDK-owned runtime surfaces.
10
10
 
11
11
  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. 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()`.
12
12
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "package": "@nextcommerce/campaigns-os",
3
- "version": "1.47.0",
3
+ "version": "1.48.0",
4
4
  "status": "developer-preview",
5
5
  "contracts": {
6
6
  "campaign_spec": "4.2-4.3",
@@ -849,8 +849,8 @@
849
849
  },
850
850
  "verification": {
851
851
  "sdk_version": "0.4.40",
852
- "verified_at": "2026-10-01T04:56:01Z",
853
- "evidence": "sdk-0.4.40-2026-10-01",
852
+ "verified_at": "2026-10-01T16:01:10Z",
853
+ "evidence": "sdk-0.4.40-2026-10-01.2",
854
854
  "status": "certified",
855
855
  "source": "template-verification.json"
856
856
  }
@@ -1273,8 +1273,8 @@
1273
1273
  },
1274
1274
  "verification": {
1275
1275
  "sdk_version": "0.4.40",
1276
- "verified_at": "2026-10-01T04:56:01Z",
1277
- "evidence": "sdk-0.4.40-2026-10-01",
1276
+ "verified_at": "2026-10-01T16:01:10Z",
1277
+ "evidence": "sdk-0.4.40-2026-10-01.2",
1278
1278
  "status": "certified",
1279
1279
  "source": "template-verification.json"
1280
1280
  }
@@ -1584,8 +1584,8 @@
1584
1584
  },
1585
1585
  "verification": {
1586
1586
  "sdk_version": "0.4.40",
1587
- "verified_at": "2026-10-01T04:56:01Z",
1588
- "evidence": "sdk-0.4.40-2026-10-01",
1587
+ "verified_at": "2026-10-01T16:01:10Z",
1588
+ "evidence": "sdk-0.4.40-2026-10-01.2",
1589
1589
  "status": "certified",
1590
1590
  "source": "template-verification.json"
1591
1591
  }
@@ -1887,8 +1887,8 @@
1887
1887
  },
1888
1888
  "verification": {
1889
1889
  "sdk_version": "0.4.40",
1890
- "verified_at": "2026-10-01T04:56:01Z",
1891
- "evidence": "sdk-0.4.40-2026-10-01",
1890
+ "verified_at": "2026-10-01T16:01:10Z",
1891
+ "evidence": "sdk-0.4.40-2026-10-01.2",
1892
1892
  "status": "certified",
1893
1893
  "source": "template-verification.json"
1894
1894
  }
@@ -2228,8 +2228,8 @@
2228
2228
  },
2229
2229
  "verification": {
2230
2230
  "sdk_version": "0.4.40",
2231
- "verified_at": "2026-10-01T04:56:01Z",
2232
- "evidence": "sdk-0.4.40-2026-10-01",
2231
+ "verified_at": "2026-10-01T16:01:10Z",
2232
+ "evidence": "sdk-0.4.40-2026-10-01.2",
2233
2233
  "status": "certified",
2234
2234
  "source": "template-verification.json"
2235
2235
  }
@@ -2667,8 +2667,8 @@
2667
2667
  },
2668
2668
  "verification": {
2669
2669
  "sdk_version": "0.4.40",
2670
- "verified_at": "2026-10-01T04:56:01Z",
2671
- "evidence": "sdk-0.4.40-2026-10-01",
2670
+ "verified_at": "2026-10-01T16:01:10Z",
2671
+ "evidence": "sdk-0.4.40-2026-10-01.2",
2672
2672
  "status": "certified",
2673
2673
  "source": "template-verification.json"
2674
2674
  }
@@ -3024,8 +3024,8 @@
3024
3024
  },
3025
3025
  "verification": {
3026
3026
  "sdk_version": "0.4.40",
3027
- "verified_at": "2026-10-01T04:56:01Z",
3028
- "evidence": "sdk-0.4.40-2026-10-01",
3027
+ "verified_at": "2026-10-01T16:01:10Z",
3028
+ "evidence": "sdk-0.4.40-2026-10-01.2",
3029
3029
  "status": "certified",
3030
3030
  "source": "template-verification.json"
3031
3031
  }
@@ -3314,8 +3314,8 @@
3314
3314
  },
3315
3315
  "verification": {
3316
3316
  "sdk_version": "0.4.40",
3317
- "verified_at": "2026-10-01T04:56:01Z",
3318
- "evidence": "sdk-0.4.40-2026-10-01",
3317
+ "verified_at": "2026-10-01T16:01:10Z",
3318
+ "evidence": "sdk-0.4.40-2026-10-01.2",
3319
3319
  "status": "certified",
3320
3320
  "source": "template-verification.json"
3321
3321
  }
@@ -3525,5 +3525,5 @@
3525
3525
  },
3526
3526
  "_synced_from_repo": "NextCommerceCo/campaign-cart-starter-templates",
3527
3527
  "_synced_from_ref": "main",
3528
- "_synced_from_sha": "3793b1de3b77cc31dffe9176f47e8e99ea6134aa"
3528
+ "_synced_from_sha": "37a8d945db4c360739ded98348814cfd632da94f"
3529
3529
  }