@nextcommerce/campaigns-os 1.54.0 → 1.55.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/CHANGELOG.md +84 -0
- package/CONTEXT.md +8 -5
- package/README.md +26 -12
- package/compatibility.json +1 -1
- package/contracts/release-ledger.json +441 -0
- package/contracts/supported-surface.json +2 -2
- package/docs/brand-theme-bridge.md +10 -0
- package/docs/build-packet.md +35 -19
- package/docs/campaigns-os-build-flow.md +1 -1
- package/docs/effects.md +2 -5
- package/docs/local-setup.md +1 -1
- package/docs/orientation-contract-reference.md +1 -1
- package/docs/qa-and-test-orders.md +55 -11
- package/docs/runtime-readiness.md +1 -1
- package/docs/skills-revision.md +10 -10
- package/docs/supported-surface.md +1 -1
- package/docs/workflow-findings-sidecar.md +57 -2
- package/package.json +3 -1
- package/schemas/campaigns-os-run-record.v0.schema.json +20 -15
- 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 +3 -3
- package/skills/next-campaigns-os/SKILL.md +3 -3
- package/skills/next-campaigns-os-setup/SKILL.md +3 -3
- package/skills/next-campaigns-polish/SKILL.md +3 -3
- package/skills/next-campaigns-qa/SKILL.md +4 -4
- package/skills.json +10 -10
- package/src/adapter-decision-contract.mjs +26 -12
- package/src/brand-theme.mjs +44 -8
- package/src/campaign-identity.mjs +33 -4
- package/src/cli.mjs +36 -59
- package/src/consent.mjs +3 -2
- package/src/design-source-publication.mjs +1 -1
- package/src/deviation.mjs +2 -1
- package/src/doctor/checks.mjs +16 -6
- package/src/doctor/next-step.mjs +16 -6
- package/src/invocation.mjs +4 -3
- package/src/lifecycle.mjs +88 -6
- package/src/local-preview-policy.mjs +6 -0
- package/src/login.mjs +2 -1
- package/src/polish-browser.mjs +8 -2
- package/src/polish-node.mjs +6 -1
- package/src/polish-readability.mjs +2 -2
- package/src/qa-browser.mjs +521 -92
- package/src/qa-cart-entry.mjs +29 -6
- package/src/qa-node.mjs +144 -39
- package/src/qa-verdict-publish.mjs +2 -1
- package/src/run-record.mjs +46 -34
- package/src/sdk-markup.mjs +41 -1
- package/src/stage-ledger.mjs +14 -2
- package/src/stage-record.mjs +50 -13
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,90 @@
|
|
|
2
2
|
|
|
3
3
|
Notable supported-surface changes are recorded here.
|
|
4
4
|
|
|
5
|
+
## [1.55.0] - 2026-10-07
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
Run Records now carry the optional `qa_verdict_publish.reason` from the QA publish decision and `closed_by` from the command path that closed the record. The reason distinguishes loopback, portal managed, consent, flag, default, and local spec decisions; the closer distinguishes `run end`, QA auto-end, stale sweep, and direct `run-record`. The unused `agent_usage` field and its `--agent-*` input flags are removed. Re-emitting an older record with `agent_usage` replaces it with a fresh record without carrying forward its prior remit state. `qa publish` posts its verdict but cannot stamp that older record as published.
|
|
10
|
+
|
|
11
|
+
QA observations in a Run Record now carry the verdict's `run_id`, the build fingerprint recorded for that verdict, and whether it differs from the build recorded in the Assembly Report. A rebuild without `record build` still reads `stale: false` when those recorded fingerprints match; doctor's `built_output.fingerprint_stale` checks the output on disk. Currency is unknown when either fingerprint is missing or the report's QA stage belongs to a different verdict.
|
|
12
|
+
|
|
13
|
+
Lifecycle stages now carry prompt `wait_ms` and, on a blocked doctor or QA exit, up to five distinct `finding_codes`. Run lifecycle separates exit 2 invocations in `needs_input_count` from other non-zero exits in `failure_count`. Legacy journal entries keep wait unknown, while new commands without prompts record zero. Duration continues to include prompt wait.
|
|
14
|
+
|
|
15
|
+
## [1.54.0+agent.10] - 2026-10-07
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
Generated brand themes keep sale, discount, badge, rating, star, strike, border and announcement colours out of primary and CTA roles when those names describe the selector's subject. Brand and button names keep their role. Header, navigation and button colours continue to map as they do on main, including selectors after CSS at-rules. When a design has no CTA token or button background, the existing CTA fallback warning asks the operator to confirm an accent colour that may be decorative.
|
|
20
|
+
|
|
21
|
+
## [1.54.0+agent.9] - 2026-10-07
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
After a page-kit build, `record build --adapter-decision <key>=<value>[,<key>=<value>...]` records the choices that are true for that build on the Assembly Report. Put all pairs in one flag: a repeated flag keeps only the last list. The build prompt now asks for actual values instead of supplying a completed status. Help and the Build Packet list the allowed values. `wrapper_policy` is selected at intake with `prepare-build --wrapper-policy` or the source-html manifest option; `record build` refuses it and names those options. Doctor checks leftover document wrappers against the effective recorded conversion status, and its adapter warnings name the recording command. The packet and Build Context are unchanged by `record build`. `template_files_copied` remains object-valued proof outside the flag.
|
|
26
|
+
|
|
27
|
+
## [1.54.0+agent.8] - 2026-10-07
|
|
28
|
+
|
|
29
|
+
### Changed
|
|
30
|
+
|
|
31
|
+
- `next` asks for Polish when a theme waiver or changed build leaves it owed on a local preview. It asks for deploy until that stage is recorded, even if the Build Packet already has a preview URL.
|
|
32
|
+
- After a changed build, `next` asks for QA again when the last QA verdict names the old build, even if its recorded stage still says completed.
|
|
33
|
+
- `--help` commands leave lifecycle and deviation journals untouched. Re-running `start` later in a campaign is treated as re-intake rather than a deviation.
|
|
34
|
+
|
|
35
|
+
## [1.54.0+agent.7] - 2026-10-07
|
|
36
|
+
|
|
37
|
+
### Added
|
|
38
|
+
|
|
39
|
+
`qa run --currency <code>` runs QA in one of a campaign's currencies. The run adds `?currency=<CODE>` to each funnel's entry URL, so the HTTP fetch, the `--browser` load and the reported `entry_urls` carry it, and each test-order path's first page load (the checkout probe, or the entry page or checkout when that load comes first) carries it too. Campaign Cart keeps the currency for the rest of that tab's session, so the runner adds it to no other load (an upsell page or a receipt reload goes without it), while a later load of the entry URL still carries it because that URL is tagged. Query and tracking parameters already on the URL are kept. The code must be three letters and is upper-cased (`gbp` runs as `GBP`); anything else, including no value, an empty value or a list, is refused before any request. The flag takes one code per run; given twice, the last one is used. `qa parity --currency` is refused, and so is `--currency` with `--legacy-api-test-order`, whose direct API order would be placed in the default currency. Before this, a run could prove only the default currency, and testing another took a hand-made copy of the built site that forced the parameter. The stored verdict removes URL queries, so the currency is recorded as `evidence.currency` on the entry page's `http:<page_id>` assertion; an entry URL that does not parse gets `evidence.currency_not_applied` with the reason instead. The verdict schema is unchanged, and a run without the flag is unchanged.
|
|
40
|
+
|
|
41
|
+
## [1.54.0+agent.6] - 2026-10-07
|
|
42
|
+
|
|
43
|
+
### Fixed
|
|
44
|
+
|
|
45
|
+
Doctor now blocks receipt order lines hidden by a cart-state visibility condition, including when only the CampaignSpec identifies the receipt page. When the campaign API key comes directly from the Build Packet or CampaignSpec, or from the environment variable named by Build Packet `campaign.api_key_source`, doctor blocks built pages with a different key even if those pages agree with one another. A mismatch names each wrong key source and the pages using it, so the built keys can be replaced before test orders begin.
|
|
46
|
+
|
|
47
|
+
## [1.54.0+agent.5] - 2026-10-07
|
|
48
|
+
|
|
49
|
+
### Fixed
|
|
50
|
+
|
|
51
|
+
- `qa run --test-order` orders a multi-unit bundle card the way the checkout shows it. A starter bundle card declares its package and per-package quantity in `data-next-bundle-items` (`bundle-2x` is `[{"packageId":1,"quantity":2}]`), and the runner now reads them there:
|
|
52
|
+
- `--select-package 1:2` finds the card whose items carry package 1 at quantity 2 even when no inner node repeats the package id. A card matches when any one of its declared items is that package at that quantity, so a kit card declaring `[{"packageId":1,"quantity":2},{"packageId":4,"quantity":1}]` is found by `4:1`; when a card declares the item alone as well, that card is preferred. Before, it failed `selected_bundle` with "no rendered card exposes that package or bundle identity".
|
|
53
|
+
- `--cart 1:2` clicks that same card. Before, it clicked the first `[data-next-package-id="1"]`, which on the starter partial is the one-unit card's inner node, so the order carried one unit. Without `--select-package`, a `--cart` ref the selected card already carries at that quantity clicks nothing, and a ref that no bundle card declares is clicked as before. The cards are read again before each ref, so a card a selector renders after an earlier `--cart` click is found.
|
|
54
|
+
- Beside `--select-package`, `--cart` never clicks another card in the selector group of the card `--select-package` chose, for bundle cards and plain package cards alike; a card in no `[data-next-bundle-selector]`, `[data-next-selector-id]` or `[data-next-cart-selector]` container counts as in that group, since its own wrapper does not say which cards it swaps with. A `--cart` ref that card carries is left as it is; a ref an order bump or a card in another selector group carries is applied through that control; any other ref is left unapplied and named in the `selected_bundle` detail (`--cart 3:1 not applied: only another card in the selector --select-package chose carries it`), and the order is reconciled against the card actually selected. Before, `--select-package 1:2 --cart 3:1` switched to the package-3 card while `selected_bundle` still reported the two-unit card, and `--select-package 1:2 --cart 1:2,2:1` reset the order to one unit.
|
|
55
|
+
- The `browser-order-display-parity` row reconciles the order against the packages and quantities every selected bundle card declares, however many cards are selected. Before, it counted the card's `data-next-bundle-id` as a displayed package and resolved lines at one unit per package, so a correct two-unit order failed with "displayed but never charged: 1".
|
|
56
|
+
- Without `--select-package`, the same row now fails when an explicit `--cart <ref:qty>` is not in the order at that quantity: the order carried another quantity, as when `--cart 1:2` produced a one-unit order, or no line for the package at all, as when `--cart 1:2,3:1` on a swap-mode selector kept only the `3:1` card. Its message names the requested and persisted units, or says the order carries no line for the package. A bare `--cart <ref>` is not judged. The row's message now also names `--select-package` quantity mismatches, which already failed the row but were not named in its message.
|
|
57
|
+
- Checkouts built from plain package cards (`[data-next-package-id]`, no bundle cards) are selected and reconciled as before, except that `--cart` beside `--select-package` no longer switches to another card in the chosen card's selector group, and without `--select-package` an explicit `--cart <ref:qty>` the order does not carry at that quantity fails the display-parity row.
|
|
58
|
+
|
|
59
|
+
## [1.54.0+agent.4] - 2026-10-07
|
|
60
|
+
|
|
61
|
+
### Fixed
|
|
62
|
+
|
|
63
|
+
`qa run` now calls `ready_with_exceptions` a passing proof, lists each exception once with its id and page (and severity when present), and tells the agent to report exceptions to the operator. `next` gives the same guidance when QA completed with exceptions while keeping the closeout action.
|
|
64
|
+
|
|
65
|
+
The completed-pipeline prompt and Build Packet guide now point to `record build` for repeated build work and distinguish local-serve recording from hosted deploy instructions. The starter-palette advisory prints the named-human argument required by a recorded `theme waive`, while help and QA guidance distinguish it from the one-run `--theme-waive` form. QA prompts, help, and guides ask once, up front, before typed-card test orders unless the operator already said they are fine for this campaign. Those orders leave real store records even though no transaction or money movement occurs. `ready` and `blocked` QA text keeps its existing finding format.
|
|
66
|
+
|
|
67
|
+
## [1.54.0+agent.3] - 2026-10-07
|
|
68
|
+
|
|
69
|
+
### Fixed
|
|
70
|
+
|
|
71
|
+
The `qa run --browser` primary-CTA row (`browser-primary-cta:<page>`) no longer fails `missing_route_cta` on checkout and upsell pages that Campaign Cart routes. Since 1.53.0 those pages are checked, but the check found a route only through a control's own link, and these pages have none: a checkout advances through the submit button of its `<form data-next-checkout="form">`, and an upsell through its `data-next-upsell-action="add"` and `"skip"` controls, which are `href="#"` links. So every SDK-routed checkout and upsell failed, the starter templates' own pages included, while the `route-link:*` rows and test orders passed on the same pages. QA now takes the route a page declares for these controls, from the same page fields the `route-link:*` rows read. On a checkout, the checkout form's submit button leads to the page's next route, whether it is `type="submit"` or has no `type` attribute, which submits the form just the same; express-checkout wallet buttons are not. On an upsell or downsell, the add control leads to the page's accept route and the skip control to its decline route, but only inside a `data-next-upsell` container: Campaign Cart binds upsell actions nowhere else, so an action outside one routes nothing. The control is checked as the primary CTA when that route is the page's next route, and its contrast, size and text are measured as before. On checkout, upsell and downsell pages these declared controls are the only controls a form can route. Any other form's `action`, for example a newsletter sign-up beside the checkout form, routes nothing there, even when it is the next route. So a page whose only route to the next page is such a form still fails `missing_route_cta`. On every other page a form's `action` is now the route of that form's own submit button only, and never inside the checkout form, which Campaign Cart submits itself. So bundle cards, wallet buttons and other controls inside a form no longer become CTA candidates because the form has an action; before, they did, and the row turned to `manual_review`. A page with no control leading to its next route still fails `missing_route_cta`.
|
|
72
|
+
|
|
73
|
+
QA now recognises `data-next-upsell-action="accept"` and `data-next-upsell-action="decline"` on upsell pages. Campaign Cart treats `accept` exactly like `add` and `decline` exactly like `skip`, but QA only looked for `add` and `skip`. So on a page written with `accept` / `decline`, the test-order upsell step failed with `Missing upsell control`, the `browser-upsell-control:<page>:accept` and `:decline` rows read `not found`, the primary-CTA row failed `missing_route_cta`, and the `route-link:<page>:accept` and `:decline` rows fell to `manual_review` when the route URL was not in the page's HTML. QA now takes either spelling everywhere it looks for an upsell control: the test-order upsell step and its timeout evidence, the upsell-page readiness wait, the rendered upsell-control rows, the primary-CTA route rule, and the static `route-link:*` rows, including the check for a `data-upsell-proxy` button, which forwards to the in-offer action with its own spelling; Polish readability's contrast check also takes either spelling for its `upsell_accept` and `upsell_decline` roles. Pages written with `add` / `skip` are checked as before, and when a page has neither spelling, QA's messages still name `add` and `skip`. Other values are still not upsell controls.
|
|
74
|
+
|
|
75
|
+
## [1.54.0+agent.2] - 2026-10-07
|
|
76
|
+
|
|
77
|
+
### Changed
|
|
78
|
+
|
|
79
|
+
Repository CI and contributor tooling only; the published package is unchanged. CI runs the unit and browser lanes as two shards each on separate runners, and a newer push to a pull request cancels that pull request's older run; pushes to `main` always finish. `npm run check:fast` runs the checks of CI's types and contracts lanes and the three PR-only release gates against `origin/main` in under a minute, and `npm run hooks:install` installs it as a pre-push hook for the clone and its worktrees (`docs/small-pr-review-path.md`).
|
|
80
|
+
|
|
81
|
+
## [1.54.0+agent.1] - 2026-10-07
|
|
82
|
+
|
|
83
|
+
### Changed
|
|
84
|
+
|
|
85
|
+
- When `start`, `prepare-build` or `build` refuses to overwrite a report that already carries stage evidence, the message now says that, if the brief or CampaignSpec changed, `record brief` or `record spec` binds it while keeping that evidence. Before, it offered only `--force`, which resets the recorded stages.
|
|
86
|
+
- README: the build steps and the `record` command list now include `record theme`, `record deploy` (bound to the build it probed), `record brief` and `record spec`. The SDK examples take `--target-sdk <x.y.z>` instead of 0.4.38. The `tooling status` note no longer says npm has no dist-tag, the Node floor reads 20.19.0 as in `engines`, and `--force` is described as moving completed records to stage history.
|
|
87
|
+
- `docs/quickstart.md`: a QA run against a local-address base URL keeps its verdict local by default, whatever the telemetry consent.
|
|
88
|
+
|
|
5
89
|
## [1.54.0] - 2026-10-07
|
|
6
90
|
|
|
7
91
|
Ships the same-surface changes 1.53.0+agent.1 through +agent.11 (+agent.6 and +agent.8 were never used), including the `qa run --test-order` fix for Campaign Cart SDK 0.4.41 card fields (+agent.5) and the starter catalog, SDK attribute index and support policy at 0.4.41 (+agent.10, +agent.11).
|
package/CONTEXT.md
CHANGED
|
@@ -22,9 +22,10 @@ The deterministic decision point that blocks `next polish|deploy|qa` and
|
|
|
22
22
|
`qa run` when theme inspect proved a brand theme is generatable, the campaign
|
|
23
23
|
ships commerce pages, and the brand layer is neither applied (after
|
|
24
24
|
`next-core.css`) nor explicitly waived. Evaluated once in the doctor
|
|
25
|
-
(`derived.theme_gate`) and consumed identically by `next` and QA. A waiver
|
|
26
|
-
|
|
27
|
-
on the Assembly Report
|
|
25
|
+
(`derived.theme_gate`) and consumed identically by `next` and QA. A waiver is
|
|
26
|
+
the only sanctioned bypass: `theme waive --reason "<why>" --waived-by "<named
|
|
27
|
+
human>"` records it on the Assembly Report; `qa run --theme-waive "<reason>"`
|
|
28
|
+
waives the gate for that one run only.
|
|
28
29
|
_Avoid_: advisory warning, recommendation, soft check
|
|
29
30
|
|
|
30
31
|
**Template Brand Contract**:
|
|
@@ -676,8 +677,10 @@ and your username. The patterns are the value, not the raw dumps."
|
|
|
676
677
|
|
|
677
678
|
**Domain Expert**: "No. Campaigns OS should show QA as the Expected Proof Step.
|
|
678
679
|
Browser QA still needs the deployed URL (and SDK-origin allowlist confirmation
|
|
679
|
-
for non-localhost)
|
|
680
|
-
|
|
680
|
+
for non-localhost). Typed-card test orders use global test cards that bypass
|
|
681
|
+
the gateway and move no money, but each leaves a real store order record.
|
|
682
|
+
Unless the operator has already said test orders are fine for this campaign,
|
|
683
|
+
ask once, up front, before placing them; then proceed. There is no permission flag."
|
|
681
684
|
|
|
682
685
|
**Developer**: "Build and polish finished, but there is no QA verdict."
|
|
683
686
|
|
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ This toolkit gives campaign developers and AI coding tools a clear path for asse
|
|
|
13
13
|
7. Hand off to `next-campaigns-build`.
|
|
14
14
|
8. Run build/lint and record the build with `campaigns-os record build`, then install the Campaigns OS Playwright browser once with `campaigns-os qa install-browser`.
|
|
15
15
|
9. Run `next-campaigns-polish`, serve the current build, run the mandatory `campaigns-os polish capture` producer, then record Polish with `campaigns-os record polish --evidence <file>`.
|
|
16
|
-
10. Deploy a preview.
|
|
16
|
+
10. Deploy a preview. For a local preview (`--deploy-target local-serve`), serve the current build and record it with `campaigns-os record deploy --base-url <loopback route root>`; a later `record build` of different output makes the deploy owed again. `record deploy` takes only a loopback route root; for a hosted preview, deploy through your host and follow `next` for what to record.
|
|
17
17
|
11. Run `next-campaigns-qa` against the tested URL.
|
|
18
18
|
12. Record launch blockers and follow-up work.
|
|
19
19
|
|
|
@@ -289,8 +289,8 @@ npm run campaigns-os -- prepare-build --spec <spec.json> --source <html-dir> --t
|
|
|
289
289
|
npm run campaigns-os -- doctor --packet <page-kit-repo>/campaign-runtime.build.json
|
|
290
290
|
npm run campaigns-os -- page-kit sync --packet <page-kit-repo>/campaign-runtime.build.json --dry-run
|
|
291
291
|
npm run campaigns-os -- checkpoint waive --packet <packet.json> --gate source_html.producer_provenance --page <page_id> --reason "<why>" --waived-by "<named human>" --review-condition "<trigger>" --dry-run
|
|
292
|
-
npm run campaigns-os -- sdk storage-check --target <campaign-git-root> --target-sdk
|
|
293
|
-
npm run campaigns-os -- sdk repin --target <static-campaign-repo> --target-sdk
|
|
292
|
+
npm run campaigns-os -- sdk storage-check --target <campaign-git-root> --target-sdk <x.y.z> --manifest <sdk-storage-manifest.json> --scope <campaign,shared> --json
|
|
293
|
+
npm run campaigns-os -- sdk repin --target <static-campaign-repo> --target-sdk <x.y.z>
|
|
294
294
|
npm run campaigns-os -- standardize --target <page-kit-repo-or-cpk-repo> --json
|
|
295
295
|
npm run campaigns-os -- theme inspect --packet <page-kit-repo>/campaign-runtime.build.json --json
|
|
296
296
|
npm run campaigns-os -- theme generate --packet <page-kit-repo>/campaign-runtime.build.json --json
|
|
@@ -302,6 +302,10 @@ npm run qa:install-browser
|
|
|
302
302
|
npm run campaigns-os -- next polish --packet <packet.json> --report <assembly-report.json>
|
|
303
303
|
npm run campaigns-os -- polish capture --packet <packet.json> --base-url <served-current-build-url>
|
|
304
304
|
npm run campaigns-os -- record polish --packet <packet.json> --evidence <polish-evidence.json>
|
|
305
|
+
npm run campaigns-os -- record theme --packet <packet.json>
|
|
306
|
+
npm run campaigns-os -- record deploy --packet <packet.json> --base-url <loopback-route-root>
|
|
307
|
+
npm run campaigns-os -- record brief --packet <packet.json> --brief <campaign-build-brief.yaml>
|
|
308
|
+
npm run campaigns-os -- record spec --packet <packet.json>
|
|
305
309
|
npm run campaigns-os -- next qa --packet <packet.json> --report <assembly-report.json>
|
|
306
310
|
npm run campaigns-os -- qa resolve --packet <packet.json>
|
|
307
311
|
npm run campaigns-os -- qa run --packet <packet.json> --base-url <preview-url> --browser --test-order common
|
|
@@ -320,14 +324,24 @@ output path alone does not create or refresh the file. Build/QA producer
|
|
|
320
324
|
commands continue to record their own stages.
|
|
321
325
|
|
|
322
326
|
Record a stage's completion with `record setup`, `record build` (after every
|
|
323
|
-
rebuild)
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
+
rebuild), `record polish --evidence <file>`, `record theme` (once the brand layer
|
|
328
|
+
is linked) and, for a local preview, `record deploy --base-url <loopback route
|
|
329
|
+
root>`, rather than hand-editing `.campaign-runtime/build-context.json` or
|
|
330
|
+
`.campaign-runtime/assembly-report.json`. A recorded deploy is bound to the
|
|
331
|
+
build it probed, so a later `record build` of different output makes it owed
|
|
332
|
+
again. When the brief or the CampaignSpec changes after stages are recorded, save
|
|
333
|
+
it with `record brief` or `record spec`: an unchanged or reformatted save keeps
|
|
334
|
+
every stage, a material change moves the superseded build, Polish and QA records
|
|
335
|
+
to stage history instead of discarding them, and `next` names the stage that is
|
|
336
|
+
owed again. Re-running
|
|
337
|
+
`start` or `prepare-build` over recorded stages is refused without `--force`.
|
|
338
|
+
Each `record` command validates what it would write, refuses a stage `next` has
|
|
339
|
+
not reached, and writes nothing on failure; `--dry-run` runs the checks without
|
|
340
|
+
writing. See
|
|
327
341
|
[Build Packet](docs/build-packet.md) and [Polish evidence](docs/polish-evidence.md).
|
|
328
342
|
|
|
329
343
|
Do not use `prepare-build --force` merely to refresh a catalog path: doctor
|
|
330
|
-
already resolves the running toolkit's catalog, and force
|
|
344
|
+
already resolves the running toolkit's catalog, and `--force` resets the recorded stages (completed build, Polish and QA records move to stage history).
|
|
331
345
|
|
|
332
346
|
|
|
333
347
|
`qa run` automatically checks contract-governed authored price, recurring
|
|
@@ -339,8 +353,8 @@ Run `tooling status` before a build session. It names the install mode — a
|
|
|
339
353
|
pinned package (`npx`, or a consumer's `node_modules`) or a git checkout — and
|
|
340
354
|
checks that the package metadata, CLI entrypoint, and installed Campaigns OS
|
|
341
355
|
skills agree. For a checkout it also reports branch, upstream, and ahead/behind;
|
|
342
|
-
for a package install the pinned
|
|
343
|
-
|
|
356
|
+
for a package install the pinned version is the freshness answer, and the
|
|
357
|
+
status does not compare it with npm's `latest` dist-tag. Neither mode makes agent skills current on
|
|
344
358
|
its own: when skills are stale, run the refresh command the status output
|
|
345
359
|
prints (it names each stale platform, through the same prefix you ran
|
|
346
360
|
`tooling status` with), then read the `SKILL.md` files it lists under `Read now`
|
|
@@ -393,7 +407,7 @@ registry — so a spec rule is authored once and reaches internal teams and
|
|
|
393
407
|
third-party agencies alike. The rules are authored in TypeScript with no heavy
|
|
394
408
|
dependencies and compiled to plain ESM (`npm run build:spec`, on `prepare`) and a
|
|
395
409
|
stable subpath export `@nextcommerce/campaigns-os/campaign-spec`, so consumers run
|
|
396
|
-
them on `engines.node` (>=20) with no type-stripping or build step of their own.
|
|
410
|
+
them on `engines.node` (>=20.19.0) with no type-stripping or build step of their own.
|
|
397
411
|
See [`campaign-spec/README.md`](campaign-spec/README.md).
|
|
398
412
|
|
|
399
413
|
## Docs
|
|
@@ -422,7 +436,7 @@ See [`campaign-spec/README.md`](campaign-spec/README.md).
|
|
|
422
436
|
|
|
423
437
|
## Status
|
|
424
438
|
|
|
425
|
-
Developer preview. Build output still needs the normal proof gates: build/lint evidence, polish plus package-owned page-load capture against the served current build, preview deploy or local dev URL, Playwright browser QA, and typed-card test-order proof via `--test-order common
|
|
439
|
+
Developer preview. Build output still needs the normal proof gates: build/lint evidence, polish plus package-owned page-load capture against the served current build, preview deploy or local dev URL, Playwright browser QA, and typed-card test-order proof via `--test-order common`. Global test cards bypass the gateway and create no transactions, but each test order leaves a real store order record. Unless the operator has already said test orders are fine for this campaign, ask once, up front, before placing test orders; then proceed. There is no permission flag. Localhost on any port is a Campaigns App Development domain, so SDK calls are allowed and analytics are suppressed there; non-localhost preview/production origins still need SDK origin allowlist confirmation.
|
|
426
440
|
|
|
427
441
|
Launch readiness is separate from Campaigns OS proof. Before real shoppers see a campaign, confirm the production storefront URL, live payment methods, shipping markets, legal/support URLs, analytics expectations, and merchant-side configuration.
|
|
428
442
|
|