@nextcommerce/campaigns-os 1.47.0 → 1.50.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +307 -0
- package/README.md +30 -3
- package/agents/claude/CLAUDE.md +6 -3
- package/agents/codex/AGENTS.md +6 -4
- package/agents/copilot/copilot-instructions.md +3 -2
- package/agents/cursor/campaigns-os.mdc +3 -3
- package/compatibility.json +1 -1
- package/contracts/commerce-surface-catalog.json +17 -17
- package/contracts/effects.v1.json +173 -0
- package/contracts/release-ledger.json +798 -0
- package/contracts/supported-surface.json +4 -4
- package/contracts/template-brand-contract.shared-commerce.v0.json +1 -1
- package/docs/brand-theme-bridge.md +12 -6
- package/docs/build-packet.md +9 -4
- package/docs/campaign-build-brief.md +25 -28
- package/docs/local-setup.md +7 -2
- package/docs/orientation-contract-reference.md +1 -1
- package/docs/qa-and-test-orders.md +70 -9
- package/docs/runtime-readiness.md +1 -1
- package/docs/skills-revision.md +10 -10
- package/package.json +1 -1
- package/schemas/campaign-runtime-build-packet.v0.schema.json +4 -0
- package/schemas/campaigns-os-qa-verdict.v0.schema.json +8 -3
- 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 +9 -4
- package/skills/contribution-intake/SKILL.md +3 -3
- package/skills/next-campaigns-build/SKILL.md +5 -4
- 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 +6 -5
- package/skills/next-campaigns-qa/SKILL.md +3 -3
- package/skills.json +10 -10
- package/src/brand-theme.mjs +13 -2
- package/src/cli.mjs +17 -12
- package/src/content-residue.mjs +18 -90
- package/src/doctor/checks.mjs +21 -29
- package/src/doctor/inspect.mjs +13 -3
- package/src/doctor/next-step.mjs +4 -0
- package/src/gate-actions.mjs +8 -0
- package/src/install-mode.mjs +0 -8
- package/src/invocation.mjs +3 -1
- package/src/local-preview-policy.mjs +92 -0
- package/src/page-kit-sdk-version.mjs +8 -1
- package/src/polish-node.mjs +26 -2
- package/src/progress-node.mjs +5 -1
- package/src/qa-binding-evidence.mjs +22 -1
- package/src/qa-browser.mjs +92 -14
- package/src/qa-node.mjs +43 -6
- package/src/readback.mjs +19 -10
- package/src/source-prep.mjs +1 -1
- package/src/stage-record.mjs +303 -22
- package/src/theme-gate.mjs +3 -3
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_note": "The downstream contract manifest. Everything listed here is SUPPORTED SURFACE: consumers (campaigns-agent, campaign-builder, the private ops repo, page-kit campaign repos) may depend on it, and changing it is a deliberate act — hashed entries require a surface_version bump in the same change (check-supported-surface.mjs --base, mirroring the skills.json bump gate), named entries must keep existing at their path, cli_commands must keep resolving in the CLI dispatch, package_exports must stay exported, and every entry must ship in the npm pack (files[] coverage). Anything NOT listed here — src/** internals, scripts/** checkers, examples/**, prompts/**, contracts/** other than this file and the entries named[] below (the orientation contract, the release ledger, and the consumer-facing orientation fixtures) — is implementation: consumers may read it for context but must not build on it, and it can change without notice. Rationale and the compatibility promise: docs/supported-surface.md.",
|
|
3
|
-
"surface_version": "1.
|
|
3
|
+
"surface_version": "1.50.0",
|
|
4
4
|
"package_exports": [
|
|
5
5
|
"./commercial-journey",
|
|
6
6
|
"./commercial-parity",
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"sha256": "f310c1b7844d9b1994864d15858ff0c6f17efc1e5285ba193d181bdb2dd4be2f"
|
|
67
67
|
},
|
|
68
68
|
"schemas/campaign-runtime-build-packet.v0.schema.json": {
|
|
69
|
-
"sha256": "
|
|
69
|
+
"sha256": "5002529c5979c4d8fef7e298de82ebdf625ffbd11f5284ba684d96d173788d62"
|
|
70
70
|
},
|
|
71
71
|
"schemas/campaign-spec.v4.schema.json": {
|
|
72
72
|
"sha256": "af56c3de638d3c4e1fd5df8c2d733754d9ad16caa23b5bec92ce3a6f71bd0271"
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"sha256": "3c40fd79f218d1b95f0424f9a2b67db140a306329e2ca02793e2740d3afded59"
|
|
85
85
|
},
|
|
86
86
|
"schemas/campaigns-os-qa-verdict.v0.schema.json": {
|
|
87
|
-
"sha256": "
|
|
87
|
+
"sha256": "8c689d29850b2b894c17438ee4411363033bae6f805820af53b7a04a5693d0e0"
|
|
88
88
|
},
|
|
89
89
|
"schemas/campaigns-os-doctor-output.v0.schema.json": {
|
|
90
90
|
"sha256": "87866e619d2a18f01a208a1682cb14a2079f61df51c642f4e1902b6e6bce0ce5"
|
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
"sha256": "dfc9abed38d456969e47a21f606d308a03bdf036f3466f7d6e47a602747dacf4"
|
|
121
121
|
},
|
|
122
122
|
"contracts/effects.v1.json": {
|
|
123
|
-
"sha256": "
|
|
123
|
+
"sha256": "75cdd0bc33788d8d6af10c995f362987725f622bf42700f1b70b39bbd87e6878"
|
|
124
124
|
},
|
|
125
125
|
"schemas/campaigns-os-effects.v1.schema.json": {
|
|
126
126
|
"sha256": "3eadd22169ab98bc7c2f682af2751267605170581182158d96be035b0cfe44dc"
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
},
|
|
56
56
|
"asset_pin": {
|
|
57
57
|
"repo": "NextCommerceCo/campaign-cart-starter-templates",
|
|
58
|
-
"sha": "
|
|
58
|
+
"sha": "37a8d945db4c360739ded98348814cfd632da94f",
|
|
59
59
|
"path": "src/<family>/assets/<asset>",
|
|
60
60
|
"note": "asset_sha256 is the sha256 of each shipped starter asset at this commit (the commerce-surface-catalog _synced_from_sha pin; the bytes are identical across every family). A served asset whose bytes hash to the shipped value is the untouched starter asset and counts as residue even though its markup names no method; different bytes mean it was edited in place. check-template-doctrine verifies these hashes against the pinned checkout."
|
|
61
61
|
},
|
|
@@ -151,8 +151,9 @@ When `theme inspect` reports `can_generate: true` and the campaign ships
|
|
|
151
151
|
commerce pages (checkout/upsell/downsell/receipt), the gate **blocks**
|
|
152
152
|
`next polish`, `next deploy`, `next qa`, and `qa run` until one of:
|
|
153
153
|
|
|
154
|
-
- the brand layer is generated and recorded as applied
|
|
155
|
-
(`report.theme.status: applied`,
|
|
154
|
+
- the brand layer is generated, linked and recorded as applied with
|
|
155
|
+
`campaigns-os record theme --packet <p>` (`report.theme.status: applied`,
|
|
156
|
+
`load_order: after-next-core`), or
|
|
156
157
|
- an explicit waiver is recorded:
|
|
157
158
|
`campaigns-os theme waive --packet <p> --reason "<why>" --waived-by "<named human>"`
|
|
158
159
|
(optionally `--expires-at <ISO>`; placeholders such as "operator" are refused), or
|
|
@@ -197,8 +198,12 @@ If a fresh `brand-theme.css` exists:
|
|
|
197
198
|
3. Preserve SDK-owned runtime surfaces: `data-next-*`, package selectors,
|
|
198
199
|
payment fields, totals, submit controls, receipt templates, route meta tags,
|
|
199
200
|
and SDK JavaScript.
|
|
200
|
-
4.
|
|
201
|
-
|
|
201
|
+
4. Rebuild, run `campaigns-os record build --packet <p>`, then
|
|
202
|
+
`campaigns-os record theme --packet <p>`. It reads each built commerce
|
|
203
|
+
page's stylesheet links and records `report.theme.status`, `css_path`,
|
|
204
|
+
`commerce_pages`, `load_order` and evidence. It refuses, writing nothing,
|
|
205
|
+
when a page that loads `next-core.css` does not load the brand layer after
|
|
206
|
+
it, or when no built commerce page loads `next-core.css`.
|
|
202
207
|
|
|
203
208
|
### Where next-core.css belongs
|
|
204
209
|
|
|
@@ -212,8 +217,9 @@ stylesheets off those pages and list them only in the frontmatter styles of
|
|
|
212
217
|
the pages that render family components, often just checkout.
|
|
213
218
|
|
|
214
219
|
`report.theme.commerce_pages` is the list of pages where the brand layer was
|
|
215
|
-
applied
|
|
216
|
-
example `commerce_pages: ["checkout"]`.
|
|
220
|
+
applied. `record theme` writes it from the built pages: every commerce page
|
|
221
|
+
that loads `next-core.css`, for example `commerce_pages: ["checkout"]`. A page
|
|
222
|
+
that loads neither stylesheet is left out and noted in the evidence. The theme gate does not compare this
|
|
217
223
|
list with the funnel. It passes on `report.theme.status: applied` with
|
|
218
224
|
`load_order: after-next-core`. The gate's own `commerce_pages` output is a
|
|
219
225
|
different field: every checkout, upsell, downsell, receipt or thank-you page
|
package/docs/build-packet.md
CHANGED
|
@@ -970,8 +970,9 @@ starter palette is acceptable>" --waived-by "<named human>"`, optionally
|
|
|
970
970
|
(status and severity — never `fail`) and keeps the shipped palette visible in
|
|
971
971
|
the verdict; or hand-author the brand
|
|
972
972
|
layer — write `brand-theme.css`, list it after `next-core.css` in commerce-page
|
|
973
|
-
frontmatter styles, rebuild, and record
|
|
974
|
-
`load_order: after-next-core
|
|
973
|
+
frontmatter styles, rebuild, `record build`, and `record theme`, which records
|
|
974
|
+
`report.theme.status: applied` with `load_order: after-next-core` from the
|
|
975
|
+
built pages. Nothing waives the gate on the operator's
|
|
975
976
|
behalf. See [Brand Theme Bridge](./brand-theme-bridge.md) for both lanes in
|
|
976
977
|
full.
|
|
977
978
|
|
|
@@ -1237,7 +1238,9 @@ loopback host (`127.0.0.1`, `[::1]`) with a ready line naming the
|
|
|
1237
1238
|
`http://localhost:<port>/` fallback, and warns (`deploy.local_serve_url`) when
|
|
1238
1239
|
the recorded URL is neither.
|
|
1239
1240
|
`next` at the deploy stage then hands off a serve-locally prompt and action
|
|
1240
|
-
instead of a ship-to-host one
|
|
1241
|
+
instead of a ship-to-host one, and the served URL is recorded with
|
|
1242
|
+
`campaigns-os record deploy --packet <p> --base-url <url>` (the record command
|
|
1243
|
+
table below). The directory to serve is `_site/`; for a
|
|
1241
1244
|
root-served campaign (`campaign.route_root: "/"`) the handoff adds that pages
|
|
1242
1245
|
are served at site-root paths while assets keep the `/<public_route_slug>/`
|
|
1243
1246
|
prefix, so `_site/` needs the same rewrite of root-level page routes onto
|
|
@@ -1453,7 +1456,7 @@ Each `manifest.pages[]` entry MAY carry a `source_hash` field — the sha256 hex
|
|
|
1453
1456
|
Behavior:
|
|
1454
1457
|
|
|
1455
1458
|
- Optional on the producer side. Producers that don't emit `source_hash` (pre-Slice-6 manifests, template-stock, hand-authored) keep working; doctor's drift check is silent without a hash to compare.
|
|
1456
|
-
- Warning severity only. A drift never blocks a build
|
|
1459
|
+
- Warning severity only. A drift never blocks a build. The hash doctor compares is the one intake recorded in the packet, so editing the manifest alone does not clear the warning: re-running `start` or `prepare-build` with `--force` records the current file, and also clears recorded stage evidence. A revision made after build belongs in the page-kit source under `src/<route>/`; the source HTML stays the design provenance.
|
|
1457
1460
|
- The warning names the file path and includes both hashes (truncated to 12 chars) so the operator can confirm which file diverged without re-running the producer.
|
|
1458
1461
|
|
|
1459
1462
|
### Reference AI-generated producer
|
|
@@ -1609,6 +1612,8 @@ hand-editing `.campaign-runtime/` JSON:
|
|
|
1609
1612
|
| `campaigns-os record setup --packet <p>` | Build Context `scaffold.required=false` (`handoff_skill` next-campaigns-build) and `stages.setup` completed | the campaign output directory (`assembly.output_dir`) does not exist, or there is no Build Context or Assembly Report |
|
|
1610
1613
|
| `campaigns-os record build --packet <p>` | `stages.assembly` completed with `build_fingerprint` = doctor's `derived.build_output_fingerprint.value`, `source_package_material_fingerprint` = the report's Design Source Package material fingerprint when present, and `stages.polish` reset to `required` (`required_by` build, `required_for` qa) unless its evidence is bound to this exact output | doctor cannot compute the fingerprint (no `_site/<public_route_slug>/`), setup is still required, or `stages.setup` is not terminal |
|
|
1611
1614
|
| `campaigns-os record polish --packet <p> --evidence <file>` | `stages.polish` from the file (`docs/polish-evidence.md` §7: completed, blocked or skipped), bound to doctor's current fingerprint; `report.theme.repair_loop_defect` when the file sets it | build is not recorded for the current output, the file has a shape error (named by field), or, for a completed status, the polish gate doctor evaluates would not pass on the result |
|
|
1615
|
+
| `campaigns-os record theme --packet <p>` | `report.theme`: status `applied`, `load_order` `after-next-core`, `css_path`, `commerce_pages` and per-page evidence read from each built commerce page's stylesheet links; any earlier theme waiver is cleared | build is not recorded for the current output, the campaign ships no commerce pages, a built commerce page that loads `next-core.css` does not load `brand-theme.css` (or `checkout-brand.css`) after it or links one missing from the built output, or no built commerce page loads `next-core.css` |
|
|
1616
|
+
| `campaigns-os record deploy --packet <p> --base-url <url>` | the packet's `deploy.preview_url` and `stages.deploy` completed with the URL in `outputs` and one evidence line per built page that answered (each page is requested under the URL first) | the packet is not `local-serve`, the URL is not a loopback origin naming the campaign's route root, a built page does not answer 2xx, polish is not recorded, the built output changed since build was recorded, or the theme gate is blocked |
|
|
1612
1617
|
|
|
1613
1618
|
Each command also refuses a stage `next` has not reached: while doctor's
|
|
1614
1619
|
prepare-build gate is set (`next` answers prepare-build) or while an earlier
|
|
@@ -62,34 +62,31 @@ Doctor warns when generated guided drafts still need answers, a brief allows pay
|
|
|
62
62
|
|
|
63
63
|
Existing template residue, theme, pricing, and built-output checks continue to run. The brief gives those checks business intent instead of replacing them.
|
|
64
64
|
|
|
65
|
-
##
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
marker (`content_residue.needs_merchant_input`) and countdown chrome rendered
|
|
91
|
-
without verified offer urgency on a brief-backed build
|
|
92
|
-
(`content_residue.unverified_urgency`).
|
|
65
|
+
## The Merchant's Own Claims Are Not Reviewed
|
|
66
|
+
|
|
67
|
+
Proof and urgency content the merchant supplies is the merchant's
|
|
68
|
+
responsibility, not Campaigns OS's: reviews and testimonials, ratings and
|
|
69
|
+
counts, "Verified Purchase" labels, recent-purchase popups, stock counters,
|
|
70
|
+
countdowns, guarantees and press mentions. The doctor does not scan for it and
|
|
71
|
+
QA does not assert on it. When the prepared source design carries these
|
|
72
|
+
elements, the build reproduces them as designed. The starter templates ship
|
|
73
|
+
without some of them; that is not a reason to drop the source's.
|
|
74
|
+
|
|
75
|
+
What the doctor does scan built output for is template residue: the starter
|
|
76
|
+
templates' own demo strings and bracket-style stubs
|
|
77
|
+
(`content_residue.demo_residue`, a warning). It also warns on promo copy
|
|
78
|
+
claiming a discount above the CampaignSpec maximum
|
|
79
|
+
(`template_contract.discount_claim_residue`, or
|
|
80
|
+
`template_contract.discount_claim_unverified` when the spec sets no maximum),
|
|
81
|
+
because that copy disagrees with the campaign's own pricing. Nothing downstream
|
|
82
|
+
blocks on either.
|
|
83
|
+
|
|
84
|
+
Two content checks do block: the needs-merchant-input marker
|
|
85
|
+
(`content_residue.needs_merchant_input`), and, on a brief-backed build only,
|
|
86
|
+
starter countdown chrome the brief payload does not verify
|
|
87
|
+
(`content_residue.unverified_urgency`). Use the brief to record which claims
|
|
88
|
+
are approved and which language is forbidden (see the high-impact questions
|
|
89
|
+
above).
|
|
93
90
|
|
|
94
91
|
## QA Policy Scope
|
|
95
92
|
|
package/docs/local-setup.md
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
# Local campaign setup
|
|
2
2
|
|
|
3
|
-
For a new campaign,
|
|
3
|
+
For a new campaign, create an empty working folder and run this from it:
|
|
4
4
|
|
|
5
5
|
```sh
|
|
6
|
-
npm install --save-exact next-campaign-page-kit@0.2.0 && npm install --save-dev --save-exact @nextcommerce/campaigns-os@1.
|
|
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.50.0 && npx --no-install campaigns-os tooling setup --target . --platform claude
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
+
`npm init -y` gives the folder its own `package.json`. Without one, npm
|
|
10
|
+
installs into the nearest parent folder that has a `package.json` or
|
|
11
|
+
`node_modules`, so a campaign folder created inside another project would add
|
|
12
|
+
page-kit and the toolkit to that project instead.
|
|
13
|
+
|
|
9
14
|
Review the release source/provenance before installation as described in
|
|
10
15
|
`AGENTS.md`. npm installs the dependencies first; `--no-install` then runs only
|
|
11
16
|
the project's installed CLI. Page-kit stays a runtime dependency and the
|
|
@@ -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.
|
|
29
|
+
Supported surface at generation time: `1.50.0`
|
|
30
30
|
|
|
31
31
|
## Forward compatibility
|
|
32
32
|
|
|
@@ -55,9 +55,10 @@ the toolkit runs that loop in a fixed order:
|
|
|
55
55
|
with it locally (the parity step renders it to a temp dir, and the deploy
|
|
56
56
|
host renders it from the committed source).
|
|
57
57
|
2. **Serve and prove.** Serve `_site/` on localhost (the `next deploy` handoff
|
|
58
|
-
names the directory and any root-route rewrite)
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
names the directory and any root-route rewrite) and run `polish capture`
|
|
59
|
+
against it. Once polish is recorded, `record deploy --packet <p> --base-url
|
|
60
|
+
<url>` records the URL on `deploy.preview_url` and the deploy stage; then run
|
|
61
|
+
`qa run --browser` and the typed-card order paths against it.
|
|
61
62
|
3. **Prove the pin on the production output.** Before committing, run
|
|
62
63
|
|
|
63
64
|
```bash
|
|
@@ -96,6 +97,32 @@ recapture. A hosted target (`netlify`, `cloudflare-pages`, …) is unaffected:
|
|
|
96
97
|
its build stage renders production as before and `page-kit parity` refuses the
|
|
97
98
|
packet (`local_proof.parity.not_local_serve`).
|
|
98
99
|
|
|
100
|
+
### Missing evidence carried forward on the local preview
|
|
101
|
+
|
|
102
|
+
On a `local-serve` packet served from a loopback host (`localhost`,
|
|
103
|
+
`127.0.0.1`, `[::1]`, for both `deploy.preview_url` and `--base-url`), some
|
|
104
|
+
missing evidence is carried forward as a warning instead of blocking the
|
|
105
|
+
loop. The campaign must still prove its commerce there: store and campaign
|
|
106
|
+
binding, routes, SDK loading, prices and a typed-card order. Only these
|
|
107
|
+
checks are carried forward:
|
|
108
|
+
|
|
109
|
+
| Check | When |
|
|
110
|
+
| --- | --- |
|
|
111
|
+
| `polish.evidence_missing`, `polish.report_missing` | Polish was never recorded for this build. |
|
|
112
|
+
| `polish.hidden_eager_media.no_capturable_routes` | Every mapped page is template stock (`skip_reason`), so polish capture has no design route to capture. |
|
|
113
|
+
| `polish.hidden_eager_media.capture_malformed` | Only when no page-load capture was recorded at all. |
|
|
114
|
+
| Template-residue severity | With `theme_gate.nothing_generatable`, the starter template is the design, so residue findings are warnings rather than blockers. |
|
|
115
|
+
|
|
116
|
+
A carried-forward gate has status `carried_forward`. Doctor reports it as a
|
|
117
|
+
warning starting "Carried forward on the local preview"; `next` moves past
|
|
118
|
+
polish to deploy and QA; QA records it as a `warn` row, so the verdict is at
|
|
119
|
+
best `ready_with_exceptions`. The evidence is reported as missing, never as
|
|
120
|
+
passed. Any other check keeps its meaning. A hosted preview or production
|
|
121
|
+
packet, and a `local-serve` packet served from any other host, gets the strict
|
|
122
|
+
gates. `record polish` and the waiver commands also keep them strict. Progress
|
|
123
|
+
snapshots record a carried-forward gate as `not_applicable`, because their
|
|
124
|
+
schema has no carried-forward state.
|
|
125
|
+
|
|
99
126
|
## Resolve
|
|
100
127
|
|
|
101
128
|
Use resolve before a full run:
|
|
@@ -482,7 +509,15 @@ the three checks and each `evidence.checks[]` entry carries `kind`
|
|
|
482
509
|
(`family_shell` or `sdk_wiring`).
|
|
483
510
|
The upsell and checkout bundle price checks count the SDK's
|
|
484
511
|
`[data-next-bundle-display*='price']` alongside the contract's price rows; a
|
|
485
|
-
hidden, zero-size or empty bundle-display node does not count.
|
|
512
|
+
hidden, zero-size or empty bundle-display node does not count. A checkout that
|
|
513
|
+
shows no price because QA opened it directly, with an empty SDK cart and no
|
|
514
|
+
package selection of its own, is `skipped` rather than failed:
|
|
515
|
+
`pricing.checkout_price_visible` records `cart_count` and
|
|
516
|
+
`checkout_selection_surface` and says so. That checkout's cart is filled on
|
|
517
|
+
an earlier page, for example by a landing link carrying `forcePackageId`, and
|
|
518
|
+
the test order enters it from there. A checkout with its own package
|
|
519
|
+
selection, or a filled cart, still fails when no price shows. If the cart
|
|
520
|
+
probe itself fails, the row stays failed and records `empty_cart_probe_error`.
|
|
486
521
|
Promoted template families must also have
|
|
487
522
|
`contracts/template-brand-contract.<family>.v0.json`; QA emits a blocker if the
|
|
488
523
|
selected family is missing its brand/residue/pricing contract instead of
|
|
@@ -1749,6 +1784,17 @@ shared real inbox rather than a synthetic one). When neither is set, the runner
|
|
|
1749
1784
|
falls back to a single stable synthetic address — still one reused customer, but
|
|
1750
1785
|
not deliverable.
|
|
1751
1786
|
|
|
1787
|
+
Reusing one customer has one cost. The platform refuses an order whose customer,
|
|
1788
|
+
items and total match one it accepted or is still processing in the last 30
|
|
1789
|
+
minutes ("Duplicate order detected, order not created"). A successful test order
|
|
1790
|
+
does not hold that window, so the paths of one run do not collide. Two QA runs
|
|
1791
|
+
against the same campaign at once do, and so can a rerun soon after an attempt
|
|
1792
|
+
that died mid-submit. QA reports it on the path's `browser-test-order` row as
|
|
1793
|
+
`order create rejected: HTTP 400: Duplicate order detected …` followed by
|
|
1794
|
+
`duplicate_order` and the remedy: re-run with a different `--test-email-prefix`
|
|
1795
|
+
(or `--test-email`), or wait. The shipping address is not part of the match, so
|
|
1796
|
+
changing `--test-address1` does not help.
|
|
1797
|
+
|
|
1752
1798
|
The browser driver intentionally behaves like a user:
|
|
1753
1799
|
|
|
1754
1800
|
- package selection uses rendered `[data-next-package-id]` controls when
|
|
@@ -1882,19 +1928,32 @@ expectations, and commerce-ref validation. A doctor-clean non-packet run means
|
|
|
1882
1928
|
matches a spec". Treat it as a residue/visual gate, not equivalent to a
|
|
1883
1929
|
packet-driven QA pass.
|
|
1884
1930
|
|
|
1885
|
-
### Per-page credential
|
|
1931
|
+
### Per-page credential binding
|
|
1886
1932
|
|
|
1887
1933
|
Canonical `qa run` emits `page-binding:<page_id>` in the existing `api-metadata`
|
|
1888
1934
|
family, with `campaigns-os-page-binding/v0` evidence (typed in the verdict schema).
|
|
1889
|
-
`match` means the
|
|
1935
|
+
`match` means the page's credential equals the expected credential;
|
|
1890
1936
|
`mismatch` is a blocker. `unknown` requires manual review. All three carry
|
|
1891
1937
|
`identity: not_verified`: credential equality never proves a unique Campaign App
|
|
1892
1938
|
ID, and no App ID is inferred from `campaignId` or `next-campaign-id`.
|
|
1893
1939
|
|
|
1894
1940
|
Expected data reuses the commercial QA resolver (packet, then spec, then an
|
|
1895
1941
|
explicit supported environment source). Conflicting authored values are unknown.
|
|
1896
|
-
|
|
1897
|
-
|
|
1942
|
+
|
|
1943
|
+
With `--browser`, the row comes from the key the Campaign Cart SDK actually
|
|
1944
|
+
sent. The SDK sends it as `Authorization` on every Campaigns API request, and
|
|
1945
|
+
the browser pass reads that header on each page it loads. The values are
|
|
1946
|
+
compared in memory and dropped: the evidence records
|
|
1947
|
+
`observation: sdk_request`, `source_kinds: ["sdk_request"]`, and `match` when
|
|
1948
|
+
every request carried the expected credential or `mismatch` when any carried
|
|
1949
|
+
another. This works whatever the
|
|
1950
|
+
page's scripts look like. A page that sent no Campaigns API request, or a run
|
|
1951
|
+
with no single expected credential, keeps the static row described below.
|
|
1952
|
+
|
|
1953
|
+
Without `--browser`, or for such a page, the row is a static read of what the
|
|
1954
|
+
page declares (`observation: static_declaration`). The SDK loads
|
|
1955
|
+
`window.nextConfig.apiKey` before `next-api-key` at boot, so meta wins at
|
|
1956
|
+
runtime; the static read deliberately reports differing declarations as a
|
|
1898
1957
|
conflict rather than certifying one. It does not observe SDK execution.
|
|
1899
1958
|
|
|
1900
1959
|
The bounded HTML loader is reused. HTML is parsed without execution; JavaScript
|
|
@@ -1919,7 +1978,9 @@ ASCII whitespace and compared case-insensitively as the browser does; classic
|
|
|
1919
1978
|
`built_output.script_syntax` in [the Build Packet doc](build-packet.md).
|
|
1920
1979
|
|
|
1921
1980
|
External executable scripts other than the recognized jsDelivr Campaign Cart
|
|
1922
|
-
loader
|
|
1981
|
+
loader or index are inspected only on the page's origin. Three Campaign Cart
|
|
1982
|
+
paths count as the SDK and are never fetched: `dist/loader.js` (the one the
|
|
1983
|
+
starter templates load), `dist/index.js` and `public/loader.js`. Each page admits at most
|
|
1923
1984
|
6 such references; each run fetches at most 24 distinct URLs (deduplicated),
|
|
1924
1985
|
256 KiB per response and 6 MiB aggregate, 5 seconds per request including body
|
|
1925
1986
|
read (at most 30 seconds of sequential config requests per page). Redirects,
|
|
@@ -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.2`, validated by `schemas/campaigns-os-runtime-recipe.v1.schema.json` (`Campaigns OS Runtime Recipe v1`). Supported surface at generation time: `1.
|
|
11
|
+
Recipe kind `campaigns-os-node-v1`, revision `1.0.2`, validated by `schemas/campaigns-os-runtime-recipe.v1.schema.json` (`Campaigns OS Runtime Recipe v1`). Supported surface at generation time: `1.50.0`.
|
|
12
12
|
|
|
13
13
|
## What this is
|
|
14
14
|
|
package/docs/skills-revision.md
CHANGED
|
@@ -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.
|
|
19
|
+
"bundle_revision": "1.50.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.
|
|
28
|
+
with the prefix**. `1.50.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.
|
|
40
|
+
Bundle revision: 1.50.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.
|
|
51
|
+
npx --no-install campaigns-os tooling status --skills-revision 1.50.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.
|
|
93
|
+
"requested": "1.50.0+skills.1",
|
|
94
94
|
"spelling": "bundle",
|
|
95
|
-
"on_disk": "1.
|
|
95
|
+
"on_disk": "1.50.0+skills.1",
|
|
96
96
|
"on_disk_skill": null,
|
|
97
|
-
"message": "match (1.
|
|
97
|
+
"message": "match (1.50.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.
|
|
105
|
-
Skills revision: mismatch: loaded 1.39.0+skills.1, on disk 1.
|
|
106
|
-
Skills revision: unchecked (on disk 1.
|
|
104
|
+
Skills revision: match (1.50.0+skills.1)
|
|
105
|
+
Skills revision: mismatch: loaded 1.39.0+skills.1, on disk 1.50.0+skills.1 — start a fresh session
|
|
106
|
+
Skills revision: unchecked (on disk 1.50.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
|
@@ -336,6 +336,8 @@
|
|
|
336
336
|
"template_family": {
|
|
337
337
|
"enum": [
|
|
338
338
|
"undecided",
|
|
339
|
+
"apollo",
|
|
340
|
+
"apollo-mv-single-step",
|
|
339
341
|
"olympus",
|
|
340
342
|
"limos",
|
|
341
343
|
"demeter",
|
|
@@ -343,6 +345,8 @@
|
|
|
343
345
|
"olympus-mv-two-step",
|
|
344
346
|
"shop-single-step",
|
|
345
347
|
"shop-three-step",
|
|
348
|
+
"arjuna",
|
|
349
|
+
"karna",
|
|
346
350
|
"custom"
|
|
347
351
|
]
|
|
348
352
|
},
|
|
@@ -146,7 +146,11 @@
|
|
|
146
146
|
"const": "campaigns-os-page-binding/v0"
|
|
147
147
|
},
|
|
148
148
|
"observation": {
|
|
149
|
-
"
|
|
149
|
+
"enum": [
|
|
150
|
+
"static_declaration",
|
|
151
|
+
"sdk_request"
|
|
152
|
+
],
|
|
153
|
+
"description": "static_declaration: the key the page's HTML and same-origin config scripts declare. sdk_request: the key the Campaign Cart SDK sent to the Campaigns API in the browser pass (qa run --browser)."
|
|
150
154
|
},
|
|
151
155
|
"outcome": {
|
|
152
156
|
"enum": [
|
|
@@ -174,7 +178,8 @@
|
|
|
174
178
|
"enum": [
|
|
175
179
|
"meta",
|
|
176
180
|
"inline",
|
|
177
|
-
"config_script"
|
|
181
|
+
"config_script",
|
|
182
|
+
"sdk_request"
|
|
178
183
|
]
|
|
179
184
|
}
|
|
180
185
|
},
|
|
@@ -182,7 +187,7 @@
|
|
|
182
187
|
"const": "not_verified"
|
|
183
188
|
}
|
|
184
189
|
},
|
|
185
|
-
"description": "Credential-free static declaration
|
|
190
|
+
"description": "Credential-free comparison of the page's key with the expected key: the static declaration, or the key the SDK sent in the browser pass. Not Campaign App identity. No keys, hashes, fragments, source URLs or inferred resource IDs."
|
|
186
191
|
},
|
|
187
192
|
"pageUrlRef": {
|
|
188
193
|
"type": "object",
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: campaign-lifecycle-orientation
|
|
3
|
-
version: 1.0.
|
|
3
|
+
version: 1.0.24
|
|
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.
|
|
8
|
-
Run `npx --no-install campaigns-os tooling status --skills-revision 1.
|
|
7
|
+
Bundle revision: 1.50.0+skills.1
|
|
8
|
+
Run `npx --no-install campaigns-os tooling status --skills-revision 1.50.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.
|
|
3
|
+
version: 1.0.24
|
|
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.
|
|
8
|
-
Run `npx --no-install campaigns-os tooling status --skills-revision 1.
|
|
7
|
+
Bundle revision: 1.50.0+skills.1
|
|
8
|
+
Run `npx --no-install campaigns-os tooling status --skills-revision 1.50.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.
|
|
3
|
+
version: 1.0.24
|
|
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.
|
|
8
|
-
Run `npx --no-install campaigns-os tooling status --skills-revision 1.
|
|
7
|
+
Bundle revision: 1.50.0+skills.1
|
|
8
|
+
Run `npx --no-install campaigns-os tooling status --skills-revision 1.50.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
|
|
@@ -65,7 +65,12 @@ Saved-Map QA may publish it under the existing consent and flag controls; a
|
|
|
65
65
|
publication failure does not erase the local one. Local-spec packet verdicts
|
|
66
66
|
stay local even with `--post-verdict`, and `qa publish` refuses those packets.
|
|
67
67
|
The readback projects `.campaign-runtime/qa-verdict.json` when
|
|
68
|
-
that sidecar has been copied into the campaign repository.
|
|
68
|
+
that sidecar has been copied into the campaign repository. The sidecar is a
|
|
69
|
+
committable projection: it always empties `test_orders`, `entry_urls`,
|
|
70
|
+
`page_urls` and `tested_urls`, so an empty `test_orders` there says nothing
|
|
71
|
+
about ordering. Its typed-card proof is the `browser-test-order:<path>`
|
|
72
|
+
assertions, each with a `browser-order-total-parity:<path>` row beside it; the
|
|
73
|
+
full verdict under `qa-output/` keeps the order records. A markdown QA
|
|
69
74
|
report, a ledger or a gate script is not a verdict and must not be scanned for
|
|
70
75
|
a disposition, a run id or a blocker. Where two JSON verdicts exist, interpret
|
|
71
76
|
the one the projection loaded; do not walk a report looking for a later rerun.
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: contribution-intake
|
|
3
|
-
version: 1.0.
|
|
3
|
+
version: 1.0.24
|
|
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.
|
|
8
|
-
Run `npx --no-install campaigns-os tooling status --skills-revision 1.
|
|
7
|
+
Bundle revision: 1.50.0+skills.1
|
|
8
|
+
Run `npx --no-install campaigns-os tooling status --skills-revision 1.50.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.
|
|
3
|
+
version: 1.0.29
|
|
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.
|
|
8
|
-
Run `npx --no-install campaigns-os tooling status --skills-revision 1.
|
|
7
|
+
Bundle revision: 1.50.0+skills.1
|
|
8
|
+
Run `npx --no-install campaigns-os tooling status --skills-revision 1.50.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
|
|
@@ -86,6 +86,7 @@ Build rules:
|
|
|
86
86
|
- Preserve SDK-owned checkout/cart/upsell/receipt/payment/address/totals/submit surfaces.
|
|
87
87
|
- If `doctor` (tier `A`: inspection that writes nothing, plus one read-only live campaign request once the site is built and a public campaign key resolves; `--write` is also tier `A` and writes doctor output; `--built` is tier `B`) reports `derived.scope.mode = "partial"`, build the pages listed in `derived.scope.built_pages` from their prepared source. Keep every out-of-scope route unbuilt by default, including pages marked `template_stock: true`; never publish placeholder presell/landing pages that remain on another host. Materialize a stock page only with explicit per-page operator opt-in (including a required pre-checkout `select` stand-in). For opted-in pages use the locked family's own page for that role with its dependent `_includes/`, `_layouts/`, and assets, wire it from CampaignSpec, and build a required select step first. Do not attest stock screenshots as design source. Built stock pages rejoin preview QA once their HTML exists. Carry remaining `skip_reason` declarations into the report and label the preview route/visual-testable rather than full-funnel launch-ready.
|
|
88
88
|
- For `landing` and `presell` pages, prefer the prepared source HTML when `source_html.pages[].path` points at a real standalone page. Preserve the design/content through a passthrough page-kit layout, inject the SDK loader/config as needed, and repoint CTAs into the CampaignSpec flow. Treat `source_html.pages[].path` and `context.page_map[].source_path` as source provenance. Treat `source_html.pages[].page_kit`, `context.page_map[].page_kit`, and `context.page_map[].output_path` as the Page Kit target file, route, CPK `page_type`, and frontmatter projection.
|
|
89
|
+
- Reproduce the source design's own proof and urgency elements as designed: reviews and testimonials, ratings, "Verified Purchase" labels, recent-purchase popups, stock counters, countdowns and guarantees. They are the merchant's content and the merchant's responsibility; Campaigns OS does not review them, so do not remove, soften or flag them. The starter templates shipping without some of these elements is not a reason to drop the source's.
|
|
89
90
|
- Prepared source HTML means page-kit-ready markup, not a wholesale Liquid rewrite. Standalone HTML mockups that are meant to stay whole (their `source_screenshot` proof is of the full document) keep their document wrappers: the source-html manifest records `wrapper_policy: preserve_document_wrappers` (or `--wrapper-policy preserve_document_wrappers` on `start` / `prepare-build`), and doctor reports the wrappers as a warning. Otherwise, standalone AI/exported HTML should keep page-owned body markup, remove document wrappers, add YAML frontmatter, move shared CSS/assets into the campaign structure, and use Liquid helpers only where page-kit needs campaign-rooted links/assets/includes.
|
|
90
91
|
- For `checkout`, `upsell`, `downsell`, and `receipt` pages, treat the selected starter-template commerce surface as the SDK contract reference: preserve required `data-next-*` controls, hidden fields, payment/address/totals/submit wiring, and `next_dont_touch` regions. The surrounding HTML wrapper, page composition, imagery, copy hierarchy, and brand layer are campaign/source-owned. Do not carry starter visual chrome forward when prepared source design should own that surface. QA checks what the checkout does, not family class names: do not add family shell classes (`.checkout-wrapper`, `.checkout-layout__left/right`) to the campaign's own grid or swap source-owned field markup for family includes to satisfy QA. Keep the checkout working instead: a `<form data-next-checkout="form">`, the contact and shipping fields bound with `data-next-checkout-field` inside it, and a visible cart total. A required field bound only on a `type="hidden"` input, a disabled control, a read-only input or read-only textarea, or a control with `aria-disabled="true"` does not count as bound: QA reports it in `fields_bound.missing`.
|
|
91
92
|
- Read `context.theme` and `.campaign-runtime/theme/theme-report.json` when present. If a fresh `brand-theme.css` artifact exists, copy it into the campaign asset tree and load it after `next-core.css` on checkout, upsell, downsell, and receipt pages. If policy is `inspect_only`, either run `campaigns-os theme generate` (tier `B`: writes the theme artifacts and doctor output under the target; `--force` is tier `C`) or record an explicit skipped reason before applying a new brand layer.
|
|
@@ -106,6 +107,6 @@ Build rules:
|
|
|
106
107
|
- Run page-kit build and SDK/template lint available in the target repo.
|
|
107
108
|
- 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.
|
|
108
109
|
- 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.
|
|
109
|
-
- Update the assembly report with commands, evidence, warnings, blockers, and next owner. If a brand theme was applied, record `report.theme
|
|
110
|
+
- 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`.
|
|
110
111
|
|
|
111
112
|
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.
|
|
3
|
+
version: 1.0.44
|
|
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.
|
|
8
|
-
Run `npx --no-install campaigns-os tooling status --skills-revision 1.
|
|
7
|
+
Bundle revision: 1.50.0+skills.1
|
|
8
|
+
Run `npx --no-install campaigns-os tooling status --skills-revision 1.50.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
|