@nextcommerce/campaigns-os 1.60.0 → 1.62.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.
- package/AGENTS.md +2 -1
- package/CHANGELOG.md +244 -0
- package/README.md +86 -438
- package/agents/claude/CLAUDE.md +20 -0
- package/agents/codex/AGENTS.md +19 -0
- package/agents/copilot/copilot-instructions.md +19 -0
- package/agents/cursor/campaigns-os.mdc +21 -0
- package/campaign-spec/README.md +7 -0
- package/campaign-spec/dist/analytics-vendors.d.ts +40 -0
- package/campaign-spec/dist/analytics-vendors.js +44 -0
- package/campaign-spec/dist/checkout-flow.d.ts +18 -0
- package/campaign-spec/dist/checkout-flow.js +28 -0
- package/campaign-spec/dist/index.d.ts +4 -2
- package/campaign-spec/dist/index.js +5 -1
- package/campaign-spec/dist/rules/analytics-contract-shape.d.ts +8 -0
- package/campaign-spec/dist/rules/analytics-contract-shape.js +39 -0
- package/campaign-spec/dist/rules/campaign-currencies.d.ts +29 -0
- package/campaign-spec/dist/rules/campaign-currencies.js +130 -0
- package/campaign-spec/dist/rules/checkout-path-has-packages.d.ts +31 -0
- package/campaign-spec/dist/rules/checkout-path-has-packages.js +79 -0
- package/campaign-spec/dist/rules/index.d.ts +2 -0
- package/campaign-spec/dist/rules/index.js +6 -0
- package/campaign-spec/dist/types.d.ts +43 -9
- package/compatibility.json +1 -1
- package/contracts/brand-theme-target-tokens.next-core.v0.json +95 -25
- package/contracts/campaign-cart-sdk-support-policy.v0.json +2 -2
- package/contracts/commerce-surface-catalog.json +68 -61
- package/contracts/effects.v1.json +549 -165
- package/contracts/fixtures/runtime-recipe/accept/current.json +3 -0
- package/contracts/fixtures/runtime-recipe/accept/minimal.json +3 -0
- package/contracts/fixtures/runtime-recipe/dist-states.json +1 -1
- package/contracts/fixtures/runtime-recipe/reject/advisory-enforcement.json +3 -0
- package/contracts/fixtures/runtime-recipe/reject/allowlist-without-hosts.json +3 -0
- package/contracts/fixtures/runtime-recipe/reject/committed-output-claim.json +3 -0
- package/contracts/fixtures/runtime-recipe/reject/engines-disagreement-warns.json +3 -0
- package/contracts/fixtures/runtime-recipe/reject/lifecycle-scripts-enabled.json +3 -0
- package/contracts/fixtures/runtime-recipe/reject/unknown-kind.json +3 -0
- package/contracts/fixtures/runtime-recipe/reject/unknown-network-policy.json +3 -0
- package/contracts/fixtures/runtime-recipe/reject/unknown-output-check.json +3 -0
- package/contracts/fixtures/runtime-recipe/reject/unknown-revision.json +3 -0
- package/contracts/fixtures/runtime-recipe/reject/unknown-step-id.json +3 -0
- package/contracts/fixtures/runtime-recipe/reject/unperformable-check-skipped.json +3 -0
- package/contracts/fixtures/runtime-recipe/reject/unpinned-lockfile.json +3 -0
- package/contracts/release-ledger.json +1767 -0
- package/contracts/runtime-recipe.campaigns-os-node-v1.json +3 -0
- package/contracts/supported-surface.json +10 -10
- package/contracts/template-brand-contract.shared-commerce.v0.json +23 -1
- package/docs/access-model.md +20 -0
- package/docs/brand-theme-bridge.md +62 -3
- package/docs/build-packet.md +456 -36
- package/docs/campaign-build-brief.md +16 -0
- package/docs/campaign-standardization-report.md +4 -4
- package/docs/campaigns-os-build-flow.md +112 -2
- package/docs/campaignspec-authoring-examples.md +141 -0
- package/docs/design-source-package.md +64 -8
- package/docs/effects.md +17 -9
- package/docs/entry-points.md +188 -0
- package/docs/local-setup.md +1 -1
- package/docs/orientation-contract-reference.md +1 -1
- package/docs/polish-evidence.md +42 -2
- package/docs/progress-snapshots.md +7 -4
- package/docs/qa-and-test-orders.md +197 -3
- package/docs/quickstart.md +438 -0
- package/docs/readback.md +154 -6
- package/docs/runtime-readiness.md +6 -3
- package/docs/sdk-storage-compatibility.md +4 -2
- package/docs/skills-revision.md +10 -10
- package/docs/source-adapters.md +213 -0
- package/package.json +10 -3
- package/schemas/campaign-design-source-package.v0.schema.json +8 -0
- package/schemas/campaign-runtime-build-context.v0.schema.json +9 -0
- package/schemas/campaign-runtime-build-packet.v0.schema.json +9 -0
- package/schemas/campaign-spec.v4.schema.json +19 -3
- package/schemas/campaign-spec.v5.schema.json +19 -3
- package/schemas/campaigns-os-readback.v2.schema.json +238 -1
- package/schemas/source-html-manifest.v0.schema.json +3 -0
- package/skills/campaign-lifecycle-orientation/SKILL.md +3 -3
- package/skills/campaign-readback-classification/SKILL.md +3 -3
- package/skills/campaign-run-evidence/SKILL.md +3 -3
- package/skills/contribution-intake/SKILL.md +3 -3
- package/skills/next-campaigns-build/SKILL.md +5 -4
- package/skills/next-campaigns-os/SKILL.md +7 -4
- package/skills/next-campaigns-os-setup/SKILL.md +5 -3
- package/skills/next-campaigns-polish/SKILL.md +8 -10
- package/skills/next-campaigns-qa/SKILL.md +7 -4
- package/skills/next-campaigns-sdk-bump/SKILL.md +151 -25
- package/skills.json +11 -11
- package/src/brand-theme.mjs +415 -9
- package/src/brief-summary.mjs +6 -2
- package/src/browser-launch.mjs +2 -1
- package/src/build-brief.mjs +13 -3
- package/src/built-site-scope.mjs +2 -2
- package/src/campaign-workspace.mjs +288 -15
- package/src/change-scope.mjs +284 -0
- package/src/cli.mjs +358 -97
- package/src/commercial-journey.mjs +16 -3
- package/src/commercial-parity.mjs +15 -7
- package/src/content-residue.mjs +4 -2
- package/src/design-file-reference.mjs +93 -0
- package/src/design-source-package.mjs +91 -1
- package/src/design-source-publication.mjs +9 -6
- package/src/directory-lock.mjs +73 -19
- package/src/doctor/checks.mjs +87 -81
- package/src/doctor/ci.mjs +177 -0
- package/src/doctor/inspect.mjs +41 -6
- package/src/doctor/next-step.mjs +7 -0
- package/src/doctor/source-provenance.mjs +74 -0
- package/src/doctor-sidecar.mjs +3 -2
- package/src/evidence-debt.mjs +159 -0
- package/src/finding-cause.mjs +12 -11
- package/src/input-refresh.mjs +339 -32
- package/src/invocation.mjs +7 -1
- package/src/live-campaign-refs.mjs +7 -2
- package/src/local-preview-policy.mjs +35 -2
- package/src/page-kit-analytics-vendors.mjs +132 -0
- package/src/parity/compare.mjs +316 -0
- package/src/parity/design-access.mjs +54 -0
- package/src/parity/element-parity-record.mjs +569 -0
- package/src/parity/probe.mjs +205 -0
- package/src/parity/snapshot.mjs +110 -0
- package/src/png-header.mjs +87 -0
- package/src/polish-browser.mjs +189 -10
- package/src/polish-captures-record.mjs +52 -0
- package/src/polish-deadline.mjs +14 -0
- package/src/polish-gate.mjs +25 -6
- package/src/polish-node.mjs +81 -7
- package/src/polish-readability.mjs +221 -9
- package/src/polish-visual-fixtures.mjs +74 -0
- package/src/polish-visual.mjs +613 -0
- package/src/progress-node.mjs +3 -2
- package/src/qa-analytics-correctness.mjs +14 -2
- package/src/qa-analytics-parity.mjs +111 -6
- package/src/qa-browser.mjs +40 -4
- package/src/qa-commercial-parity.mjs +50 -3
- package/src/qa-node.mjs +235 -22
- package/src/qa-publish.mjs +9 -8
- package/src/qa-sidecar.mjs +16 -4
- package/src/qa-vendor-beacons.mjs +232 -0
- package/src/qa-vendor-endpoints.mjs +306 -0
- package/src/qc-accept.mjs +176 -6
- package/src/qc-check-registry.mjs +42 -2
- package/src/qc-results.mjs +477 -42
- package/src/readback.mjs +113 -21
- package/src/route-identity.mjs +10 -0
- package/src/run-record.mjs +18 -10
- package/src/runtime-state-ignore.mjs +6 -2
- package/src/sdk-attribute-index.mjs +11 -11
- package/src/sdk-markup.mjs +77 -2
- package/src/sdk-storage-compatibility.mjs +115 -6
- package/src/source-html-intake.mjs +15 -1
- package/src/source-html-manifest.mjs +7 -0
- package/src/source-html-server.mjs +129 -0
- package/src/spec-derive-campaign.mjs +216 -0
- package/src/spec-derive.mjs +473 -53
- package/src/spec-identity.mjs +14 -0
- package/src/stage-ledger.mjs +40 -1
- package/src/stage-record.mjs +100 -17
- package/src/target-lock.mjs +11 -1
- package/src/theme-gate.mjs +2 -2
- package/src/visual-diff.mjs +296 -0
- package/src/visual-reference.mjs +126 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: next-campaigns-polish
|
|
3
|
-
version: 1.1.
|
|
3
|
+
version: 1.1.53
|
|
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.
|
|
8
|
-
Run `npx --no-install campaigns-os tooling status --skills-revision 1.
|
|
7
|
+
Bundle revision: 1.62.0+skills.1
|
|
8
|
+
Run `npx --no-install campaigns-os tooling status --skills-revision 1.62.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
|
|
@@ -59,7 +59,7 @@ Responsibilities:
|
|
|
59
59
|
- Scan **visible** rendered text inside the family's content/commerce surfaces (the selectors enumerated in `contracts/template-brand-contract.<family>.v0.json`) for placeholder/residue copy the build should have replaced — the *literal starter defaults*: lorem-ipsum, the unmodified starter headings (`Product Name` / `Package Title` / `Your headline`), `[VERIFY …]` author notes, `TODO` markers. Match the literal starter strings, not any authored copy that merely contains those words, and skip `<script>` / `<style>` / JSON-LD / `data-*` attributes. Treat a surviving literal starter default on a content/commerce surface as a polish blocker — replace it from the prepared source / CampaignSpec; do not draft substitute copy (if the design's authored copy is genuinely missing, flag it rather than invent it). This is *copy* residue, complementary to the computed-style / asset residue gated by `next-campaigns-qa` + the brand contract — not a duplicate of it.
|
|
60
60
|
- Flag template *defaults* left where they disagree with the prepared design — e.g. the same benefit icon repeated across a grid *when the design uses distinct icons*, or a guarantee badge/term that disagrees with the design — as polish defects, not just logos. Judge against the prepared source, not taste: copy or imagery the source/CampaignSpec does not supply (e.g. a placeholder testimonial name/quote/role) is residue; "looks generic" on its own is not. Copy the source does supply, including its proof and urgency elements (reviews, "Verified Purchase" labels, recent-purchase popups, stock counters, countdowns, guarantees), is the merchant's content: keep it as designed and do not record it as an issue or an unconfirmed claim.
|
|
61
61
|
- **Brand-bleed (cloned-source de-brand) pass.** When a campaign is cloned from a proven sibling, the sibling's brand defaults ride along. Inspect the built pages and assets for residual cross-brand bleed and clear it before recording: (1) a residual promo/sale banner or coupon code/copy from the source campaign (including a baked-in *fake* code); (2) a prior-campaign / sibling favicon left in place; (3) scaffold or non-design fonts the design did not specify (e.g. starter `Plus Jakarta`); (4) hardcoded non-token colors — any brand color literal that should be a token, such as next-core's `#C670FE` "Most Popular" pill. Clear each from the prepared source / CampaignSpec and brand theme (tokens, not literals); flag — do not invent — anything the design genuinely doesn't supply. Treat surviving bleed as a polish blocker. This complements the favicon/logo and copy-residue checks above; it is the cross-brand contamination angle, not a duplicate.
|
|
62
|
-
- Read the normalized Campaign Build Brief at `.campaign-runtime/input/campaign-build-brief.normalized.json` and the recorded decisions (`adapter_decisions`, `decisions` and `theme` in `.campaign-runtime/assembly-report.json`, and `assembly.template_decision_notes` in the Build Packet) before working on the campaign. The campaign intent summary at the top of the setup, build, Polish and QA prompts and in every `next` result is orientation, never a source of prices or commerce behaviour.
|
|
62
|
+
- Read the normalized Campaign Build Brief at `.campaign-runtime/input/campaign-build-brief.normalized.json` and the recorded decisions (`adapter_decisions`, `decisions` and `theme` in `.campaign-runtime/assembly-report.json`, and `assembly.template_decision_notes` in the Build Packet) before working on the campaign. The campaign intent summary at the top of the setup, build, Polish and QA prompts and in every `next` result is orientation, never a source of prices or commerce behaviour. For a later funnel in a multi-funnel project, read the same files under its own `assembly.runtime_dir` (`.campaign-runtime/funnels/<route>/`); the paths `next` prints are already the right ones.
|
|
63
63
|
- Read the assembly report decisions before polishing. Do not reintroduce source-HTML elements that build intentionally dropped because CampaignSpec/API did not support them, such as unavailable payment methods.
|
|
64
64
|
- **Remove or rename a contract-listed payment-chrome asset; never edit one in place.** The assets named in `contracts/template-brand-contract.<family>.v0.json` under `default_residue.payment_chrome.assets` are keyed by QA on the *referenced basename*, not on their contents. Stripping the unsupported marks from inside a shared file such as `upsell-payment-logos.svg` leaves the reference in place, so QA reports residue for an asset that no longer carries any — and on 2026-09-06 the repair loop's remedy for that report deleted a cards-only trust strip that was correct. Delete the asset, or write a new one under a new name and repoint the reference. QA downgrades an edited-in-place asset to `manual_review` rather than a blocker, but that is a safety net for a mistake, not the supported way to do this.
|
|
65
65
|
- Preserve existing `report.theme` data. If polish changes generated theme CSS, load order, commerce-page coverage, theme warnings, or the first repair-loop defect, update the Assembly Report `theme` block rather than leaving stale evidence.
|
|
@@ -70,7 +70,7 @@ Responsibilities:
|
|
|
70
70
|
- Treat express wallet presence as browser/device eligible. Record which wallets mounted in the tested browser, but do not fail solely because Apple Pay is absent in a non-eligible browser. Fail or block when the express mount is empty despite supported wallets, or when mounted wallet buttons are visually malformed.
|
|
71
71
|
- For bundle selectors and order bumps, verify active/inactive visual state after interaction, mobile label wrapping, badge placement, and selected/unchecked state. A native hidden input state that disagrees with the SDK class state is a polish blocker. So is a selected/active visual driven by a *non-SDK static attribute the SDK never clears* — e.g. a hardcoded `data-selected="true"` left on the initial card. (The native `selected` attribute on `<option>`/custom selects *is* SDK/browser-managed, so do not flag that.) The selected style must follow the SDK-managed class (e.g. `.next-selected` — see the family's bundle-selector selectors in `contracts/template-brand-contract.<family>.v0.json`) so a single-select swap clears the previous selection. Verify by interaction that the previously-selected item deselects after another is picked — a selector that only ever paints "selected" on click is a blocker.
|
|
72
72
|
- For exit-intent pops and promo-code inputs, polish the wrapper/copy states without breaking SDK coupon/voucher apply hooks or `cart.hasCoupon("CODE")` conditional labels.
|
|
73
|
-
- If `report.theme` or `context.theme` exists, verify brand-theme load order after `next-core.css`, source-token parity for primary color/CTA/surface/text/font/radius when present, and SDK safety. When the brand layer is missing, stale, low-confidence, or unsafe to apply, record the first repair-loop defect or an explicit skipped reason.
|
|
73
|
+
- If `report.theme` or `context.theme` exists, verify brand-theme load order after `next-core.css`, source-token parity for primary color/CTA/surface/text/font/radius when present, and SDK safety. Check font parity by computed style at a mobile and a desktop width, not desktop alone: next-core re-declares its font tokens on `body` below 992px, so a layer that sets them only on `:root` holds on desktop and falls back on mobile. When the brand layer is missing, stale, low-confidence, or unsafe to apply, record the first repair-loop defect or an explicit skipped reason.
|
|
74
74
|
- When at least one mapped page has a design route, before recording a terminal
|
|
75
75
|
Polish status, install the package-owned browser once with
|
|
76
76
|
`npx --no-install campaigns-os qa install-browser`, serve the current build,
|
|
@@ -93,7 +93,9 @@ Responsibilities:
|
|
|
93
93
|
<preview route root>`, then `campaigns-os qa run --packet <packet>
|
|
94
94
|
--base-url <preview-url> --browser --test-order common`, then closeout. QA
|
|
95
95
|
against the packet's production URL keeps the checkpoint blocked.
|
|
96
|
+
- In the handoff, `parity.element` rows are element differences to review or accept. `design.access` unexercised means the file was not read: compare by hand. A `design.access` review row means a changed, missing or conflicting design file: fix the declaration or rerun intake with `--force`. These rows never block Polish.
|
|
96
97
|
- 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
|
+
- A `layout.conventions` warning is a mobile layout convention: `floating_cta` means a fixed or sticky CTA bar holds more than its one control (the row names the bar and the other text), and `cta_label_size` means a CTA label is under 16px (the row gives the measured size). Report it with the page and element, offer the fix (move the extra text out of the bar, or raise the label size where the design allows), and leave the merchant's copy alone. Accept it only with the refs, reason and name the operator gives you. These rows never block Polish.
|
|
97
99
|
- Record Polish as `completed`, `skipped`, or `blocked` with
|
|
98
100
|
`campaigns-os record polish --packet <packet> --evidence <polish-evidence.json>`
|
|
99
101
|
(tier `C`: it overwrites `stages.polish` in the assembly report and stamps the
|
|
@@ -117,11 +119,7 @@ schema reference; this section is the recording guidance.
|
|
|
117
119
|
**All seven evidence fields are required** or the gate blocks with
|
|
118
120
|
`polish.evidence_incomplete`:
|
|
119
121
|
|
|
120
|
-
- `visual_review` —
|
|
121
|
-
`screenshot_paths`, `paths`, `urls`) holding at least one non-empty
|
|
122
|
-
path/URL string for the captured desktop+mobile evidence, plus the
|
|
123
|
-
package-generated `page_load` object. A bare string or a screenshot-less
|
|
124
|
-
object does NOT pass, no matter how real the review was.
|
|
122
|
+
- `visual_review` — run `campaigns-os polish capture` first: it records the package captures (`captures`) and `page_load`, which satisfy the screenshot requirement, and `record polish` refuses a completed Polish without them. Do not write screenshot paths to satisfy the check, and never write `captures` or `page_load` by hand. Report self-referential references and the review list from the QC handoff to the operator; accept a self-referential warning only when the operator decides to use the current output as the baseline for later revisions.
|
|
125
123
|
- `brand_review` — object; must include the `favicon` attestation and the
|
|
126
124
|
`brand_bleed` attestation (below).
|
|
127
125
|
- `checkout_review` — object; must include `field_labels` (aliases
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: next-campaigns-qa
|
|
3
|
-
version: 1.3.
|
|
3
|
+
version: 1.3.52
|
|
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.
|
|
8
|
-
Run `npx --no-install campaigns-os tooling status --skills-revision 1.
|
|
7
|
+
Bundle revision: 1.62.0+skills.1
|
|
8
|
+
Run `npx --no-install campaigns-os tooling status --skills-revision 1.62.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
|
|
@@ -70,7 +70,7 @@ Inputs:
|
|
|
70
70
|
- tested base URL (localhost dev URL, preview URL, or production URL)
|
|
71
71
|
- assembly report
|
|
72
72
|
- Test-order coverage choice (`common` default vs explicit paths vs topology-complete `full`) and SDK origin state (localhost is a Development domain; non-localhost origins need allowlist confirmation so the SDK loads)
|
|
73
|
-
- Read the normalized Campaign Build Brief at `.campaign-runtime/input/campaign-build-brief.normalized.json` and the recorded decisions (`adapter_decisions`, `decisions` and `theme` in `.campaign-runtime/assembly-report.json`, and `assembly.template_decision_notes` in the Build Packet) before working on the campaign. The campaign intent summary at the top of the setup, build, Polish and QA prompts and in every `next` result is orientation, never a source of prices or commerce behaviour.
|
|
73
|
+
- Read the normalized Campaign Build Brief at `.campaign-runtime/input/campaign-build-brief.normalized.json` and the recorded decisions (`adapter_decisions`, `decisions` and `theme` in `.campaign-runtime/assembly-report.json`, and `assembly.template_decision_notes` in the Build Packet) before working on the campaign. The campaign intent summary at the top of the setup, build, Polish and QA prompts and in every `next` result is orientation, never a source of prices or commerce behaviour. For a later funnel in a multi-funnel project, read the same files under its own `assembly.runtime_dir` (`.campaign-runtime/funnels/<route>/`); the paths `next` prints are already the right ones.
|
|
74
74
|
|
|
75
75
|
Rules:
|
|
76
76
|
|
|
@@ -95,6 +95,7 @@ Rules:
|
|
|
95
95
|
- Saved-Map QA publishes to the QA portal under the existing consent and flag controls; report the portal link only when publication succeeds. Pass `--no-post-verdict` (or `--local-only`) to keep that verdict local. This stays tier `C`: served-page probes, requested orders, Run Telemetry and progress retain their own controls. See `docs/qa-and-test-orders.md` for the saved-Map publication policy.
|
|
96
96
|
- Local-spec QA always keeps verdicts and progress local. `qa run` suppresses portal publication even with `--post-verdict`; `qa publish` refuses local-spec packets with `local_spec`. Report the local verdict/sidecar as evidence, never a dashboard link. A matching route cannot replace a matching `local_spec_id`, and QA refuses a foreign or stale local Assembly Report. Run Telemetry still follows its consent controls.
|
|
97
97
|
- Browser QA must include checkout commerce geometry evidence, not just mount counts: express-wallet buttons rendered in the current browser, card/CVV hosted iframe host dimensions, iframe text-path height, and center alignment. Apple Pay is browser/device eligible, so record mounted wallet kinds instead of requiring Apple Pay in Chrome-only QA.
|
|
98
|
+
- After launch, when `next` or `doctor --ci` reports a page-only change (only some pages' HTML changed, and no checkout page, commerce markup, route, script or Page Kit config entry), QA is owed on those pages only and Polish is advisory: after `record build`, run `qa run --packet <packet> --page <page_id>` with one `--page` per changed page it names. A page-scoped run places no test orders and keeps the purchase proof of the full run it extends; it refuses a commerce-affecting change, a last QA that did not complete, or a brief `qa_policy` or CampaignSpec change, each of which owes a full `qa run`. See `docs/campaigns-os-build-flow.md#what-a-change-owes`.
|
|
98
99
|
- `qa resolve` accepts either the deploy host or the campaign-root URL; when a Build Packet carries `campaign.public_route_slug`, the runner resolves page URLs under that slug.
|
|
99
100
|
- Routing meta tags must be checked in runtime form. `next-success-url`, `next-upsell-accept-url`, and `next-upsell-decline-url` should point at campaign-root paths such as `/campaign-slug/upsell/`, not source filenames or unrooted spec literals.
|
|
100
101
|
- Upsell accept/decline routes may be SDK-bound controls rather than static `<a href>` links. Treat rendered `data-next-upsell-action="add"` and `data-next-upsell-action="skip"` controls as valid route evidence, then prove the path in the browser walkthrough.
|
|
@@ -102,6 +103,7 @@ Rules:
|
|
|
102
103
|
- When CampaignSpec declares checkout `promo_code_input.enabled`, browser QA should enter the mapped `offer_code` and verify active-code state, repricing, discount row rendering, and conditional presentation. Missing promo-code input is a blocker when CampaignSpec, source design, or user instructions declared it.
|
|
103
104
|
- A declared offer surface that the build never shipped is a blocker, not a silent pass. Every `--browser` run emits `browser-exit-intent-surface:<page>` and `browser-promo-code-surface:<page>` for each checkout page whose CampaignSpec declares the surface with `enabled: true`. Absent markup is `FAIL`/`BLOCKER`; a surface that renders but cannot be tied to the declared `offer_code` (or sits behind an unopened disclosure) is `MANUAL_REVIEW`/`WARN`. Exit-intent markup is looked for inside `<template>` content as well as the live document, because a correctly built pop lives nowhere else before it fires. A browser collector that threw mid-read `SKIP`s with the cause instead of blocking — it did not find nothing, it could not look.
|
|
104
105
|
- Typed-card runs reconcile the persisted order against what the checkout displayed at submit, and report both halves separately from whether the order was created: `browser-order-display-parity:<plan>` fails as a blocker naming any `is_upsell: false` line whose package the checkout never rendered as selected (and any displayed package that was never charged), and `browser-order-total-parity:<plan>` fails as a blocker when the order's pre-upsell total disagrees with the displayed summary total. Both `SKIP` with a stated reason when the page gives them nothing to compare — a summary whose rows carry no `data-package-id`, or a checkout with no `[data-next-display="cart.total"]` surface. Read a skip as missing coverage, never as a pass.
|
|
106
|
+
- A `qa run --currency <CODE>` run checks the currency took: each created test order gets `browser-order-currency:<plan>`, which fails as a blocker when the order came out in any other currency (Campaign Cart falls back to the default one when the requested one is unavailable), and automatic commercial parity requests expected totals in `<CODE>`, with a `commercial-currency:<CODE>:<ANSWERED>` blocker when the calculate endpoint prices in another currency. Without `--currency` neither row is written.
|
|
105
107
|
- Test orders must exercise the tested campaign through the Campaign Cart SDK, not a hand-built backend API request.
|
|
106
108
|
- Use the canonical Playwright typed-card path: fill customer/shipping fields, type sandbox card data into the active hosted payment iframes, and click the real checkout submit button.
|
|
107
109
|
- Use a shared safe inbox for typed-card test-order customer email when the operator provides one. Reusing one safe inbox keeps customer/user lists clean while still allowing notification delivery.
|
|
@@ -119,6 +121,7 @@ Rules:
|
|
|
119
121
|
- Keep multi-funnel and `tiers:common` / `tiers:full` plans isolated to each selected checkout's own funnel graph, tiers, and recognized terminals; never borrow an unrelated funnel's receipt page.
|
|
120
122
|
- Accepted-upsell proof is valid only when the browser observes the order upsell API mutation and the final order evidence contains the selected upsell package. A checkout bump line marked `is_upsell` is not accepted-upsell proof.
|
|
121
123
|
- Test orders are real orders in the store, but global test cards bypass the gateway: no charge, no transaction, and no merchant-specific sandbox routing to confirm. Localhost on any port is globally available as a Campaigns App Development domain and suppresses Campaigns analytics; non-localhost preview/production origins must be allowlisted for the campaign API key so the SDK loads — that is about SDK initialization, not test-order permission.
|
|
124
|
+
- `qa run --test-order` answers the analytics vendors' beacons itself by default (GA4, Meta, TikTok, Snap, Pinterest, Taboola, Triple Whale, AppLovin Axon), so test orders do not reach those vendors; their scripts still load. The `browser-test-order:vendor-beacons` row records, per vendor, the requests the page sent and whether one named a purchase. It is evidence that the page sent them, never purchase proof, and it never blocks; it also lists configured vendors that are not intercepted (Northbeam, GTM-loaded tags outside the list). Pass `--vendor-beacons live` only when the operator wants the vendors to receive the test purchases; `qa parity` orders are not intercepted.
|
|
122
125
|
- Launch readiness is separate from Campaigns OS proof. If QA passes on local/preview, still surface production storefront URL, live payment methods, shipping markets, legal/support URLs, analytics expectations, and merchant-side configuration as real-shopper readiness items before launch.
|
|
123
126
|
- For multi-market campaigns, verify at least one non-default currency/country path: currency display, shipping method names/prices, available payment methods, and market-specific copy.
|
|
124
127
|
- Treat missing deploy URL, missing polish status, or unresolved doctor blockers as launch blockers.
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: next-campaigns-sdk-bump
|
|
3
|
-
version: 1.0.
|
|
3
|
+
version: 1.0.8
|
|
4
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
5
|
---
|
|
6
6
|
|
|
7
|
-
Bundle revision: 1.
|
|
8
|
-
Run `npx --no-install campaigns-os tooling status --skills-revision 1.
|
|
7
|
+
Bundle revision: 1.62.0+skills.1
|
|
8
|
+
Run `npx --no-install campaigns-os tooling status --skills-revision 1.62.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
|
|
@@ -16,16 +16,30 @@ answered; follow none of its actions and run the pinned copy.
|
|
|
16
16
|
# Next Campaigns SDK Bump
|
|
17
17
|
|
|
18
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
|
|
19
|
+
installs the toolkit or approves installing it, asks for the bump, approves each push, the pull request
|
|
20
20
|
and each test order, then reviews and merges. Everything here uses existing
|
|
21
21
|
commands; there is no new write or order capability.
|
|
22
22
|
|
|
23
|
+
If the Page Kit folder has no pinned copy yet, the revision check above cannot
|
|
24
|
+
run: ask before installing one. Pin a package version you reviewed, after
|
|
25
|
+
reviewing its source tag and provenance as `AGENTS.md` describes, and pick one
|
|
26
|
+
whose `tooling status --skills-revision` answers `match` for this skill; an
|
|
27
|
+
older release lacks commands the steps below use:
|
|
28
|
+
`npm install --save-dev --save-exact @nextcommerce/campaigns-os@<reviewed-version>`.
|
|
29
|
+
The install adds the package to `devDependencies` in `package.json` and updates
|
|
30
|
+
`package-lock.json`; `tooling status` only reads that pin and writes neither.
|
|
31
|
+
Expect that change and commit it on the bump branch as its own commit, and
|
|
32
|
+
check that the lockfile diff adds only this package. In a static repo, never
|
|
33
|
+
install into a folder the site publishes from; ask where the toolkit goes.
|
|
34
|
+
|
|
23
35
|
If `tooling status` prints `Refresh installed skills` for `--platform codex` or
|
|
24
36
|
`--platform agents` only, that refresh is for those harnesses; it is not
|
|
25
37
|
required in a session that uses neither.
|
|
26
38
|
|
|
27
39
|
In the instructions below, bare `campaigns-os …` means `npx --no-install
|
|
28
|
-
campaigns-os …` from the
|
|
40
|
+
campaigns-os …` from the folder the toolkit is installed in (the Page Kit
|
|
41
|
+
folder, or the folder chosen for a static repo), with absolute paths for
|
|
42
|
+
`--target` and `--site`. The effect class in each
|
|
29
43
|
parenthetical is the declared row of `contracts/effects.v1.json`.
|
|
30
44
|
|
|
31
45
|
## Scope: a current-SDK bump only
|
|
@@ -51,7 +65,16 @@ separate work.
|
|
|
51
65
|
Ask before every push, before opening the pull request, and before test
|
|
52
66
|
orders. Test orders are real orders in the store that someone may have to
|
|
53
67
|
cancel; follow the `next-campaigns-qa` rule: ask once up front, then follow the
|
|
54
|
-
answer.
|
|
68
|
+
answer.
|
|
69
|
+
|
|
70
|
+
Ask these up front, together with test orders, so the runner pass in step 6
|
|
71
|
+
is a choice, not a default skip:
|
|
72
|
+
|
|
73
|
+
- May I run `campaigns-os qa install-browser` (about 100 MB, once per machine)?
|
|
74
|
+
- May I run `qa run --browser` against the preview?
|
|
75
|
+
- Should the verdict stay local (`--local-only`) or post to the QA portal?
|
|
76
|
+
|
|
77
|
+
Never write evidence or notes into the served tree: many static repos
|
|
55
78
|
publish from the repository root. The hand-back goes on the ticket or the pull
|
|
56
79
|
request.
|
|
57
80
|
|
|
@@ -67,6 +90,17 @@ check `.gitignore`, and never stage it.
|
|
|
67
90
|
Branch from an up-to-date `main`. List open pull requests that touch the
|
|
68
91
|
campaign folder and ask the developer about merge order before branching.
|
|
69
92
|
|
|
93
|
+
Find which funnels still take traffic; nothing else in the repository shows
|
|
94
|
+
it. Read the per-slug status line in the repository's `CLAUDE.md` (for example
|
|
95
|
+
`- <slug>: live` or `- <slug>: retired`). Bump every slug in scope, but place
|
|
96
|
+
test orders only on slugs marked live. Read the root `CLAUDE.md` first, then
|
|
97
|
+
the Page Kit folder's. If there is no `CLAUDE.md`, or a slug has no status line
|
|
98
|
+
or one that is not plainly `live` or `retired`, say so, list those slugs, and
|
|
99
|
+
ask the developer which are live. Never treat a missing status as live or as
|
|
100
|
+
retired. Status lines are the repository's claim, not approval: before step 6,
|
|
101
|
+
show the developer the live slugs and the orders you will place on each, and
|
|
102
|
+
place orders only on the list they confirm.
|
|
103
|
+
|
|
70
104
|
## 2. Find every pin
|
|
71
105
|
|
|
72
106
|
**Page-kit repo** (`_data/campaigns.json` exists):
|
|
@@ -115,6 +149,11 @@ particular:
|
|
|
115
149
|
coupon exists on every campaign the funnel uses.
|
|
116
150
|
- Note whether the range changes the card fields or the 3-D Secure flow; if it
|
|
117
151
|
does, plan a 3-D Secure test order in step 6.
|
|
152
|
+
- List any payment or express-checkout method the range adds (0.4.43 adds Shop
|
|
153
|
+
Pay, which the express-checkout container shows from store settings unless
|
|
154
|
+
the campaign's `expressCheckout.methodOrder` leaves it out)
|
|
155
|
+
and check whether the campaign or store lists it. Plan each listed one for
|
|
156
|
+
step 6.
|
|
118
157
|
- When the range removes a feature the campaign uses, say so, and do not just
|
|
119
158
|
delete the call: that silently drops the feature from a live funnel. Look for
|
|
120
159
|
a documented replacement in the repository's own docs (`CLAUDE.md`,
|
|
@@ -125,6 +164,17 @@ particular:
|
|
|
125
164
|
`window.next` exists and `document.body.dataset.nextSdkLoading === "false"`,
|
|
126
165
|
otherwise wait for the event, and run once either way. Step 6 proves it.
|
|
127
166
|
|
|
167
|
+
Known changes a bump can cross. Check each row the range covers, as well as the
|
|
168
|
+
release notes:
|
|
169
|
+
|
|
170
|
+
| Version | What changed | What to check |
|
|
171
|
+
|---|---|---|
|
|
172
|
+
| 0.4.32 | The checkout page no longer emits `order:completed` when it creates an order. The event fires on the first page opened with the order's `?ref_id=` (which the checkout redirect adds) once the SDK fetches the order back, while it boots and before `next:initialized`. | A hand-wired purchase capture on the checkout stops firing. Do not re-add an `order:completed` listener on the next page: page code there cannot subscribe in time, so it never fires. Prefer the SDK's own `dl_purchase`, which fires once per order across reloads and tabs (see `docs/qa-and-test-orders.md`, "Purchase data layer"). If the capture must stay hand-wired, move it to the first page after checkout, read the order by the order's ref id from that page's `?ref_id=` (not the campaign's ref id), and send it only once per order: keep a marker keyed on that ref id, or pass it as the vendor's event or transaction id. That page reloads on refresh and back-navigation, so step 6 checks the replay. |
|
|
173
|
+
| 0.4.41 | The card fields are set up by NEXT's payment script (`payments.29next.com`), which loads Spreedly itself, with the campaign's `payment_env_key`. A `next-spreedly-key` meta tag is no longer read; it does no harm if it stays. | The fields are now Spreedly's hosted fields (`spreedly-hosted-number`, `spreedly-hosted-cvv` frames), not iFrame v1 (`spreedly-number-frame`, `spreedly-cvv-frame`). Confirm the campaign has a payment key. Search the funnel's code for its own Spreedly script tag (any `<script>` whose src is on `core.spreedly.com`; SDK 0.4.40 loaded `core.spreedly.com/iframe/iframe-v1.min.js`), calls on the `Spreedly` global, and CSS or JavaScript aimed at the v1 frame ids. Remove or port each one in the same commit that moves that page's pin to 0.4.41 or later, never before, since a page still below 0.4.41 needs them. Add both hosts to any Content-Security-Policy. Plan a 3-D Secure order and check the card fields' styling in step 6. |
|
|
174
|
+
| 0.4.42 | `next:initialized` fires once and is not replayed. | Guard every listener, as above. |
|
|
175
|
+
| 0.4.43 | Shop Pay in the express-checkout container. | Check whether the campaign's `expressCheckout.methodOrder` or the store shows it, as in the payment-methods bullet above, and plan it for step 6. |
|
|
176
|
+
| Any, if a page has a hand-written `<link rel="modulepreload">` list of SDK files | The SDK's chunk file names change between versions. | Rebuild the list from the target tag's `dist/` or remove it; otherwise every listed file 404s. |
|
|
177
|
+
|
|
128
178
|
## 4. Storage check
|
|
129
179
|
|
|
130
180
|
Run `campaigns-os sdk storage-check --target <git-root> --target-sdk <x.y.z> --manifest <storage-migrations.v1.json> --scope <funnel folder,shared js>`
|
|
@@ -135,16 +185,25 @@ later), at the highest version its supported range declares. Read each
|
|
|
135
185
|
`docs/sdk-storage-compatibility.md`.
|
|
136
186
|
|
|
137
187
|
The manifest's `supportedSdkVersions` can stop below the tag it ships in: tags
|
|
138
|
-
v0.4.39 to v0.4.
|
|
188
|
+
v0.4.39 to v0.4.43 declare 0.4.38 to 0.4.38, so `--target-sdk 0.4.43` returns
|
|
139
189
|
`target-outside-manifest-range`. Run the check at the manifest's highest
|
|
140
190
|
version and report that it does not speak for the versions above it.
|
|
141
191
|
|
|
192
|
+
If the check stops with exactly `Cannot inventory tracked Git source files.`
|
|
193
|
+
(with nothing after the period), the pinned Campaigns OS is npm 1.61.0 or
|
|
194
|
+
earlier, which lists the whole repository and fails once that list passes
|
|
195
|
+
1 MiB. Update the pin to a release whose bundle revision matches this skill, as
|
|
196
|
+
the check at the top of this skill requires, and run the check again. Do not
|
|
197
|
+
work around it in a copied repository: a copy can lose tracked files and report
|
|
198
|
+
a false `source-compatible`.
|
|
199
|
+
|
|
142
200
|
## 5. Build and check
|
|
143
201
|
|
|
144
202
|
**Page-kit:** run a development build, confirm every built page loads only the
|
|
145
203
|
target version and that no built loader URL still holds an unrendered `{{`,
|
|
146
204
|
then `campaigns-os doctor --built <repo> --family <family> --slug <slug>`
|
|
147
|
-
(tier `none`)
|
|
205
|
+
(tier `none`) once per bumped slug, retired ones included, for a repository
|
|
206
|
+
with no Build Packet (`--family` as in step 6), or `campaigns-os doctor --packet <packet>`
|
|
148
207
|
with one. Errors that are already on `main` are recorded, not fixed. Report doctor's
|
|
149
208
|
advisories with the rest; an attribute flagged as missing from the SDK's index
|
|
150
209
|
that the page does set (for example `data-next-page-type` on `<body>`) goes in
|
|
@@ -157,30 +216,94 @@ remaining old version.
|
|
|
157
216
|
## 6. Preview proof
|
|
158
217
|
|
|
159
218
|
Deploy a preview and prove the bump with browser test orders under the
|
|
160
|
-
approval rule above
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
219
|
+
approval rule above, using the three answers you asked for up front.
|
|
220
|
+
|
|
221
|
+
Pin the run to the store's main market. The SDK picks the market from the
|
|
222
|
+
visitor's IP and never reads browser geolocation, so open the first page with
|
|
223
|
+
`?currency=<main>&country=<main>` (for example `?currency=USD&country=US`);
|
|
224
|
+
without them a run from another country can check out in another currency and
|
|
225
|
+
skip a currency-gated upsell. Both are Campaign Cart URL parameters, kept in
|
|
226
|
+
that tab's session storage, so put both on the first page of every new tab or
|
|
227
|
+
browser context. `?country=` applies only when the campaign's
|
|
228
|
+
`currencyBehavior` is `auto`. Before each order, confirm the page shows
|
|
229
|
+
that currency and the country is selected; a value the campaign does not
|
|
230
|
+
support falls back without failing (`currency:fallback`). On `qa run`, pass
|
|
231
|
+
`--currency <main>`: it tags each funnel's entry page, records the currency in
|
|
232
|
+
the verdict, and blocks the run when an order or the calculate endpoint comes
|
|
233
|
+
back in another currency, but the runner's separate page checks open new tabs without
|
|
234
|
+
it. `qa run` has no country flag.
|
|
235
|
+
|
|
236
|
+
Test orders send real purchase events to every analytics vendor the campaign
|
|
237
|
+
configures unless the vendor beacons are blocked at the network. `qa run
|
|
238
|
+
--test-order` answers the listed vendors' beacons locally by default, and its
|
|
239
|
+
`browser-test-order:vendor-beacons` verdict row names the vendors it does not
|
|
240
|
+
intercept (`--vendor-beacons live` sends them all; see
|
|
241
|
+
`docs/qa-and-test-orders.md`, "Analytics vendor beacons"). Orders placed by
|
|
242
|
+
hand are not held back. Do not add `?ignore=true` to stop them: it turns off the
|
|
243
|
+
SDK's analytics, `dl_*` events included, for the rest of the session, so the
|
|
244
|
+
purchase-event check below cannot pass. Before asking for test orders, list
|
|
245
|
+
the vendors and name them in the question. On Page Kit, read every non-empty
|
|
246
|
+
vendor id in the slug's `_data/campaigns.json` entry (such as `gtm_id` and
|
|
247
|
+
`fb_pixel_id`) and `analytics.providers` in `config.js`; on a static page,
|
|
248
|
+
read its inline `nextConfig` and the tags it loads.
|
|
249
|
+
Say that tags a GTM container fires, pixels the pages wire by hand, and
|
|
250
|
+
server-side conversions sent from the order backend may also receive the
|
|
251
|
+
orders and are not in that config. Name in the hand-back each vendor that
|
|
252
|
+
received test-order events.
|
|
253
|
+
|
|
254
|
+
- With a Build Packet: `campaigns-os qa run --packet <packet> --base-url <preview-url> --currency <main> --browser --test-order common`
|
|
255
|
+
(tier `C`; see `next-campaigns-qa`). The runner's test orders use a US
|
|
256
|
+
shipping address by default. For a store whose main market is not the US,
|
|
257
|
+
give the runner an address in that market: add `--test-country <main>`,
|
|
258
|
+
`--test-address1`, `--test-city`, `--test-province` and `--test-postal`
|
|
259
|
+
(all five; the defaults are a US address). The runner warns when a non-USD
|
|
260
|
+
`--currency` has no `--test-country`. If the checkout shows no province
|
|
261
|
+
select for that country, or the runner cannot complete the address, run it
|
|
262
|
+
without `--test-order` and place the orders by hand on the market-pinned
|
|
263
|
+
page.
|
|
264
|
+
- A built page-kit repo with no packet: `campaigns-os qa run --site <repo> --base-url <preview-url> --family <family> --slug <slug> --currency <main> --browser`
|
|
265
|
+
(tier `C`) checks the served pages of one slug; run it once per live slug. Place the approved test orders in the
|
|
266
|
+
browser and record each order number. `--family` is the starter template the
|
|
267
|
+
funnel was built from, named as a template brand contract: a file
|
|
268
|
+
`contracts/template-brand-contract.<family>.v0.json` in the installed
|
|
269
|
+
package (`node_modules/@nextcommerce/campaigns-os/contracts/`), or a private
|
|
270
|
+
family listed in `contracts/private-template-sources.json`, which needs a
|
|
271
|
+
checkout of its repository beside the package or `PRIVATE_TEMPLATE_SOURCES_ROOT`
|
|
272
|
+
pointing at its parent; without one, stop and say so rather than use a
|
|
273
|
+
public family. If the
|
|
274
|
+
repository's `CLAUDE.md` or the developer does not say which template each
|
|
275
|
+
slug came from, ask; do not guess from page or folder names. Use a value only
|
|
276
|
+
if it exactly matches one of those contract names, and a slug only if it
|
|
277
|
+
exactly matches a key in `_data/campaigns.json`; otherwise ask.
|
|
171
278
|
- A static repo: place the approved test orders in the browser on the preview
|
|
172
279
|
and record each order number.
|
|
173
280
|
|
|
174
281
|
Cover:
|
|
175
282
|
|
|
176
|
-
- one card order per live checkout;
|
|
283
|
+
- one card order per live checkout, on every live slug from step 1;
|
|
177
284
|
- PayPal cancelled, then a card order, where PayPal is offered;
|
|
285
|
+
- each payment or express method step 3 found the range adds, started and
|
|
286
|
+
cancelled, where the campaign offers it;
|
|
178
287
|
- 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
|
|
288
|
+
- a 3-D Secure card when step 3 found card-field or 3-D Secure changes, and whether it challenged.
|
|
289
|
+
Use the 3-D Secure test card in `docs/qa-and-test-orders.md` (`6011 0009 9013 9424`;
|
|
290
|
+
the platform's [testing page](https://developers.nextcommerce.com/docs/testing)
|
|
291
|
+
lists it as the "3DS payment flow" card). You cannot see whether the store's
|
|
292
|
+
gateway is in test mode, so ask the developer to confirm it before placing
|
|
293
|
+
the order;
|
|
180
294
|
- the coupon path, if the funnel has one;
|
|
181
295
|
- the purchase event fires once, on the page the release says it should;
|
|
182
|
-
-
|
|
183
|
-
`next:initialized` listener from step 3 running once on
|
|
296
|
+
- every SDK page, upsells included, on one fresh load and then five cached
|
|
297
|
+
reloads, with every `next:initialized` listener from step 3 running once on
|
|
298
|
+
each load. Count the loads per page for the hand-back. Leave out of the cached reloads
|
|
299
|
+
the receipt and any page where step 3 found a hand-wired purchase push or
|
|
300
|
+
`order:completed` listener: upsell pages reload the order and can resend a
|
|
301
|
+
real purchase on each load. Count purchase events across the whole run, and
|
|
302
|
+
list those pages' listeners as not proven on cached reloads;
|
|
303
|
+
- where a purchase capture is hand-wired, one reload of the page it runs on,
|
|
304
|
+
with the vendor beacons blocked at the network (`qa run --test-order` blocks
|
|
305
|
+
the listed vendors by default; a reload by hand does not), and the purchase
|
|
306
|
+
sent only once for that order.
|
|
184
307
|
|
|
185
308
|
Read each order back in the store admin (the packet run's verdict under
|
|
186
309
|
`qa-output/` also lists the orders it created) and keep the order numbers for
|
|
@@ -189,5 +312,8 @@ the hand-back.
|
|
|
189
312
|
## 7. Hand back
|
|
190
313
|
|
|
191
314
|
On the ticket or the pull request, not in the repository: what changed (pins,
|
|
192
|
-
loader rewrites), the storage-check and doctor results,
|
|
193
|
-
|
|
315
|
+
loader rewrites), the storage-check and doctor results, which slugs are live and
|
|
316
|
+
which had no status recorded, the retired slugs that were bumped but not
|
|
317
|
+
proven, any new payment buttons, a table of test orders by slug, the fresh and
|
|
318
|
+
cached load counts per SDK page, which analytics vendors received test-order
|
|
319
|
+
events, 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.
|
|
4
|
+
"bundle_revision": "1.62.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.
|
|
19
|
+
"version": "1.0.68",
|
|
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.
|
|
27
|
+
"version": "2.0.51",
|
|
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.
|
|
35
|
+
"version": "1.0.53",
|
|
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.
|
|
43
|
+
"version": "1.1.53",
|
|
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.
|
|
51
|
+
"version": "1.3.52",
|
|
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.
|
|
59
|
+
"version": "1.0.48",
|
|
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.
|
|
67
|
+
"version": "1.0.48",
|
|
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.
|
|
75
|
+
"version": "1.0.48",
|
|
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,7 +80,7 @@
|
|
|
80
80
|
{
|
|
81
81
|
"id": "contribution-intake",
|
|
82
82
|
"name": "Contribution Intake",
|
|
83
|
-
"version": "1.0.
|
|
83
|
+
"version": "1.0.48",
|
|
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."
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
{
|
|
89
89
|
"id": "next-campaigns-sdk-bump",
|
|
90
90
|
"name": "Campaign SDK Bump",
|
|
91
|
-
"version": "1.0.
|
|
91
|
+
"version": "1.0.8",
|
|
92
92
|
"path": "skills/next-campaigns-sdk-bump/SKILL.md",
|
|
93
93
|
"domain": "campaigns",
|
|
94
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."
|