@nextcommerce/campaigns-os 1.59.0 → 1.60.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 (41) hide show
  1. package/CHANGELOG.md +116 -0
  2. package/README.md +6 -5
  3. package/compatibility.json +1 -1
  4. package/contracts/commerce-surface-catalog.json +18 -18
  5. package/contracts/release-ledger.json +543 -0
  6. package/contracts/supported-surface.json +1 -1
  7. package/contracts/template-brand-contract.shared-commerce.v0.json +1 -1
  8. package/docs/build-packet.md +14 -12
  9. package/docs/campaign-build-brief.md +1 -1
  10. package/docs/campaigns-os-build-flow.md +1 -1
  11. package/docs/local-setup.md +1 -1
  12. package/docs/orientation-contract-reference.md +1 -1
  13. package/docs/polish-evidence.md +1 -1
  14. package/docs/runtime-readiness.md +1 -1
  15. package/docs/skills-revision.md +10 -10
  16. package/package.json +1 -1
  17. package/skills/campaign-lifecycle-orientation/SKILL.md +3 -3
  18. package/skills/campaign-readback-classification/SKILL.md +3 -3
  19. package/skills/campaign-run-evidence/SKILL.md +3 -3
  20. package/skills/contribution-intake/SKILL.md +3 -3
  21. package/skills/next-campaigns-build/SKILL.md +4 -4
  22. package/skills/next-campaigns-os/SKILL.md +3 -3
  23. package/skills/next-campaigns-os-setup/SKILL.md +3 -3
  24. package/skills/next-campaigns-polish/SKILL.md +9 -10
  25. package/skills/next-campaigns-qa/SKILL.md +3 -3
  26. package/skills/next-campaigns-sdk-bump/SKILL.md +193 -0
  27. package/skills.json +18 -10
  28. package/src/built-site-scope.mjs +5 -12
  29. package/src/campaign-identity.mjs +6 -4
  30. package/src/cli.mjs +37 -60
  31. package/src/doctor/checks.mjs +6 -3
  32. package/src/doctor/inspect.mjs +2 -8
  33. package/src/doctor/next-step.mjs +6 -3
  34. package/src/orchestration-stage-contract.mjs +6 -3
  35. package/src/page-kit-build-summary.mjs +21 -1
  36. package/src/page-kit-campaign-config.mjs +19 -0
  37. package/src/polish-gate.mjs +1 -5
  38. package/src/progress-node.mjs +2 -1
  39. package/src/spec-derive.mjs +24 -9
  40. package/src/stage-ledger.mjs +27 -1
  41. package/src/stage-record.mjs +18 -2
@@ -41,7 +41,7 @@ URL.
41
41
  - Starter template contracts own the SDK attribute contract and protected runtime surfaces: checkout/cart/upsell/receipt/payment/address/totals/submit controls and their required data attributes.
42
42
  - Designed source owns visual composition, content hierarchy, imagery, and page-level copy.
43
43
 
44
- Packages identify sellable products or variants, and Offers own campaign price changes. Package Retail Price/Quantity fields may exist on older campaigns, but assembly should not introduce them for new tier pricing.
44
+ Packages identify sellable products or variants, and Offers own campaign price changes. The Campaigns App dashboard calls packages **Products** and creates one per variant when an Offer that selects it is saved, so a campaign set up there has one package per variant and a separate Offer for each Buy 1/2/3 tier. Package Retail Price/Quantity fields and multi-unit packages exist on older campaigns that have the legacy **Enable Package Retail Price & Quantity** setting on (see the "Older Campaigns" section of [Campaign Products](https://docs.nextcommerce.com/docs/apps/campaigns-app/build-campaign-packages)), but assembly should not introduce them for new tier pricing.
45
45
 
46
46
  ## Offer Application Surfaces
47
47
 
@@ -3,7 +3,7 @@
3
3
  For a new campaign, create an empty working folder and run this from it:
4
4
 
5
5
  ```sh
6
- npm init -y && npm install --save-exact next-campaign-page-kit@0.2.0 && npm install --save-dev --save-exact @nextcommerce/campaigns-os@1.59.0 && npx --no-install campaigns-os tooling setup --target . --platform claude
6
+ npm init -y && npm install --save-exact next-campaign-page-kit@0.3.0 && npm install --save-dev --save-exact @nextcommerce/campaigns-os@1.60.0 && npx --no-install campaigns-os tooling setup --target . --platform claude
7
7
  ```
8
8
 
9
9
  `npm init -y` gives the folder its own `package.json`. Without one, npm
@@ -26,7 +26,7 @@ Ledger schema id: `campaigns-os-release-ledger/v1`
26
26
  Change policy version: `1.0.0`
27
27
  Reason-code vocabulary version: `1.0.0`
28
28
  Limits version: `1.0.0`
29
- Supported surface at generation time: `1.59.0`
29
+ Supported surface at generation time: `1.60.0`
30
30
 
31
31
  ## Forward compatibility
32
32
 
@@ -37,7 +37,7 @@ The gate only applies once assembly is complete
37
37
  | `status` | `stages.polish.status` | Must start with `completed`. `blocked` → `polish.blocked`; anything else → `polish.evidence_missing`. |
38
38
  | `performed_by` | `stages.polish.performed_by`, `stages.polish.command_identity`, `evidence.performed_by` | Must be exactly `next-campaigns-polish`. Anything else (including missing) → `polish.self_certified`. |
39
39
  | `commands` | `stages.polish.commands` and/or `evidence.commands` | Must NOT mention a build command anywhere — a polish record that ran build is self-certification → `polish.self_certified`. The matcher is exactly the strings `next-campaigns-build` and `campaigns-os next build` (case-insensitive); other build tooling (e.g. page-kit's `campaign-build`) is not matched. |
40
- | `source_build_fingerprint` | `stages.polish.source_build_fingerprint` or `evidence.source_build_fingerprint` | Required, and must equal the current build fingerprint (`stages.assembly.build_fingerprint`, falling back to `stages.assembly.artifact_fingerprint`, `report.build_fingerprint`, `report.artifact_fingerprint`). Missing → `polish.source_build_fingerprint_missing`; different → `polish.stale`. Doctor, QA, and `polish capture` also recompute the fingerprint from the built output under `_site/<slug>/` (algorithm in `docs/build-packet.md`); when the output no longer matches the recorded value the gate is `polish.output_drift` with `current_output_fingerprint` and a `rerun_build` action, whatever the recorded string says. |
40
+ | `source_build_fingerprint` | `stages.polish.source_build_fingerprint` or `evidence.source_build_fingerprint` | Required, and must equal the current build fingerprint (`stages.assembly.build_fingerprint`). Missing → `polish.source_build_fingerprint_missing`; different → `polish.stale`. Doctor, QA, and `polish capture` also recompute the fingerprint from the built output under `_site/<slug>/` (algorithm in `docs/build-packet.md`); when the output no longer matches the recorded value the gate is `polish.output_drift` with `current_output_fingerprint` and a `rerun_build` action, whatever the recorded string says. |
41
41
  | `source_package_material_fingerprint` | `stages.polish.source_package_material_fingerprint` or `evidence.source_package_material_fingerprint` | Only enforced when the report carries a current Design Source Package material fingerprint (`design_source_package.material_fingerprint` or equivalents). Missing → `polish.source_package_material_fingerprint_missing`; different → `polish.source_package_stale`. |
42
42
  | `completed_at` | `stages.polish.completed_at` or `evidence.completed_at` | Required non-empty timestamp string → else `polish.completed_at_missing`. |
43
43
 
@@ -8,7 +8,7 @@
8
8
 
9
9
  How a checkout of this repository at one commit becomes a usable installed runtime, and how a consumer decides whether a prepared one is still trustworthy. Everything below is generated from `contracts/runtime-recipe.campaigns-os-node-v1.json`, which is the only authority for these values.
10
10
 
11
- Recipe kind `campaigns-os-node-v1`, revision `1.0.3`, validated by `schemas/campaigns-os-runtime-recipe.v1.schema.json` (`Campaigns OS Runtime Recipe v1`). Supported surface at generation time: `1.59.0`.
11
+ Recipe kind `campaigns-os-node-v1`, revision `1.0.3`, validated by `schemas/campaigns-os-runtime-recipe.v1.schema.json` (`Campaigns OS Runtime Recipe v1`). Supported surface at generation time: `1.60.0`.
12
12
 
13
13
  ## What this is
14
14
 
@@ -16,7 +16,7 @@ that the copy on disk moved.
16
16
  `skills.json` carries one top-level field:
17
17
 
18
18
  ```json
19
- "bundle_revision": "1.59.0+skills.1"
19
+ "bundle_revision": "1.60.0+skills.1"
20
20
  ```
21
21
 
22
22
  The spelling is `<package version>+skills.<n>`:
@@ -25,7 +25,7 @@ The spelling is `<package version>+skills.<n>`:
25
25
  skills ship with (`check-skill-versions.mjs` fails if the two disagree);
26
26
  - `<n>` is a plain counter, not a semver component. It says "this is the *n*th
27
27
  skill-text revision published against that package version" and it **resets
28
- with the prefix**. `1.59.0+skills.1` is therefore ahead of `1.40.0+skills.7`.
28
+ with the prefix**. `1.60.0+skills.1` is therefore ahead of `1.40.0+skills.7`.
29
29
 
30
30
  It is one identity for the bundle as a whole, on purpose. Per-skill versions
31
31
  still exist and still gate per-skill changes, but an agent that loaded one skill
@@ -37,7 +37,7 @@ The first body line of every bundled `SKILL.md`, immediately after the
37
37
  frontmatter, is exactly:
38
38
 
39
39
  ```
40
- Bundle revision: 1.59.0+skills.1
40
+ Bundle revision: 1.60.0+skills.1
41
41
  ```
42
42
 
43
43
  followed by a short paragraph telling the agent to run the check below at the
@@ -48,7 +48,7 @@ text the agent is actually reading, not from a file it would have to go and open
48
48
  ## The check
49
49
 
50
50
  ```bash
51
- npx --no-install campaigns-os tooling status --skills-revision 1.59.0+skills.1
51
+ npx --no-install campaigns-os tooling status --skills-revision 1.60.0+skills.1
52
52
  ```
53
53
 
54
54
  The value is compared against the bundle revision of the **CLI the command runs
@@ -90,20 +90,20 @@ reports the choice as `skills.scope` (`requested`, `installed_platforms`, or
90
90
  "revision_check": "match",
91
91
  "skills_revision": {
92
92
  "status": "match",
93
- "requested": "1.59.0+skills.1",
93
+ "requested": "1.60.0+skills.1",
94
94
  "spelling": "bundle",
95
- "on_disk": "1.59.0+skills.1",
95
+ "on_disk": "1.60.0+skills.1",
96
96
  "on_disk_skill": null,
97
- "message": "match (1.59.0+skills.1)"
97
+ "message": "match (1.60.0+skills.1)"
98
98
  }
99
99
  ```
100
100
 
101
101
  The text view prints one named line, as a header above the rest of the status:
102
102
 
103
103
  ```
104
- Skills revision: match (1.59.0+skills.1)
105
- Skills revision: mismatch: loaded 1.39.0+skills.1, on disk 1.59.0+skills.1 — start a fresh session
106
- Skills revision: unchecked (on disk 1.59.0+skills.1)
104
+ Skills revision: match (1.60.0+skills.1)
105
+ Skills revision: mismatch: loaded 1.39.0+skills.1, on disk 1.60.0+skills.1 — start a fresh session
106
+ Skills revision: unchecked (on disk 1.60.0+skills.1)
107
107
  ```
108
108
 
109
109
  `unchecked` is the state when the flag is absent. It is not an error — an
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextcommerce/campaigns-os",
3
- "version": "1.59.0",
3
+ "version": "1.60.0",
4
4
  "description": "Toolkit for agent-assisted NEXT campaign builds.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: campaign-lifecycle-orientation
3
- version: 1.0.37
3
+ version: 1.0.41
4
4
  description: Orient a reader to the Campaigns OS lifecycle artifacts a run has already emitted, without advancing any stage or changing any state.
5
5
  ---
6
6
 
7
- Bundle revision: 1.59.0+skills.1
8
- Run `npx --no-install campaigns-os tooling status --skills-revision 1.59.0+skills.1`
7
+ Bundle revision: 1.60.0+skills.1
8
+ Run `npx --no-install campaigns-os tooling status --skills-revision 1.60.0+skills.1`
9
9
  from the campaign's Page Kit folder, where it runs the project's pinned copy and
10
10
  never installs one, at the start of each task. Start a fresh session if it
11
11
  reports `mismatch`: this text is already in your context and is never re-read
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: campaign-readback-classification
3
- version: 1.0.37
3
+ version: 1.0.41
4
4
  description: Classify a selected campaign from the readback projection's v2 fields and write a read-only handoff without turning diagnosis into permission.
5
5
  ---
6
6
 
7
- Bundle revision: 1.59.0+skills.1
8
- Run `npx --no-install campaigns-os tooling status --skills-revision 1.59.0+skills.1`
7
+ Bundle revision: 1.60.0+skills.1
8
+ Run `npx --no-install campaigns-os tooling status --skills-revision 1.60.0+skills.1`
9
9
  from the campaign's Page Kit folder, where it runs the project's pinned copy and
10
10
  never installs one, at the start of each task. Start a fresh session if it
11
11
  reports `mismatch`: this text is already in your context and is never re-read
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: campaign-run-evidence
3
- version: 1.0.37
3
+ version: 1.0.41
4
4
  description: Interpret existing Campaigns OS doctor, QA and proof-depth evidence without claiming more proof than the artifacts contain.
5
5
  ---
6
6
 
7
- Bundle revision: 1.59.0+skills.1
8
- Run `npx --no-install campaigns-os tooling status --skills-revision 1.59.0+skills.1`
7
+ Bundle revision: 1.60.0+skills.1
8
+ Run `npx --no-install campaigns-os tooling status --skills-revision 1.60.0+skills.1`
9
9
  from the campaign's Page Kit folder, where it runs the project's pinned copy and
10
10
  never installs one, at the start of each task. Start a fresh session if it
11
11
  reports `mismatch`: this text is already in your context and is never re-read
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: contribution-intake
3
- version: 1.0.37
3
+ version: 1.0.41
4
4
  description: Turn a suggestion about the agent surface into a classified, evidence-checked proposal and, only with attended approval, one issue on this repository's tracker.
5
5
  ---
6
6
 
7
- Bundle revision: 1.59.0+skills.1
8
- Run `npx --no-install campaigns-os tooling status --skills-revision 1.59.0+skills.1`
7
+ Bundle revision: 1.60.0+skills.1
8
+ Run `npx --no-install campaigns-os tooling status --skills-revision 1.60.0+skills.1`
9
9
  from the campaign's Page Kit folder, where it runs the project's pinned copy and
10
10
  never installs one, at the start of each task. Start a fresh session if it
11
11
  reports `mismatch`: this text is already in your context and is never re-read
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: next-campaigns-build
3
- version: 1.0.42
3
+ version: 1.0.46
4
4
  description: Assemble a NEXT campaign from a doctor-cleared Build Packet, CampaignSpec/API values, prepared HTML/assets, page-kit, and starter-template contracts.
5
5
  ---
6
6
 
7
- Bundle revision: 1.59.0+skills.1
8
- Run `npx --no-install campaigns-os tooling status --skills-revision 1.59.0+skills.1`
7
+ Bundle revision: 1.60.0+skills.1
8
+ Run `npx --no-install campaigns-os tooling status --skills-revision 1.60.0+skills.1`
9
9
  from the campaign's Page Kit folder, where it runs the project's pinned copy and
10
10
  never installs one, at the start of each task. Start a fresh session if it
11
11
  reports `mismatch`: this text is already in your context and is never re-read
@@ -110,7 +110,7 @@ Build rules:
110
110
  - Run page-kit build and SDK/template lint available in the target repo.
111
111
  - Record build with `campaigns-os record build --packet <packet>` after every page-kit build (tier `C`: it overwrites `stages.assembly` and, when the output changed, resets `stages.polish` to `required` in the assembly report, and stamps the doctor output stale; `--dry-run` is tier `none`). It stamps `stages.assembly.build_fingerprint` with the fingerprint doctor computes from `_site/<slug>/` and the Design Source Package material fingerprint when the report has one. Never type or copy these fields by hand.
112
112
  - If `next` reports that the build output is unchanged after a brief or CampaignSpec change, rebuild so the change reaches the pages. Pass `--deviation-reason` to `record build` only when the operator explicitly decides in this conversation that the change needs no change to the built pages, and quote their reason.
113
- - Capture the machine-readable build summary as an artifact: `npx campaign-build --json > .campaign-runtime/page-kit-build-summary.json` (requires `next-campaign-page-kit` >= 0.1.4). Doctor's `built_output.build_summary` check verifies per-page build status and Page Kit shape warnings (`NESTED_NO_PERMALINK`, `DUPLICATE_OUTPUT`, `MISSING_FRONTMATTER`, `LAYOUT_NOT_FOUND`, `NO_CAMPAIGN`) from this artifact. If the installed page-kit predates `--json`, record that in the assembly report instead of skipping silently.
113
+ - Capture the machine-readable build summary as an artifact: `npx campaign-build --json > .campaign-runtime/page-kit-build-summary.json` (requires `next-campaign-page-kit` >= 0.1.4). Doctor's `built_output.build_summary` check verifies per-page build status and Page Kit shape warnings (`NESTED_NO_PERMALINK`, `DUPLICATE_OUTPUT`, `MISSING_FRONTMATTER`, `LAYOUT_NOT_FOUND`, `NO_CAMPAIGN`) from this artifact. On `next-campaign-page-kit` >= 0.3.0 it also reads the summary's top-level `assetWarnings`: each `ASSET_IGNORED` entry names an `.html` file under `assets/` that page-kit neither builds nor copies, so a link or iframe to it 404s. Move such a file out of `assets/` if it is a page, or remove it. If the installed page-kit predates `--json`, record that in the assembly report instead of skipping silently.
114
114
  - Update the assembly report with commands, evidence, warnings, blockers, and next owner. If a brand theme was applied, run `campaigns-os record theme --packet <p>` (tier `C`) after `record build`: it reads each built commerce page's stylesheet links and records `report.theme` (status applied, `load_order=after-next-core`, `css_path`, `commerce_pages`, evidence). It refuses, writing nothing, when a page that loads `next-core.css` does not load the brand layer after it. Don't hand-edit `report.theme`; a first repair-loop defect goes through `record polish`.
115
115
 
116
116
  Build does not replace polish or QA. Hand off to `next-campaigns-polish` when the campaign is runnable.
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: next-campaigns-os
3
- version: 1.0.57
3
+ version: 1.0.61
4
4
  description: Coordinate Campaigns OS lifecycle workflows from CampaignSpec, Build Packet, starter-template contracts, stage reports, deploy evidence, and QA proof depth.
5
5
  ---
6
6
 
7
- Bundle revision: 1.59.0+skills.1
8
- Run `npx --no-install campaigns-os tooling status --skills-revision 1.59.0+skills.1`
7
+ Bundle revision: 1.60.0+skills.1
8
+ Run `npx --no-install campaigns-os tooling status --skills-revision 1.60.0+skills.1`
9
9
  from the campaign's Page Kit folder, where it runs the project's pinned copy and
10
10
  never installs one, at the start of each task. Start a fresh session if it
11
11
  reports `mismatch`: this text is already in your context and is never re-read
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: next-campaigns-os-setup
3
- version: 2.0.40
3
+ version: 2.0.44
4
4
  description: Bootstrap or prepare a target page-kit campaign repo from a doctor-cleared Campaigns OS Build Packet before full build wiring. Formerly installed as next-campaigns-setup; renamed 2026-08 to stop colliding with the published NextCommerceCo/skills scaffolder of that name.
5
5
  ---
6
6
 
7
- Bundle revision: 1.59.0+skills.1
8
- Run `npx --no-install campaigns-os tooling status --skills-revision 1.59.0+skills.1`
7
+ Bundle revision: 1.60.0+skills.1
8
+ Run `npx --no-install campaigns-os tooling status --skills-revision 1.60.0+skills.1`
9
9
  from the campaign's Page Kit folder, where it runs the project's pinned copy and
10
10
  never installs one, at the start of each task. Start a fresh session if it
11
11
  reports `mismatch`: this text is already in your context and is never re-read
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: next-campaigns-polish
3
- version: 1.1.42
3
+ version: 1.1.46
4
4
  description: Run the visual/runtime polish pass after build and before QA for a Campaigns OS campaign.
5
5
  ---
6
6
 
7
- Bundle revision: 1.59.0+skills.1
8
- Run `npx --no-install campaigns-os tooling status --skills-revision 1.59.0+skills.1`
7
+ Bundle revision: 1.60.0+skills.1
8
+ Run `npx --no-install campaigns-os tooling status --skills-revision 1.60.0+skills.1`
9
9
  from the campaign's Page Kit folder, where it runs the project's pinned copy and
10
10
  never installs one, at the start of each task. Start a fresh session if it
11
11
  reports `mismatch`: this text is already in your context and is never re-read
@@ -87,13 +87,12 @@ Responsibilities:
87
87
  evidence forward as a warning. Query or fragment text on the production
88
88
  page does not make it a distinct preview. If the hosted preview URL is not
89
89
  yet recorded, run
90
- `campaigns-os qa policy set --packet <packet> --preview-url <url>` first,
91
- then `campaigns-os next --packet <packet>`. Run
92
- `campaigns-os next qa --packet <packet>`, then
93
- `campaigns-os qa run --packet <packet> --base-url <preview-url> --browser
94
- --test-order common`. The hosted preview URL satisfies the deploy handoff;
95
- after QA records its verdict, run `campaigns-os next --packet <packet>` for
96
- closeout. QA against the packet's production URL keeps the checkpoint blocked.
90
+ `campaigns-os qa policy set --packet <packet> --preview-url <url>` first.
91
+ Then follow `campaigns-os next --packet <packet>`: it hands off
92
+ `campaigns-os record deploy --packet <packet> --base-url
93
+ <preview route root>`, then `campaigns-os qa run --packet <packet>
94
+ --base-url <preview-url> --browser --test-order common`, then closeout. QA
95
+ against the packet's production URL keeps the checkpoint blocked.
97
96
  - When a readability warning appears, report it with its colours, ratio, requirement and pages. Offer the operator options inside the brand palette (a darker or lighter shade of the same hue, the palette's text colour, or a larger, bold label where the design allows). Do not recolour the merchant's design until the operator chooses. Accept a warning only with the refs, reason and name the operator gives you at the QC handoff.
98
97
  - Record Polish as `completed`, `skipped`, or `blocked` with
99
98
  `campaigns-os record polish --packet <packet> --evidence <polish-evidence.json>`
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: next-campaigns-qa
3
- version: 1.3.41
3
+ version: 1.3.45
4
4
  description: Run spec-aware QA from a saved Map or local-spec Build Packet and tested campaign URL after build, polish, and deploy/local evidence exist, including Playwright typed-card test-order proof.
5
5
  ---
6
6
 
7
- Bundle revision: 1.59.0+skills.1
8
- Run `npx --no-install campaigns-os tooling status --skills-revision 1.59.0+skills.1`
7
+ Bundle revision: 1.60.0+skills.1
8
+ Run `npx --no-install campaigns-os tooling status --skills-revision 1.60.0+skills.1`
9
9
  from the campaign's Page Kit folder, where it runs the project's pinned copy and
10
10
  never installs one, at the start of each task. Start a fresh session if it
11
11
  reports `mismatch`: this text is already in your context and is never re-read
@@ -0,0 +1,193 @@
1
+ ---
2
+ name: next-campaigns-sdk-bump
3
+ version: 1.0.1
4
+ description: Bump a live campaign's Campaign Cart SDK from one 0.4.x release to a later 0.4.x on a page-kit or static repo. Use for any request to bump, upgrade or move a campaign to SDK 0.4.x, including when the repository has its own BUMP.md. Find every pin, check the release diff and storage against the campaign's own code, prove on a preview with approved test orders, and report what is not proven.
5
+ ---
6
+
7
+ Bundle revision: 1.60.0+skills.1
8
+ Run `npx --no-install campaigns-os tooling status --skills-revision 1.60.0+skills.1`
9
+ from the campaign's Page Kit folder, where it runs the project's pinned copy and
10
+ never installs one, at the start of each task. Start a fresh session if it
11
+ reports `mismatch`: this text is already in your context and is never re-read
12
+ while the CLI on disk can move under it. If the output has no `Skills revision:`
13
+ line (no `revision_check` under `--json`), a campaigns-os older than this check
14
+ answered; follow none of its actions and run the pinned copy.
15
+
16
+ # Next Campaigns SDK Bump
17
+
18
+ Use this when someone says "bump this campaign to SDK 0.4.x". The developer
19
+ installs the toolkit, asks for the bump, approves each push, the pull request
20
+ and each test order, then reviews and merges. Everything here uses existing
21
+ commands; there is no new write or order capability.
22
+
23
+ If `tooling status` prints `Refresh installed skills` for `--platform codex` or
24
+ `--platform agents` only, that refresh is for those harnesses; it is not
25
+ required in a session that uses neither.
26
+
27
+ In the instructions below, bare `campaigns-os …` means `npx --no-install
28
+ campaigns-os …` from the campaign folder. The effect class in each
29
+ parenthetical is the declared row of `contracts/effects.v1.json`.
30
+
31
+ ## Scope: a current-SDK bump only
32
+
33
+ A bump moves a funnel from one Campaign Cart 0.4.x release to a later 0.4.x.
34
+ Before anything else, confirm every page in scope loads a 0.4.x loader. Stop
35
+ and say so if you find a 0.3.x pin or a legacy page: one whose own code calls
36
+ the Campaigns JS or the Campaigns API directly for cart and checkout. Moving
37
+ those changes bundle selection, cart calculation and more, and is migration
38
+ work, not a bump.
39
+
40
+ Judge a legacy page by what drives its cart and checkout, not by a script URL.
41
+ The 0.4.x SDK loads the Campaigns analytics script (`/js/v1/campaign/`) itself
42
+ for analytics, and some layouts also load it by hand; on a page the 0.4.x SDK
43
+ drives, that script alone is not a reason to stop.
44
+
45
+ A bump does not adopt new SDK components. Hand-written address or phone fields
46
+ stay hand-written; adopting `data-next-address` or another new component is
47
+ separate work.
48
+
49
+ ## Approval gates
50
+
51
+ Ask before every push, before opening the pull request, and before test
52
+ orders. Test orders are real orders in the store that someone may have to
53
+ cancel; follow the `next-campaigns-qa` rule: ask once up front, then follow the
54
+ answer. Never write evidence or notes into the served tree: many static repos
55
+ publish from the repository root. The hand-back goes on the ticket or the pull
56
+ request.
57
+
58
+ `qa run` against a preview that is not a local address posts its verdict to the
59
+ QA portal on campaign-map.nextcommerce.com and prints the link. Say so when you
60
+ ask about test orders, and pass `--local-only` unless the developer wants the
61
+ verdict there. `qa run` writes its local verdict under `qa-output/` in the
62
+ current folder (or `--output-dir <path>`). Keep `qa-output/` out of commits:
63
+ check `.gitignore`, and never stage it.
64
+
65
+ ## 1. Branch
66
+
67
+ Branch from an up-to-date `main`. List open pull requests that touch the
68
+ campaign folder and ask the developer about merge order before branching.
69
+
70
+ ## 2. Find every pin
71
+
72
+ **Page-kit repo** (`_data/campaigns.json` exists):
73
+
74
+ - `sdk_version` on each slug's entry in `_data/campaigns.json`.
75
+ - Pages that type the version into their own loader. Search with
76
+ `grep -rn "campaign-cart@v" src`. Switch each one to
77
+ `campaign-cart@v{{ campaign.sdk_version }}` so the data file is the only pin.
78
+ A data-file-only bump leaves those pages on the old SDK. The starter
79
+ templates render with Liquid and expose the entry as `campaign`; on a page
80
+ that does not, keep a literal version instead and say so. Step 5 checks the
81
+ built pages for an unrendered `{{`.
82
+ - With a Build Packet, `campaigns-os page-kit sync --packet <packet>` (tier `B`)
83
+ writes the CampaignSpec's pin into the entry; without one, edit the entry.
84
+
85
+ **Static repo** (no `_data/campaigns.json` anywhere in the repository, root
86
+ included):
87
+
88
+ - Preview with `campaigns-os sdk repin --target <funnel folder> --target-sdk <x.y.z>`
89
+ (tier `none` without `--apply`). It lists every loader and CSS pin with path
90
+ and line.
91
+ - Scope it to the funnel folder, not the repository root. Repin rewrites every
92
+ semver pin below `--target`, so in a repository where funnels sit side by
93
+ side, a root-level `--apply` moves pages outside the bump. Check every listed
94
+ file belongs to the funnel, then run the same command with `--apply` (tier
95
+ `B`). It writes `.campaign-runtime/sdk-repin.json` under the target; that file
96
+ is served if the publish root includes it, so say so or keep it out of the
97
+ deploy.
98
+ - `sdk repin` refuses a target with `_data/campaigns.json` at or below it,
99
+ but it does not look above `--target`. A funnel folder inside a page-kit
100
+ repository is not refused, so never point `sdk repin` at one; use the
101
+ page-kit steps above.
102
+
103
+ ## 3. Read the release diff against the campaign
104
+
105
+ Read the release notes and the source diff between the two Campaign Cart tags.
106
+ For each change, search the campaign's own JavaScript, includes and markup, and
107
+ report file and line where the campaign depends on the changed behaviour. In
108
+ particular:
109
+
110
+ - Trace where the funnel's purchase event comes from before the bump. Static
111
+ funnels often hand-wire `order:completed` listeners and their own `dataLayer`
112
+ pushes; check that event's page and timing against the release you are
113
+ moving to.
114
+ - If a page shows a discount before the SDK confirms a coupon, check that the
115
+ coupon exists on every campaign the funnel uses.
116
+ - Note whether the range changes the card fields or the 3-D Secure flow; if it
117
+ does, plan a 3-D Secure test order in step 6.
118
+ - When the range removes a feature the campaign uses, say so, and do not just
119
+ delete the call: that silently drops the feature from a live funnel. Look for
120
+ a documented replacement in the repository's own docs (`CLAUDE.md`,
121
+ `BUMP.md`) and the release notes. If none is documented, stop and ask.
122
+ - Classify every `next:initialized` listener. From 0.4.42 the SDK fires that
123
+ event once and does not replay it, so a deferred script that only listens for
124
+ it can miss it on a cached reload. Guard each one in the bump: run now if
125
+ `window.next` exists and `document.body.dataset.nextSdkLoading === "false"`,
126
+ otherwise wait for the event, and run once either way. Step 6 proves it.
127
+
128
+ ## 4. Storage check
129
+
130
+ Run `campaigns-os sdk storage-check --target <git-root> --target-sdk <x.y.z> --manifest <storage-migrations.v1.json> --scope <funnel folder,shared js>`
131
+ (tier `none`). Take the manifest from an unmodified checkout of the target
132
+ Campaign Cart tag (`docs/compatibility/storage-migrations.v1.json`, v0.4.40 or
133
+ later), at the highest version its supported range declares. Read each
134
+ `incompatible` and `unknown` line and say whose key it is. See
135
+ `docs/sdk-storage-compatibility.md`.
136
+
137
+ The manifest's `supportedSdkVersions` can stop below the tag it ships in: tags
138
+ v0.4.39 to v0.4.42 declare 0.4.38 to 0.4.38, so `--target-sdk 0.4.42` returns
139
+ `target-outside-manifest-range`. Run the check at the manifest's highest
140
+ version and report that it does not speak for the versions above it.
141
+
142
+ ## 5. Build and check
143
+
144
+ **Page-kit:** run a development build, confirm every built page loads only the
145
+ target version and that no built loader URL still holds an unrendered `{{`,
146
+ then `campaigns-os doctor --built <repo> --family <family> --slug <slug>`
147
+ (tier `none`) for a repository with no Build Packet, or `campaigns-os doctor --packet <packet>`
148
+ with one. Errors that are already on `main` are recorded, not fixed. Report doctor's
149
+ advisories with the rest; an attribute flagged as missing from the SDK's index
150
+ that the page does set (for example `data-next-page-type` on `<body>`) goes in
151
+ the hand-back as unchecked, not fixed by guesswork.
152
+
153
+ **Static:** there is no build and no doctor. Re-run the repin preview (it
154
+ should list nothing below the target) and search the served pages for any
155
+ remaining old version.
156
+
157
+ ## 6. Preview proof
158
+
159
+ Deploy a preview and prove the bump with browser test orders under the
160
+ approval rule above. `qa run --browser` needs the browser once per machine:
161
+ `campaigns-os qa install-browser` downloads about 100 MB, so ask before running
162
+ it. Pin the browser to the store's main market: a run
163
+ geolocated elsewhere can order in another currency and skip a currency-gated
164
+ upsell.
165
+
166
+ - With a Build Packet: `campaigns-os qa run --packet <packet> --base-url <preview-url> --browser --test-order common`
167
+ (tier `C`; see `next-campaigns-qa`).
168
+ - A built page-kit repo with no packet: `campaigns-os qa run --site <repo> --base-url <preview-url> --family <family> --browser`
169
+ (tier `C`) checks the served pages. Place the approved test orders in the
170
+ browser and record each order number.
171
+ - A static repo: place the approved test orders in the browser on the preview
172
+ and record each order number.
173
+
174
+ Cover:
175
+
176
+ - one card order per live checkout;
177
+ - PayPal cancelled, then a card order, where PayPal is offered;
178
+ - an upsell at quantity 2 or more on a page that shows a quantity picker;
179
+ - a 3-D Secure card when step 3 found card-field or 3-D Secure changes, and whether it challenged;
180
+ - the coupon path, if the funnel has one;
181
+ - the purchase event fires once, on the page the release says it should;
182
+ - each SDK page on a fresh load and on a cached reload, with every
183
+ `next:initialized` listener from step 3 running once on both.
184
+
185
+ Read each order back in the store admin (the packet run's verdict under
186
+ `qa-output/` also lists the orders it created) and keep the order numbers for
187
+ the hand-back.
188
+
189
+ ## 7. Hand back
190
+
191
+ On the ticket or the pull request, not in the repository: what changed (pins,
192
+ loader rewrites), the storage-check and doctor results, a table of test orders,
193
+ what is not proven, and which orders to cancel.
package/skills.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "campaigns-os-skills",
3
3
  "description": "Skills bundled with Campaigns OS. `skills.sh` installs these into the shared agent skill directories (~/.claude/skills, ~/.codex/skills), so each one is a versioned package: bump the version whenever a package changes. `bundle_revision` identifies the bundle as a whole — `<package version>+skills.<n>`, where the prefix is this package's version and `<n>` counts the skill-text revisions published against it. It advances whenever ANY bundled skill changes, every SKILL.md states it on its first body line, and `campaigns-os tooling status --skills-revision <value>` compares the value an agent read from a skill against the bundle on disk. See docs/skills-revision.md.",
4
- "bundle_revision": "1.59.0+skills.1",
4
+ "bundle_revision": "1.60.0+skills.1",
5
5
  "homepage": "https://github.com/NextCommerceCo/campaigns-os",
6
6
  "retired_skills": [
7
7
  {
@@ -16,7 +16,7 @@
16
16
  {
17
17
  "id": "next-campaigns-os",
18
18
  "name": "Campaigns OS Lifecycle",
19
- "version": "1.0.57",
19
+ "version": "1.0.61",
20
20
  "path": "skills/next-campaigns-os/SKILL.md",
21
21
  "domain": "campaigns",
22
22
  "description": "Coordinate Campaigns OS lifecycle workflows from CampaignSpec, Build Packet, starter-template contracts, stage reports, deploy evidence, and QA proof depth."
@@ -24,7 +24,7 @@
24
24
  {
25
25
  "id": "next-campaigns-os-setup",
26
26
  "name": "Campaigns OS Setup",
27
- "version": "2.0.40",
27
+ "version": "2.0.44",
28
28
  "path": "skills/next-campaigns-os-setup/SKILL.md",
29
29
  "domain": "campaigns",
30
30
  "description": "Bootstrap or prepare a target page-kit campaign repo from a doctor-cleared Campaigns OS Build Packet before full build wiring. Formerly next-campaigns-setup; renamed to release that name to the published NextCommerceCo/skills scaffolder."
@@ -32,7 +32,7 @@
32
32
  {
33
33
  "id": "next-campaigns-build",
34
34
  "name": "Campaign Build",
35
- "version": "1.0.42",
35
+ "version": "1.0.46",
36
36
  "path": "skills/next-campaigns-build/SKILL.md",
37
37
  "domain": "campaigns",
38
38
  "description": "Assemble a NEXT campaign from a doctor-cleared Build Packet, CampaignSpec/API values, prepared HTML/assets, page-kit, and starter-template contracts."
@@ -40,7 +40,7 @@
40
40
  {
41
41
  "id": "next-campaigns-polish",
42
42
  "name": "Campaign Polish",
43
- "version": "1.1.42",
43
+ "version": "1.1.46",
44
44
  "path": "skills/next-campaigns-polish/SKILL.md",
45
45
  "domain": "campaigns",
46
46
  "description": "Run the visual/runtime polish pass after build and before QA for a Campaigns OS campaign."
@@ -48,7 +48,7 @@
48
48
  {
49
49
  "id": "next-campaigns-qa",
50
50
  "name": "Campaign QA",
51
- "version": "1.3.41",
51
+ "version": "1.3.45",
52
52
  "path": "skills/next-campaigns-qa/SKILL.md",
53
53
  "domain": "campaigns",
54
54
  "description": "Run spec-aware QA from a saved Map or local-spec Build Packet and tested campaign URL after build, polish, and deploy/local evidence exist, including Playwright typed-card test-order proof."
@@ -56,7 +56,7 @@
56
56
  {
57
57
  "id": "campaign-lifecycle-orientation",
58
58
  "name": "Campaign Lifecycle Orientation",
59
- "version": "1.0.37",
59
+ "version": "1.0.41",
60
60
  "path": "skills/campaign-lifecycle-orientation/SKILL.md",
61
61
  "domain": "campaigns",
62
62
  "description": "Orient a reader to the Campaigns OS lifecycle artifacts a run has already emitted, without advancing their state: the shared vocabulary, doctor as a gate, the stage record, and the store-theme/Page Kit two-worlds trap."
@@ -64,7 +64,7 @@
64
64
  {
65
65
  "id": "campaign-run-evidence",
66
66
  "name": "Campaign Run Evidence",
67
- "version": "1.0.37",
67
+ "version": "1.0.41",
68
68
  "path": "skills/campaign-run-evidence/SKILL.md",
69
69
  "domain": "campaigns",
70
70
  "description": "Interpret existing doctor, QA verdict and proof-depth evidence without claiming more proof than the artifacts contain, and keep funnel proof apart from merchant launch readiness."
@@ -72,7 +72,7 @@
72
72
  {
73
73
  "id": "campaign-readback-classification",
74
74
  "name": "Campaign Readback Classification",
75
- "version": "1.0.37",
75
+ "version": "1.0.41",
76
76
  "path": "skills/campaign-readback-classification/SKILL.md",
77
77
  "domain": "campaigns",
78
78
  "description": "Classify a selected campaign from the campaigns-os-readback/v2 fields (artifacts, staleness.stale_keys, clean, doctor, divergences, skip_cascades) and write a read-only handoff without turning diagnosis into permission."
@@ -80,10 +80,18 @@
80
80
  {
81
81
  "id": "contribution-intake",
82
82
  "name": "Contribution Intake",
83
- "version": "1.0.37",
83
+ "version": "1.0.41",
84
84
  "path": "skills/contribution-intake/SKILL.md",
85
85
  "domain": "campaigns",
86
86
  "description": "Turn a suggestion about the agent surface into a classified, evidence-checked and redacted proposal, filed on this repository tracker only with attended approval."
87
+ },
88
+ {
89
+ "id": "next-campaigns-sdk-bump",
90
+ "name": "Campaign SDK Bump",
91
+ "version": "1.0.1",
92
+ "path": "skills/next-campaigns-sdk-bump/SKILL.md",
93
+ "domain": "campaigns",
94
+ "description": "Bump a live campaign from one Campaign Cart 0.4.x release to a later 0.4.x on a page-kit or static repo: find every pin, check the release diff and storage against the campaign code, prove on a preview with approved test orders, and report what is not proven."
87
95
  }
88
96
  ]
89
97
  }