@nextcommerce/campaigns-os 1.47.0 → 1.50.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 (53) hide show
  1. package/CHANGELOG.md +307 -0
  2. package/README.md +30 -3
  3. package/agents/claude/CLAUDE.md +6 -3
  4. package/agents/codex/AGENTS.md +6 -4
  5. package/agents/copilot/copilot-instructions.md +3 -2
  6. package/agents/cursor/campaigns-os.mdc +3 -3
  7. package/compatibility.json +1 -1
  8. package/contracts/commerce-surface-catalog.json +17 -17
  9. package/contracts/effects.v1.json +173 -0
  10. package/contracts/release-ledger.json +798 -0
  11. package/contracts/supported-surface.json +4 -4
  12. package/contracts/template-brand-contract.shared-commerce.v0.json +1 -1
  13. package/docs/brand-theme-bridge.md +12 -6
  14. package/docs/build-packet.md +9 -4
  15. package/docs/campaign-build-brief.md +25 -28
  16. package/docs/local-setup.md +7 -2
  17. package/docs/orientation-contract-reference.md +1 -1
  18. package/docs/qa-and-test-orders.md +70 -9
  19. package/docs/runtime-readiness.md +1 -1
  20. package/docs/skills-revision.md +10 -10
  21. package/package.json +1 -1
  22. package/schemas/campaign-runtime-build-packet.v0.schema.json +4 -0
  23. package/schemas/campaigns-os-qa-verdict.v0.schema.json +8 -3
  24. package/skills/campaign-lifecycle-orientation/SKILL.md +3 -3
  25. package/skills/campaign-readback-classification/SKILL.md +3 -3
  26. package/skills/campaign-run-evidence/SKILL.md +9 -4
  27. package/skills/contribution-intake/SKILL.md +3 -3
  28. package/skills/next-campaigns-build/SKILL.md +5 -4
  29. package/skills/next-campaigns-os/SKILL.md +3 -3
  30. package/skills/next-campaigns-os-setup/SKILL.md +3 -3
  31. package/skills/next-campaigns-polish/SKILL.md +6 -5
  32. package/skills/next-campaigns-qa/SKILL.md +3 -3
  33. package/skills.json +10 -10
  34. package/src/brand-theme.mjs +13 -2
  35. package/src/cli.mjs +17 -12
  36. package/src/content-residue.mjs +18 -90
  37. package/src/doctor/checks.mjs +21 -29
  38. package/src/doctor/inspect.mjs +13 -3
  39. package/src/doctor/next-step.mjs +4 -0
  40. package/src/gate-actions.mjs +8 -0
  41. package/src/install-mode.mjs +0 -8
  42. package/src/invocation.mjs +3 -1
  43. package/src/local-preview-policy.mjs +92 -0
  44. package/src/page-kit-sdk-version.mjs +8 -1
  45. package/src/polish-node.mjs +26 -2
  46. package/src/progress-node.mjs +5 -1
  47. package/src/qa-binding-evidence.mjs +22 -1
  48. package/src/qa-browser.mjs +92 -14
  49. package/src/qa-node.mjs +43 -6
  50. package/src/readback.mjs +19 -10
  51. package/src/source-prep.mjs +1 -1
  52. package/src/stage-record.mjs +303 -22
  53. package/src/theme-gate.mjs +3 -3
package/CHANGELOG.md CHANGED
@@ -2,6 +2,313 @@
2
2
 
3
3
  Notable supported-surface changes are recorded here.
4
4
 
5
+ ## [1.50.0] - 2026-10-02
6
+
7
+ ### Changed
8
+
9
+ - With `qa run --browser`, each page's `page-binding:<page_id>` row comes
10
+ from the key the Campaign Cart SDK actually sent. The SDK sends the page's
11
+ key as `Authorization` on every Campaigns API request. The browser pass
12
+ reads that header on each page it loads, compares it with the expected key
13
+ in memory and keeps only the outcome: `match` (pass) when every request
14
+ carried the expected key, `mismatch` (blocker) when any carried another.
15
+ The key itself is never recorded. The static read of a page's declarations
16
+ could not resolve most real pages: the starter templates' `config.js` opens
17
+ with `window.dataLayer = window.dataLayer || []` and
18
+ `window.nextReady = window.nextReady || []`, which the static grammar treats
19
+ as dynamic, so every starter page was left for manual review, and inline
20
+ scripts, `async` scripts and scripts from other origins left other pages
21
+ the same way. A page that sends no Campaigns API request, a run with no
22
+ single expected key, and `qa run` without `--browser` keep the static read.
23
+ - The QA verdict schema's page-binding evidence accepts
24
+ `observation: "sdk_request"` and the `sdk_request` source kind for that row.
25
+ Nothing is removed, so every verdict that validated before still does.
26
+ `docs/qa-and-test-orders.md` describes both observations.
27
+ - Ships the same-surface changes recorded since 1.49.0, each described in
28
+ its own section below: the agent context spells every command
29
+ `npx --no-install campaigns-os …` and carries the build skill's proof rule
30
+ (`+agent.1`); and the install-mode module drops a stale comment, with no
31
+ behavior change (`+agent.2`).
32
+ - Package and supported-surface version advance to 1.50.0 for the QA verdict
33
+ schema hash. The local setup install command pins 1.50.0. Bundled skills
34
+ carry revision `1.50.0+skills.1`, with each skill version advanced one
35
+ patch. The skill text is unchanged.
36
+
37
+ ## [1.49.0+agent.2] - 2026-10-02
38
+
39
+ ### Changed
40
+
41
+ - No command behaves differently. The install-mode module drops a trailing
42
+ comment that described `applyInvocationPrefix`, a function removed when
43
+ commands began to be spelled with their prefix at the source (`cmd()` and
44
+ `asInvocation` in the install-invocation module). Comment-only; every
45
+ message and every exit code is unchanged.
46
+
47
+ ## [1.49.0+agent.1] - 2026-10-02
48
+
49
+ ### Changed
50
+
51
+ - The agent context that `install-agent-context` and `tooling setup` write
52
+ (`agents/claude/CLAUDE.md`, `agents/codex/AGENTS.md`,
53
+ `agents/copilot/copilot-instructions.md`, `agents/cursor/campaigns-os.mdc`)
54
+ spells every command `npx --no-install campaigns-os …`, as the skills and
55
+ `AGENTS.md` do. It said `campaigns-os readback .`, `campaigns-os qa run …`
56
+ and so on, and fresh sessions ran them as written: "command not found"
57
+ where nothing is installed globally, and an older global copy instead of
58
+ the campaign's pinned one where something is. A test keeps bare commands
59
+ out of the agent context.
60
+ - The agent context carries the build skill's proof rule: reproduce the
61
+ source design's own proof and urgency elements as designed, and do not
62
+ remove, soften or flag them. The rule was only in the build and polish
63
+ skills, and sessions were still questioning or removing the merchant's
64
+ proof.
65
+ - An installed copy keeps the old text until `install-agent-context`
66
+ refreshes it.
67
+
68
+ ## [1.49.0] - 2026-10-02
69
+
70
+ ### Added
71
+
72
+ - `campaigns-os record theme --packet <p>` records an applied brand layer on
73
+ the Assembly Report, where the theme gate previously sent the operator to
74
+ edit `report.theme` by hand. It reads each built commerce page's stylesheet
75
+ links in document order. A page that loads `next-core.css` must load
76
+ `brand-theme.css` (or `checkout-brand.css`) after it, and that file must be
77
+ in the built output. A page that loads neither renders the design's own
78
+ markup and is left out, noted in the evidence. When every page passes and at
79
+ least one loads the brand layer, it writes `report.theme`: status `applied`,
80
+ `load_order` `after-next-core`, `css_path`, `commerce_pages` and one evidence
81
+ line per page, and clears any earlier theme waiver. Otherwise it is refused,
82
+ naming each page, and writes nothing. Build must be recorded for the current
83
+ output first. `--dry-run` runs every check and writes nothing.
84
+ - `campaigns-os record deploy --packet <p> --base-url <url>` records a local
85
+ preview (`deploy.target: local-serve`), where `next` previously sent the
86
+ operator to edit the packet and `stages.deploy` by hand. The URL must be a
87
+ loopback origin naming the campaign's route root. Every built page is
88
+ requested under it and must answer 2xx. It then writes the packet's
89
+ `deploy.preview_url` and `stages.deploy` completed, with the URL in
90
+ `outputs` and one evidence line per page. It is refused, writing nothing,
91
+ when any check fails, when polish is not recorded, when the built output
92
+ changed since build was recorded, or while the theme gate is blocked. The
93
+ requests stay on this machine. `--dry-run` runs every check, the requests
94
+ included, and writes nothing.
95
+
96
+ ### Changed
97
+
98
+ - The theme gate's apply and load-order actions, the starter-palette notice,
99
+ the build prompt, the build and polish skills, `docs/brand-theme-bridge.md`
100
+ and `docs/build-packet.md` name `record theme` where they described a hand
101
+ edit of `report.theme`.
102
+ - `next`'s local-serve deploy action and deploy prompt,
103
+ `docs/build-packet.md` and `docs/qa-and-test-orders.md` name `record deploy`
104
+ where they described a hand edit of `deploy.preview_url` and
105
+ `stages.deploy`.
106
+ - `contracts/effects.v1.json` declares `record theme`, `record deploy` and
107
+ their `--dry-run` forms.
108
+ - The Build Packet schema's `assembly.template_family` accepts every family
109
+ the commerce surface catalog and the private template sources name:
110
+ `apollo`, `apollo-mv-single-step`, `arjuna` and `karna` join the enum, which
111
+ had fallen behind both. Nothing is removed, so every packet that validated
112
+ before still does.
113
+ - Package and supported-surface version advance to 1.49.0 for the effects
114
+ contract and Build Packet schema hashes. The local setup install command pins 1.49.0. Bundled skills
115
+ carry revision `1.49.0+skills.1`, with each skill version advanced one patch;
116
+ the build and polish skills also name `record theme`.
117
+
118
+ ## [1.48.0] - 2026-10-02
119
+
120
+ ### Changed
121
+
122
+ - The supported surface advances to 1.48.0 and ships the same-surface
123
+ changes recorded since 1.47.0, each described in its own section below:
124
+ the local setup command starts with `npm init -y` (`+agent.1`); the
125
+ `start`, `prepare-build` and `build` usage lines list
126
+ `--deploy-target`, `--preview-url` and `--production-url` (`+agent.6`);
127
+ doctor no longer scans built pages for proof and urgency copy
128
+ (`+agent.7`); QA stops failing the checkout price check on a checkout whose
129
+ cart is filled on an earlier page, and recognises the starter templates'
130
+ SDK loader (`+agent.8`); `readback` shows `warn` and `manual_review` rows as
131
+ themselves, and the agent context sends a resumed session to `readback`
132
+ and `next` first (`+agent.9`); a test order refused as a duplicate says so
133
+ (`+agent.10`); doctor's missing SDK pin message names the SDK the template
134
+ family was verified against (`+agent.11`); the local preview carries
135
+ missing polish and page-load evidence forward as warnings, so a campaign
136
+ built from a starter template can reach a test order (`+agent.12`); and the
137
+ vendored starter-template catalog is pinned to
138
+ campaign-cart-starter-templates `37a8d94` (`+agent.13`).
139
+ - The bundled SDK support policy's `latest_known_release` returns to 0.4.38,
140
+ the value 1.47.0 shipped; `+agent.11` had moved it to 0.4.40. The policy
141
+ line only feeds template freshness, where the catalog's verification
142
+ records already name 0.4.40 as the current SDK, so freshness results and
143
+ doctor's missing SDK pin message are unchanged.
144
+ - Bundled skills carry revision `1.48.0+skills.1`, with each skill version
145
+ advanced one patch, and the local setup install command pins the 1.48.0
146
+ package. The skill text is unchanged.
147
+
148
+ ## [1.47.0+agent.13] - 2026-10-02
149
+
150
+ ### Changed
151
+
152
+ - The vendored starter-template catalog is re-synced to
153
+ campaign-cart-starter-templates `37a8d94` (was `3793b1d`). That brings in
154
+ the single-offer upsell copy priced outside the offer, order bumps that hide
155
+ their savings line and badge when the package has no discount, the
156
+ `is_upsell` wording for order reports, and refreshed template verification
157
+ evidence for Campaign Cart SDK 0.4.40. The verified SDK and the SDK support
158
+ policy are unchanged.
159
+ - `fixtures/certified-families` is regenerated at the new pin, and the shared
160
+ commerce brand contract's payment-chrome `asset_pin` moves with it. The
161
+ shipped asset bytes are unchanged.
162
+
163
+ ## [1.47.0+agent.12] - 2026-10-01
164
+
165
+ ### Changed
166
+
167
+ - On the local preview (a `local-serve` packet served from a loopback host),
168
+ missing polish and page-load evidence no longer stops the loop before a
169
+ typed-card order. One policy, `src/local-preview-policy.mjs`, carries
170
+ forward `polish.evidence_missing` / `polish.report_missing`, a page-load
171
+ checkpoint with no capture recorded, and the new
172
+ `polish.hidden_eager_media.no_capturable_routes` (every mapped page is
173
+ template stock). It also makes starter-template residue a warning when the
174
+ theme gate finds nothing generatable. Doctor reports these as warnings,
175
+ `next` moves past polish, and QA records `warn` rows, so the verdict is at
176
+ best `ready_with_exceptions`. A campaign built from a starter template with
177
+ no design can now reach a toolkit test order locally. Hosted preview and
178
+ production packets, other checks, `record polish` and the waiver commands
179
+ are unchanged. `docs/qa-and-test-orders.md` lists the carried-forward
180
+ checks.
181
+ - An all-template-stock packet's page-load checkpoint now reports
182
+ `polish.hidden_eager_media.no_capturable_routes` instead of the
183
+ malformed-authority `capture_malformed`, and `polish capture` says why it
184
+ has nothing to capture. It still blocks off the local preview, with one
185
+ action: map a page to its design source, or prove on the local preview.
186
+
187
+ ## [1.47.0+agent.11] - 2026-10-01
188
+
189
+ ### Changed
190
+
191
+ - `doctor`'s `page_kit.sdk_version.spec_missing` now names the SDK the
192
+ selected certified template family was last verified against (for
193
+ example `The "apollo" template family was last verified against
194
+ 0.4.40.`), so the CampaignSpec pin is not chosen by searching docs. The
195
+ bundled SDK support policy's `latest_known_release` moves from 0.4.38 to
196
+ 0.4.40, which the catalog's verification records already named.
197
+ - `source_html.prep.document_wrapper` names the two ways to record a
198
+ standalone page as whole: `--wrapper-policy preserve_document_wrappers`
199
+ on `start` or `prepare-build`, or `wrapper_policy` in the source-html
200
+ manifest.
201
+ - `source_html.pages.source_hash` now says the hash it compares is the one
202
+ intake recorded in the Build Packet, that re-running intake with
203
+ `--force` refreshes it (and clears recorded stage evidence), and that
204
+ editing the manifest alone does not. It no longer points at a producer
205
+ script. `docs/build-packet.md` says the same, and that a revision made
206
+ after build belongs under `src/<route>/`.
207
+
208
+ ## [1.47.0+agent.10] - 2026-10-01
209
+
210
+ ### Fixed
211
+
212
+ - A test order the platform refuses as a duplicate now says so. The order
213
+ API puts the reason in `payment_details`, which QA's response capture
214
+ dropped, so the `browser-test-order` row read only
215
+ `order create rejected: HTTP 400`. The capture now keeps a string
216
+ `payment_details` on an error response, and a duplicate-order refusal adds `duplicate_order`
217
+ with the remedy: re-run with a different `--test-email-prefix` (or
218
+ `--test-email`), or wait up to 30 minutes. `docs/qa-and-test-orders.md`
219
+ explains what the platform matches on and why concurrent runs collide.
220
+
221
+ ## [1.47.0+agent.9] - 2026-10-01
222
+
223
+ ### Changed
224
+
225
+ - The agent context `install-agent-context` writes (`agents/claude/CLAUDE.md`,
226
+ `agents/codex/AGENTS.md`, `agents/copilot/copilot-instructions.md`,
227
+ `agents/cursor/campaigns-os.mdc`) now tells a session picking up an
228
+ existing campaign to run `readback` and `next` before reading artifacts by
229
+ hand. It also says the committed `.campaign-runtime/qa-verdict.json` keeps
230
+ no order records or URLs, so its `browser-test-order:<path>` assertions are
231
+ the typed-card proof. A resumed session had read the sidecar's empty
232
+ `test_orders` as "no test orders" after five verified orders.
233
+ - The `campaign-run-evidence` skill says the same: the sidecar always
234
+ empties `test_orders` and the URL fields, so an empty `test_orders` there
235
+ says nothing about ordering. Bundled skills carry revision
236
+ `1.47.0+skills.3`, with each skill version advanced two patches from
237
+ `1.47.0+skills.1`.
238
+
239
+ ### Fixed
240
+
241
+ - `readback` shows `warn` and `manual_review` assertions as the verdict
242
+ statuses they are, with their severity, recorded `actual` and evidence
243
+ problems (as it does for `fail` rows), instead of counting them as
244
+ "unrecognized status".
245
+
246
+ ## [1.47.0+agent.8] - 2026-10-01
247
+
248
+ ### Fixed
249
+
250
+ - `qa run` no longer fails `pricing.checkout_price_visible` on a checkout
251
+ whose cart is filled on an earlier page. When QA opens such a checkout
252
+ directly, the SDK cart is empty and the page has no package selection of its
253
+ own, so no price can show. The row is now `skipped` with that reason and
254
+ records `cart_count` and `checkout_selection_surface`. The test order
255
+ already enters that cart from the landing page. A checkout with its own
256
+ package selection, or a filled cart, still fails when no price shows.
257
+ - The page-binding check recognises `campaign-cart@<tag>/dist/loader.js`, the
258
+ SDK loader the starter templates use, and no longer tries to fetch it as a
259
+ cross-origin config script. Starter-template pages now report
260
+ `dynamic_unresolved` instead of `script_unavailable_or_limit`; they still
261
+ need manual review, because the static reader cannot prove a binding on a
262
+ page that runs other scripts.
263
+
264
+ ## [1.47.0+agent.7] - 2026-10-01
265
+
266
+ ### Removed
267
+
268
+ - `doctor` no longer scans built pages for proof and urgency copy. The
269
+ `content_residue.anti_pattern` warning (review counts, "Verified Purchase"
270
+ labels, stock and sell-out lines, expert and press mentions) is gone, and so
271
+ is `content_residue.urgency_unattested`, which asked a campaign without a
272
+ brief payload to confirm its countdown was real. That copy belongs to the
273
+ merchant, and agents read the warnings as a reason to strip it from the
274
+ merchant's own designs. Template demo residue, the needs-merchant-input
275
+ marker, the discount-claim warnings and the brief-backed urgency and proof
276
+ attestation gates are unchanged.
277
+
278
+ ### Changed
279
+
280
+ - The `next-campaigns-build` and `next-campaigns-polish` skills now say to
281
+ reproduce the source design's own proof and urgency elements (reviews,
282
+ "Verified Purchase" labels, recent-purchase popups, stock counters,
283
+ countdowns, guarantees) as designed, and not to record them as polish
284
+ issues. `docs/campaign-build-brief.md` says the same. Bundled skills carry
285
+ revision `1.47.0+skills.2`, with each skill version advanced one patch.
286
+
287
+ ## [1.47.0+agent.6] - 2026-10-01
288
+
289
+ ### Changed
290
+
291
+ - The usage lines for `start`, `prepare-build` and `build` now list
292
+ `--deploy-target <target>`, `--preview-url <url>` and
293
+ `--production-url <url>`. Intake has always written them to the Build
294
+ Packet's `deploy` block (`deploy.target` defaults to `unknown`), and
295
+ `docs/build-packet.md`, the README and the Start page already pass
296
+ `--deploy-target local-serve` to `start`, but the help text left them out,
297
+ so an agent checking that command against the help read it as
298
+ unsupported. Behaviour is unchanged.
299
+
300
+ ## [1.47.0+agent.1] - 2026-10-01
301
+
302
+ ### Fixed
303
+
304
+ - The one-line setup command in `docs/local-setup.md` now starts with
305
+ `npm init -y`. Without a `package.json` in the campaign folder, npm installs
306
+ into the nearest parent folder that has a `package.json` or `node_modules`,
307
+ so a campaign folder created inside another project added page-kit and the
308
+ toolkit to that project instead of the campaign. The README and quickstart
309
+ installs already started with `npm init -y`; a test now holds all three to
310
+ it.
311
+
5
312
  ## [1.47.0] - 2026-10-01
6
313
 
7
314
  ### 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 `npx --no-install campaigns-os readback .` and `npx --no-install 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.
@@ -17,15 +19,16 @@ Core rules:
17
19
  - 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.
18
20
  - Preserve prepared source HTML for landing/presell pages when it is a real standalone design.
19
21
  - For checkout/upsell/downsell/receipt, use starter-template commerce surfaces as SDK contract references: preserve required `data-next-*` controls and runtime wiring, but let the campaign/source own visual chrome, copy hierarchy, imagery, and brand layer.
22
+ - 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.
20
23
  - If `.campaign-runtime/build-context.json` has `theme` or `.campaign-runtime/theme/theme-report.json` exists, use it as optional brand-theme evidence. A 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.
21
24
  - Copy a starter template family atomically with dependent pages, `_includes/`, `_layouts/`, `assets/css/`, and `assets/js/`; do not copy only checkout/receipt pages.
22
25
  - Resolve SDK routing meta tags to campaign-root paths such as `/campaign-slug/upsell/`; do not emit source filenames or unrooted `upsell/` values into built checkout/upsell pages.
23
26
  - Default one-time `packages.prepurchase_*` order bumps to fixed quantity rather than syncing with the main bundle unless the spec explicitly requires sync.
24
27
  - Record spec-driven removals, such as unavailable payment methods, so polish does not reintroduce them.
25
28
  - Do not copy Olympus-style `shipping_methods` frontmatter into `shop-three-step`; it uses dynamic shipping through `window.next.getShippingMethods()`.
26
- - Run build/lint checks and record evidence in the assembly report, then hand off to polish. 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 `campaigns-os polish capture --packet campaign-runtime.build.json --base-url <served-current-build-url>`.
27
- - After that checkpoint clears, QA uses the Campaigns OS Node/npm runner: run `campaigns-os qa resolve --packet campaign-runtime.build.json`, then run `campaigns-os qa run --packet campaign-runtime.build.json --base-url <url> --browser --test-order common`.
28
- - Typed-card test-order proof uses `campaigns-os qa run --test-order <common|checkout|decline|accept|both|full|explicit-path>` through the deployed checkout and rendered upsell controls. `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. Coverage is the only control — there is no permission/approval step.
29
+ - Run build/lint checks and record evidence in the assembly report, then hand off to polish. 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>`.
30
+ - After that checkpoint clears, QA uses the Campaigns OS Node/npm runner: run `npx --no-install campaigns-os qa resolve --packet campaign-runtime.build.json`, then run `npx --no-install campaigns-os qa run --packet campaign-runtime.build.json --base-url <url> --browser --test-order common`.
31
+ - Typed-card test-order proof uses `npx --no-install campaigns-os qa run --test-order <common|checkout|decline|accept|both|full|explicit-path>` through the deployed checkout and rendered upsell controls. `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. Coverage is the only control — there is no permission/approval step.
29
32
  - 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.
30
33
  - Test-order proof must use the canonical Playwright typed-card path through the tested checkout: select the rendered cart, fill customer/shipping fields, type the sandbox card into active hosted payment iframes, click the real submit button, then click rendered SDK upsell accept/decline controls and verify receipt/order evidence.
31
34
  - 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.
@@ -3,8 +3,9 @@
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 `npx --no-install campaigns-os readback .` and `npx --no-install 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
- - Run `campaigns-os doctor --packet campaign-runtime.build.json` before build work.
8
+ - Run `npx --no-install 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.
9
10
  - Respect the selected template family's `agentContract`.
10
11
  - Replace demo refs from CampaignSpec/API; do not preserve starter sample IDs.
@@ -12,15 +13,16 @@ Use this context when working in a target campaign repo with Campaigns OS artifa
12
13
  - 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.
13
14
  - Preserve prepared source HTML for landing/presell pages when it is a real standalone design.
14
15
  - For checkout/upsell/downsell/receipt, use starter-template commerce surfaces as SDK contract references: preserve required `data-next-*` controls and runtime wiring, but let the campaign/source own visual chrome, copy hierarchy, imagery, and brand layer.
16
+ - 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.
15
17
  - If `.campaign-runtime/build-context.json` has `theme` or `.campaign-runtime/theme/theme-report.json` exists, use it as optional brand-theme evidence. A 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.
16
18
  - Copy a starter template family atomically with dependent pages, `_includes/`, `_layouts/`, `assets/css/`, and `assets/js/`; do not copy only checkout/receipt pages.
17
19
  - Emit SDK routing meta tags as campaign-root paths such as `/campaign-slug/upsell/`.
18
20
  - Default one-time `packages.prepurchase_*` bumps to fixed quantity unless the CampaignSpec explicitly requires package sync.
19
21
  - Record spec-driven drops so polish does not reintroduce unsupported source elements.
20
22
  - For `shop-three-step`, keep dynamic shipping via `window.next.getShippingMethods()` and do not add Olympus-style static `shipping_methods` frontmatter.
21
- - Build hands off to polish. 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 `campaigns-os polish capture --packet campaign-runtime.build.json --base-url <served-current-build-url>`.
22
- - After that checkpoint clears, QA uses the Campaigns OS Node/npm runner: run `campaigns-os qa resolve`, then `campaigns-os qa run --browser --test-order common` against the tested URL.
23
- - Typed-card test-order proof uses `campaigns-os qa run --test-order <common|checkout|decline|accept|both|full|explicit-path>` through the tested checkout and rendered upsell controls. Global test cards bypass the gateway and create no transactions, so no permission/approval is needed — coverage is the only control. `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. 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, the SDK test-mode event, or hand-built backend API orders as launch proof.
23
+ - Build hands off to polish. 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>`.
24
+ - After that checkpoint clears, QA uses the Campaigns OS Node/npm runner: run `npx --no-install campaigns-os qa resolve`, then `npx --no-install campaigns-os qa run --browser --test-order common` against the tested URL.
25
+ - Typed-card 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. Global test cards bypass the gateway and create no transactions, so no permission/approval is needed — coverage is the only control. `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. 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, the SDK test-mode event, or hand-built backend API orders as launch proof.
24
26
  - 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.
25
27
  - 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.
26
28
  - 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.
@@ -5,10 +5,11 @@ 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 `npx --no-install campaigns-os readback .` and `npx --no-install 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.
11
12
 
12
- 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. 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.
13
+ 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.
13
14
 
14
- 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 `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 `campaigns-os qa resolve`, then run `campaigns-os qa run --browser --test-order common` against the tested URL. Typed-card test-order proof must use `campaigns-os qa run --test-order <common|checkout|decline|accept|both|full|explicit-path>` through the tested checkout and rendered upsell controls; global test cards bypass the gateway and create no transactions, so no permission/approval is needed. `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.
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 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; global test cards bypass the gateway and create no transactions, so no permission/approval is needed. `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.
@@ -6,8 +6,8 @@ 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 `npx --no-install campaigns-os readback .` and `npx --no-install 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
- 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()`.
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. 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()`.
12
12
 
13
- 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 `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: `campaigns-os qa resolve`, then `campaigns-os qa run --browser --test-order common` against the tested URL. Test-order proof uses `campaigns-os qa run --test-order <common|checkout|decline|accept|both|full|explicit-path>` through the tested checkout and rendered upsell controls; global test cards bypass the gateway and create no transactions, so no permission/approval is needed. `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.
13
+ 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; global test cards bypass the gateway and create no transactions, so no permission/approval is needed. `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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "package": "@nextcommerce/campaigns-os",
3
- "version": "1.47.0",
3
+ "version": "1.50.0",
4
4
  "status": "developer-preview",
5
5
  "contracts": {
6
6
  "campaign_spec": "4.2-4.3",