@nextcommerce/campaigns-os 1.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (310) hide show
  1. package/AGENTS.md +204 -0
  2. package/CHANGELOG.md +5002 -0
  3. package/CONTEXT.md +685 -0
  4. package/LICENSE +202 -0
  5. package/NOTICE +4 -0
  6. package/README.md +368 -0
  7. package/agents/claude/CLAUDE.md +32 -0
  8. package/agents/codex/AGENTS.md +27 -0
  9. package/agents/copilot/copilot-instructions.md +14 -0
  10. package/agents/cursor/campaigns-os.mdc +13 -0
  11. package/bin/campaigns-os.mjs +38 -0
  12. package/campaign-spec/README.md +138 -0
  13. package/campaign-spec/dist/analytics-vocabulary.d.ts +47 -0
  14. package/campaign-spec/dist/analytics-vocabulary.js +74 -0
  15. package/campaign-spec/dist/index.d.ts +40 -0
  16. package/campaign-spec/dist/index.js +77 -0
  17. package/campaign-spec/dist/normalize.d.ts +22 -0
  18. package/campaign-spec/dist/normalize.js +41 -0
  19. package/campaign-spec/dist/routing.d.ts +190 -0
  20. package/campaign-spec/dist/routing.js +263 -0
  21. package/campaign-spec/dist/rules/analytics-contract-shape.d.ts +42 -0
  22. package/campaign-spec/dist/rules/analytics-contract-shape.js +303 -0
  23. package/campaign-spec/dist/rules/assembly-hints-shape.d.ts +42 -0
  24. package/campaign-spec/dist/rules/assembly-hints-shape.js +191 -0
  25. package/campaign-spec/dist/rules/campaign-metadata.d.ts +14 -0
  26. package/campaign-spec/dist/rules/campaign-metadata.js +40 -0
  27. package/campaign-spec/dist/rules/checkout-has-success-url.d.ts +31 -0
  28. package/campaign-spec/dist/rules/checkout-has-success-url.js +66 -0
  29. package/campaign-spec/dist/rules/cycle-detection.d.ts +12 -0
  30. package/campaign-spec/dist/rules/cycle-detection.js +141 -0
  31. package/campaign-spec/dist/rules/design-source-shape.d.ts +29 -0
  32. package/campaign-spec/dist/rules/design-source-shape.js +142 -0
  33. package/campaign-spec/dist/rules/downsell-without-upsell.d.ts +11 -0
  34. package/campaign-spec/dist/rules/downsell-without-upsell.js +40 -0
  35. package/campaign-spec/dist/rules/exit-intent-validation.d.ts +23 -0
  36. package/campaign-spec/dist/rules/exit-intent-validation.js +147 -0
  37. package/campaign-spec/dist/rules/funnel-count.d.ts +9 -0
  38. package/campaign-spec/dist/rules/funnel-count.js +37 -0
  39. package/campaign-spec/dist/rules/funnel-hypothesis-length.d.ts +22 -0
  40. package/campaign-spec/dist/rules/funnel-hypothesis-length.js +60 -0
  41. package/campaign-spec/dist/rules/funnel-identity.d.ts +15 -0
  42. package/campaign-spec/dist/rules/funnel-identity.js +57 -0
  43. package/campaign-spec/dist/rules/funnel-weight-sum.d.ts +20 -0
  44. package/campaign-spec/dist/rules/funnel-weight-sum.js +66 -0
  45. package/campaign-spec/dist/rules/index.d.ts +69 -0
  46. package/campaign-spec/dist/rules/index.js +131 -0
  47. package/campaign-spec/dist/rules/offer-ref-integrity.d.ts +13 -0
  48. package/campaign-spec/dist/rules/offer-ref-integrity.js +59 -0
  49. package/campaign-spec/dist/rules/package-pricing-sanity.d.ts +12 -0
  50. package/campaign-spec/dist/rules/package-pricing-sanity.js +42 -0
  51. package/campaign-spec/dist/rules/page-count.d.ts +11 -0
  52. package/campaign-spec/dist/rules/page-count.js +31 -0
  53. package/campaign-spec/dist/rules/page-id-uniqueness.d.ts +14 -0
  54. package/campaign-spec/dist/rules/page-id-uniqueness.js +47 -0
  55. package/campaign-spec/dist/rules/promo-code-input-validation.d.ts +8 -0
  56. package/campaign-spec/dist/rules/promo-code-input-validation.js +126 -0
  57. package/campaign-spec/dist/rules/promo-codes-shape.d.ts +30 -0
  58. package/campaign-spec/dist/rules/promo-codes-shape.js +187 -0
  59. package/campaign-spec/dist/rules/route-field-ignored-for-page-type.d.ts +33 -0
  60. package/campaign-spec/dist/rules/route-field-ignored-for-page-type.js +81 -0
  61. package/campaign-spec/dist/rules/route-target-resolves.d.ts +32 -0
  62. package/campaign-spec/dist/rules/route-target-resolves.js +112 -0
  63. package/campaign-spec/dist/rules/schema-version.d.ts +21 -0
  64. package/campaign-spec/dist/rules/schema-version.js +53 -0
  65. package/campaign-spec/dist/rules/sdk-version.d.ts +26 -0
  66. package/campaign-spec/dist/rules/sdk-version.js +96 -0
  67. package/campaign-spec/dist/rules/shipping-countries-shape.d.ts +10 -0
  68. package/campaign-spec/dist/rules/shipping-countries-shape.js +30 -0
  69. package/campaign-spec/dist/rules/shipping-methods-present.d.ts +10 -0
  70. package/campaign-spec/dist/rules/shipping-methods-present.js +26 -0
  71. package/campaign-spec/dist/rules/store-profile-shape.d.ts +30 -0
  72. package/campaign-spec/dist/rules/store-profile-shape.js +127 -0
  73. package/campaign-spec/dist/rules/thank-you-requirement.d.ts +16 -0
  74. package/campaign-spec/dist/rules/thank-you-requirement.js +50 -0
  75. package/campaign-spec/dist/rules/unknown-top-level-fields.d.ts +28 -0
  76. package/campaign-spec/dist/rules/unknown-top-level-fields.js +114 -0
  77. package/campaign-spec/dist/rules/upsell-has-packages.d.ts +9 -0
  78. package/campaign-spec/dist/rules/upsell-has-packages.js +35 -0
  79. package/campaign-spec/dist/rules/upsell-routing-complete.d.ts +10 -0
  80. package/campaign-spec/dist/rules/upsell-routing-complete.js +45 -0
  81. package/campaign-spec/dist/rules/upsell-without-checkout.d.ts +11 -0
  82. package/campaign-spec/dist/rules/upsell-without-checkout.js +44 -0
  83. package/campaign-spec/dist/rules/variant-labels-shape.d.ts +28 -0
  84. package/campaign-spec/dist/rules/variant-labels-shape.js +86 -0
  85. package/campaign-spec/dist/sdk-version-parse.d.ts +43 -0
  86. package/campaign-spec/dist/sdk-version-parse.js +62 -0
  87. package/campaign-spec/dist/types.d.ts +674 -0
  88. package/campaign-spec/dist/types.js +40 -0
  89. package/campaign-spec/package.json +12 -0
  90. package/compatibility.json +25 -0
  91. package/contracts/agent-relevant-change-policy.v1.json +111 -0
  92. package/contracts/brand-theme-source-defaults.figma-sections-export.v0.json +32 -0
  93. package/contracts/brand-theme-target-tokens.next-core.v0.json +65 -0
  94. package/contracts/campaign-cart-checkout-field-contract.v0.json +45 -0
  95. package/contracts/campaign-cart-sdk-support-policy.v0.json +11 -0
  96. package/contracts/commerce-surface-catalog.json +2452 -0
  97. package/contracts/fixtures/orientation/canonicalization/v1.json +34 -0
  98. package/contracts/fixtures/orientation/envelope/current.json +95 -0
  99. package/contracts/fixtures/orientation/envelope/freshness_unknown.json +97 -0
  100. package/contracts/fixtures/orientation/envelope/legacy_baseline.json +95 -0
  101. package/contracts/fixtures/orientation/envelope/orientation_available.json +136 -0
  102. package/contracts/fixtures/orientation/envelope/recovered_interrupted_update.json +136 -0
  103. package/contracts/fixtures/orientation/envelope/refused.json +100 -0
  104. package/contracts/fixtures/orientation/envelope/restart_required.json +137 -0
  105. package/contracts/fixtures/orientation/envelope/updated.json +135 -0
  106. package/contracts/fixtures/orientation/hostile-target/README.md +61 -0
  107. package/contracts/fixtures/orientation/hostile-target/manifest.json +82 -0
  108. package/contracts/fixtures/orientation/hostile-target/repo/CHANGELOG.md +18 -0
  109. package/contracts/fixtures/orientation/hostile-target/repo/bin/intended.mjs +12 -0
  110. package/contracts/fixtures/orientation/hostile-target/repo/bin/tripwire.mjs +15 -0
  111. package/contracts/fixtures/orientation/hostile-target/repo/contracts/release-ledger.json +48 -0
  112. package/contracts/fixtures/orientation/hostile-target/repo/contracts/supported-surface.json +17 -0
  113. package/contracts/fixtures/orientation/hostile-target/repo/docs/example-contract.md +13 -0
  114. package/contracts/fixtures/orientation/hostile-target/repo/hooks/post-checkout +5 -0
  115. package/contracts/fixtures/orientation/hostile-target/repo/hooks/post-merge +5 -0
  116. package/contracts/fixtures/orientation/hostile-target/repo/hooks/pre-commit +5 -0
  117. package/contracts/fixtures/orientation/hostile-target/repo/hostile-dependency-tripwire/package.json +15 -0
  118. package/contracts/fixtures/orientation/hostile-target/repo/hostile-dependency-tripwire/tripwire.mjs +9 -0
  119. package/contracts/fixtures/orientation/hostile-target/repo/package.json +20 -0
  120. package/contracts/fixtures/orientation/hostile-target/repo/schemas/example.v0.schema.json +15 -0
  121. package/contracts/fixtures/orientation/release-gate/cases.json +1073 -0
  122. package/contracts/fixtures/runtime-recipe/accept/current.json +299 -0
  123. package/contracts/fixtures/runtime-recipe/accept/minimal.json +294 -0
  124. package/contracts/fixtures/runtime-recipe/dist-states.json +51 -0
  125. package/contracts/fixtures/runtime-recipe/manifest.json +85 -0
  126. package/contracts/fixtures/runtime-recipe/reject/advisory-enforcement.json +299 -0
  127. package/contracts/fixtures/runtime-recipe/reject/allowlist-without-hosts.json +297 -0
  128. package/contracts/fixtures/runtime-recipe/reject/committed-output-claim.json +299 -0
  129. package/contracts/fixtures/runtime-recipe/reject/engines-disagreement-warns.json +299 -0
  130. package/contracts/fixtures/runtime-recipe/reject/lifecycle-scripts-enabled.json +299 -0
  131. package/contracts/fixtures/runtime-recipe/reject/missing-required-field.json +251 -0
  132. package/contracts/fixtures/runtime-recipe/reject/unknown-kind.json +299 -0
  133. package/contracts/fixtures/runtime-recipe/reject/unknown-network-policy.json +299 -0
  134. package/contracts/fixtures/runtime-recipe/reject/unknown-output-check.json +310 -0
  135. package/contracts/fixtures/runtime-recipe/reject/unknown-revision.json +299 -0
  136. package/contracts/fixtures/runtime-recipe/reject/unknown-step-id.json +299 -0
  137. package/contracts/fixtures/runtime-recipe/reject/unperformable-check-skipped.json +299 -0
  138. package/contracts/fixtures/runtime-recipe/reject/unpinned-lockfile.json +299 -0
  139. package/contracts/fixtures/sidecar-bundle/production-shaped/.campaign-runtime/assembly-report.json +180 -0
  140. package/contracts/fixtures/sidecar-bundle/production-shaped/.campaign-runtime/build-context.json +115 -0
  141. package/contracts/fixtures/sidecar-bundle/production-shaped/.campaign-runtime/doctor-output.json +29 -0
  142. package/contracts/fixtures/sidecar-bundle/production-shaped/.campaign-runtime/qa-verdict.json +27 -0
  143. package/contracts/fixtures/sidecar-bundle/production-shaped/campaign-runtime.build.json +141 -0
  144. package/contracts/migration-sidecar-bundle.v0.json +149 -0
  145. package/contracts/orientation-limits.v1.json +41 -0
  146. package/contracts/orientation-reason-codes.v1.json +196 -0
  147. package/contracts/private-template-sources.json +8 -0
  148. package/contracts/release-ledger.json +4598 -0
  149. package/contracts/reserved-skill-names.json +13 -0
  150. package/contracts/runtime-recipe.campaigns-os-node-v1.json +299 -0
  151. package/contracts/supported-surface.json +180 -0
  152. package/contracts/template-brand-contract.apollo-mv-single-step.v0.json +27 -0
  153. package/contracts/template-brand-contract.apollo.v0.json +27 -0
  154. package/contracts/template-brand-contract.demeter.v0.json +27 -0
  155. package/contracts/template-brand-contract.olympus-mv-single-step.v0.json +27 -0
  156. package/contracts/template-brand-contract.olympus-mv-two-step.v0.json +28 -0
  157. package/contracts/template-brand-contract.olympus.v0.json +27 -0
  158. package/contracts/template-brand-contract.shared-commerce.v0.json +190 -0
  159. package/contracts/template-brand-contract.shop-single-step.v0.json +27 -0
  160. package/contracts/template-brand-contract.shop-three-step.v0.json +29 -0
  161. package/contracts/template-slot-manifest.apollo-mv-single-step.v0.json +14 -0
  162. package/contracts/template-slot-manifest.apollo.v0.json +12 -0
  163. package/contracts/template-slot-manifest.demeter.v0.json +30 -0
  164. package/contracts/template-slot-manifest.olympus-mv-single-step.v0.json +14 -0
  165. package/contracts/template-slot-manifest.olympus-mv-two-step.v0.json +15 -0
  166. package/contracts/template-slot-manifest.olympus.v0.json +12 -0
  167. package/contracts/template-slot-manifest.shared-content-core.v0.json +4254 -0
  168. package/contracts/template-slot-manifest.shop-single-step.v0.json +47 -0
  169. package/contracts/template-slot-manifest.shop-three-step.v0.json +33 -0
  170. package/docs/brand-theme-bridge.md +159 -0
  171. package/docs/build-packet.md +1300 -0
  172. package/docs/campaign-build-brief.md +145 -0
  173. package/docs/campaign-standardization-report.md +329 -0
  174. package/docs/campaigns-os-build-flow.md +117 -0
  175. package/docs/design-source-package.md +784 -0
  176. package/docs/legacy-migration.md +58 -0
  177. package/docs/migration-sidecar-bundle.md +139 -0
  178. package/docs/orientation-contract-reference.md +1220 -0
  179. package/docs/polish-evidence.md +502 -0
  180. package/docs/qa-and-test-orders.md +1691 -0
  181. package/docs/release-ledger-authoring-guide.md +274 -0
  182. package/docs/runtime-readiness.md +211 -0
  183. package/docs/supported-surface.md +83 -0
  184. package/docs/versioning.md +55 -0
  185. package/docs/workflow-findings-sidecar.md +588 -0
  186. package/package.json +135 -0
  187. package/prompts/first-build.md +27 -0
  188. package/prompts/friction-log.md +30 -0
  189. package/schemas/campaign-build-brief.v1.schema.json +149 -0
  190. package/schemas/campaign-design-source-package.v0.schema.json +697 -0
  191. package/schemas/campaign-runtime-assembly-report.v0.schema.json +390 -0
  192. package/schemas/campaign-runtime-build-context.v0.schema.json +339 -0
  193. package/schemas/campaign-runtime-build-packet.v0.schema.json +452 -0
  194. package/schemas/campaign-spec.v4.schema.json +582 -0
  195. package/schemas/campaigns-os-doctor-output.v0.schema.json +43 -0
  196. package/schemas/campaigns-os-legacy-migration-inventory.v0.schema.json +112 -0
  197. package/schemas/campaigns-os-legacy-provisioning-plan.v0.schema.json +38 -0
  198. package/schemas/campaigns-os-legacy-provisioning-receipt.v0.schema.json +57 -0
  199. package/schemas/campaigns-os-qa-verdict-sidecar.v0.schema.json +150 -0
  200. package/schemas/campaigns-os-qa-verdict.v0.schema.json +438 -0
  201. package/schemas/campaigns-os-release-ledger.v1.schema.json +162 -0
  202. package/schemas/campaigns-os-run-record.v0.schema.json +343 -0
  203. package/schemas/campaigns-os-runtime-recipe.v1.schema.json +313 -0
  204. package/schemas/campaigns-os-sidecar-bundle-conformance.v0.schema.json +78 -0
  205. package/schemas/campaigns-os-tooling-orientation.v1.schema.json +381 -0
  206. package/schemas/campaigns-os-workflow-finding.v0.schema.json +134 -0
  207. package/schemas/source-html-manifest.v0.schema.json +252 -0
  208. package/skills/next-campaigns-build/SKILL.md +73 -0
  209. package/skills/next-campaigns-os/SKILL.md +101 -0
  210. package/skills/next-campaigns-os/references/session-intake.md +160 -0
  211. package/skills/next-campaigns-os-setup/SKILL.md +22 -0
  212. package/skills/next-campaigns-polish/SKILL.md +145 -0
  213. package/skills/next-campaigns-qa/SKILL.md +92 -0
  214. package/skills.json +56 -0
  215. package/skills.sh +64 -0
  216. package/src/adapter-decision-contract.mjs +333 -0
  217. package/src/brand-theme.mjs +1151 -0
  218. package/src/browser-launch.mjs +79 -0
  219. package/src/build-brief.mjs +781 -0
  220. package/src/built-site-scope.mjs +312 -0
  221. package/src/campaign-ecosystem.mjs +734 -0
  222. package/src/campaign-identity.mjs +405 -0
  223. package/src/campaign-workspace.mjs +127 -0
  224. package/src/checkpoint-waiver.mjs +302 -0
  225. package/src/cli.mjs +13442 -0
  226. package/src/commercial-journey.mjs +1119 -0
  227. package/src/commercial-parity.mjs +965 -0
  228. package/src/consent.mjs +347 -0
  229. package/src/content-residue.mjs +322 -0
  230. package/src/deadline.mjs +81 -0
  231. package/src/design-source-package.mjs +2604 -0
  232. package/src/deviation.mjs +107 -0
  233. package/src/doctor-check-registry.mjs +49 -0
  234. package/src/doctor-sidecar.mjs +106 -0
  235. package/src/finding-cause.mjs +557 -0
  236. package/src/findings.mjs +326 -0
  237. package/src/fs-identity.mjs +68 -0
  238. package/src/gate-actions.mjs +105 -0
  239. package/src/html-scan.mjs +53 -0
  240. package/src/install-mode.mjs +272 -0
  241. package/src/legacy-migration.d.ts +128 -0
  242. package/src/legacy-migration.mjs +510 -0
  243. package/src/lifecycle.mjs +338 -0
  244. package/src/local-proof.mjs +401 -0
  245. package/src/map-pin-writeback.mjs +210 -0
  246. package/src/orchestration-stage-contract.mjs +81 -0
  247. package/src/package-install-fixture.mjs +33 -0
  248. package/src/page-kit-build-summary.mjs +175 -0
  249. package/src/page-kit-campaign-config.mjs +57 -0
  250. package/src/page-kit-sdk-version.mjs +392 -0
  251. package/src/page-kit-store-profile.mjs +369 -0
  252. package/src/page-kit-sync.mjs +162 -0
  253. package/src/polish-browser.mjs +867 -0
  254. package/src/polish-capture.mjs +1094 -0
  255. package/src/polish-deadline.mjs +51 -0
  256. package/src/polish-gate.mjs +739 -0
  257. package/src/polish-node.mjs +639 -0
  258. package/src/polish-page-load.mjs +1100 -0
  259. package/src/private-template-source.mjs +237 -0
  260. package/src/proof-policy.mjs +82 -0
  261. package/src/qa-analytics-correctness.mjs +307 -0
  262. package/src/qa-analytics-errors.mjs +38 -0
  263. package/src/qa-analytics-parity.mjs +699 -0
  264. package/src/qa-binding-evidence.mjs +140 -0
  265. package/src/qa-browser.mjs +6608 -0
  266. package/src/qa-cart-entry.mjs +406 -0
  267. package/src/qa-commercial-parity.mjs +641 -0
  268. package/src/qa-node.mjs +3620 -0
  269. package/src/qa-order-bump.mjs +381 -0
  270. package/src/qa-parity-capture.mjs +428 -0
  271. package/src/qa-parity-fixture.mjs +359 -0
  272. package/src/qa-publish.mjs +362 -0
  273. package/src/qa-purchase-data-layer.mjs +263 -0
  274. package/src/qa-route-probe.mjs +272 -0
  275. package/src/qa-sidecar.mjs +188 -0
  276. package/src/qa-test-order-topology.mjs +207 -0
  277. package/src/qa-url-privacy.mjs +13 -0
  278. package/src/qa-verdict-discovery.mjs +192 -0
  279. package/src/qa-verdict-publish.mjs +105 -0
  280. package/src/qa-verdict.mjs +287 -0
  281. package/src/remit.mjs +388 -0
  282. package/src/repo-scan.mjs +83 -0
  283. package/src/route-identity.mjs +133 -0
  284. package/src/run-record-closeout.mjs +229 -0
  285. package/src/run-record.mjs +839 -0
  286. package/src/run-session.mjs +226 -0
  287. package/src/runtime-state-ignore.mjs +113 -0
  288. package/src/sdk-attribute-index.mjs +212 -0
  289. package/src/sdk-markup.mjs +358 -0
  290. package/src/sdk-meta-tags.mjs +52 -0
  291. package/src/shell-token.mjs +7 -0
  292. package/src/sidecar-bundle.mjs +399 -0
  293. package/src/source-asset-crawl.mjs +469 -0
  294. package/src/source-html-intake.mjs +627 -0
  295. package/src/source-html-manifest.mjs +276 -0
  296. package/src/source-prep.mjs +284 -0
  297. package/src/spec-derive-store.mjs +431 -0
  298. package/src/spec-derive.mjs +514 -0
  299. package/src/spec-fetch.mjs +66 -0
  300. package/src/spec-hash.mjs +48 -0
  301. package/src/spec-identity.mjs +27 -0
  302. package/src/stage-ledger.mjs +509 -0
  303. package/src/standardization-report.mjs +1297 -0
  304. package/src/template-brand-contract.mjs +473 -0
  305. package/src/template-freshness.mjs +196 -0
  306. package/src/template-reference.mjs +81 -0
  307. package/src/template-slot-manifest.mjs +150 -0
  308. package/src/text-safety.mjs +62 -0
  309. package/src/theme-gate.mjs +185 -0
  310. package/src/upsell-selector-scope.mjs +299 -0
@@ -0,0 +1,252 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://nextcommerce.com/schemas/source-html-manifest.v0.schema.json",
4
+ "title": "Campaigns OS Source HTML Manifest v0",
5
+ "description": "Producer-authored manifest consumed by Campaigns OS prepare-build. Paths are relative to the source HTML root, not the .campaigns-os directory.",
6
+ "type": "object",
7
+ "additionalProperties": true,
8
+ "required": ["schema_version", "pages"],
9
+ "properties": {
10
+ "schema_version": {
11
+ "const": "source-html-manifest/v0"
12
+ },
13
+ "generated_at": {
14
+ "type": "string",
15
+ "minLength": 1
16
+ },
17
+ "generator": {
18
+ "type": "string",
19
+ "minLength": 1,
20
+ "description": "Producer identity such as figma-sections-export@1.2.3 or reference-ai-producer@1.0.0."
21
+ },
22
+ "campaign_slug": {
23
+ "type": "string",
24
+ "minLength": 1
25
+ },
26
+ "root": {
27
+ "type": "string",
28
+ "minLength": 1,
29
+ "description": "Optional producer hint. Manifest page paths still resolve relative to the source root passed to prepare-build."
30
+ },
31
+ "wrapper_policy": {
32
+ "type": "string",
33
+ "enum": ["strip_document_wrappers", "preserve_document_wrappers", "not_required", "unknown"],
34
+ "description": "Optional operator selection of the document-wrapper policy for this source, in the same vocabulary the Build Packet records at source_html.adapter_contract.wrapper_policy. prepare-build seeds the adapter contract from it, so declaring \"preserve_document_wrappers\" here reports source_html.prep.document_wrapper without blocking instead of requiring the wrappers to be stripped. The prepare-build --wrapper-policy flag overrides this key; with neither, the default is \"strip_document_wrappers\". A value outside the enum does not invalidate the manifest: the key is ignored with a warning naming it, the value, and the accepted values, and the rest of the manifest is used as written. See docs/source-adapters.md, section \"Source preparation check\"."
35
+ },
36
+ "producer_provenance": {
37
+ "type": "object",
38
+ "additionalProperties": true,
39
+ "description": "Optional producer evidence. Required by doctor for Figma exporter manifests.",
40
+ "properties": {
41
+ "source_type": {
42
+ "type": "string",
43
+ "minLength": 1,
44
+ "description": "For figma-sections-export output this must be semantic_figma_export."
45
+ },
46
+ "screenshot_fallback_used": {
47
+ "type": "boolean"
48
+ },
49
+ "generator_repo": {
50
+ "type": "string",
51
+ "minLength": 1
52
+ },
53
+ "generator_version": {
54
+ "type": "string",
55
+ "minLength": 1
56
+ },
57
+ "export_log": {
58
+ "type": ["string", "null"],
59
+ "minLength": 1
60
+ },
61
+ "figma_file_key": {
62
+ "type": ["string", "null"],
63
+ "minLength": 1
64
+ },
65
+ "figma_file_keys": {
66
+ "type": "array",
67
+ "items": { "type": "string", "minLength": 1 }
68
+ },
69
+ "semantic_section_count": {
70
+ "type": "integer",
71
+ "minimum": 1
72
+ },
73
+ "breakpoint_image_count": {
74
+ "type": "integer",
75
+ "minimum": 0
76
+ },
77
+ "material_fingerprint": {
78
+ "type": "string",
79
+ "pattern": "^[0-9a-f]{64}$"
80
+ },
81
+ "section_exports": {
82
+ "type": "array",
83
+ "items": {
84
+ "type": "object",
85
+ "additionalProperties": true,
86
+ "required": ["section", "type"],
87
+ "properties": {
88
+ "section": { "type": "string", "minLength": 1 },
89
+ "type": { "type": "string", "minLength": 1 },
90
+ "file_key": { "type": ["string", "null"], "minLength": 1 },
91
+ "node_ids": { "type": "object" },
92
+ "partial": { "type": ["string", "null"], "minLength": 1 },
93
+ "images": { "type": "array" },
94
+ "command": { "type": ["string", "null"], "minLength": 1 },
95
+ "warnings": { "type": "array" }
96
+ }
97
+ }
98
+ }
99
+ }
100
+ },
101
+ "files": {
102
+ "type": "array",
103
+ "description": "Optional material inventory for drift/provenance checks.",
104
+ "items": {
105
+ "type": "object",
106
+ "additionalProperties": true,
107
+ "required": ["path", "role", "sha256"],
108
+ "properties": {
109
+ "path": { "type": "string", "minLength": 1 },
110
+ "role": {
111
+ "type": "string",
112
+ "enum": ["page", "partial", "layout", "asset", "export_log", "support"]
113
+ },
114
+ "sha256": {
115
+ "type": "string",
116
+ "pattern": "^[0-9a-f]{64}$"
117
+ },
118
+ "bytes": {
119
+ "type": "integer",
120
+ "minimum": 0
121
+ }
122
+ }
123
+ }
124
+ },
125
+ "pages": {
126
+ "type": "array",
127
+ "items": {
128
+ "type": "object",
129
+ "additionalProperties": true,
130
+ "required": ["page_id"],
131
+ "description": "Exactly one of path (bind a source HTML file) or skip_reason (declare the page out of source scope) is required per entry; the oneOf below enforces the exclusion.",
132
+ "oneOf": [
133
+ { "required": ["path"], "not": { "required": ["skip_reason"] } },
134
+ { "required": ["skip_reason"], "not": { "required": ["path"] } }
135
+ ],
136
+ "properties": {
137
+ "page_id": {
138
+ "type": "string",
139
+ "minLength": 1,
140
+ "description": "Active CampaignSpec page id. This is the primary join key."
141
+ },
142
+ "path": {
143
+ "type": "string",
144
+ "minLength": 1,
145
+ "description": "Source-root-relative HTML file path."
146
+ },
147
+ "skip_reason": {
148
+ "type": "string",
149
+ "minLength": 1,
150
+ "description": "Reason this active page carries no source HTML (e.g. template-derived)."
151
+ },
152
+ "page_type": {
153
+ "type": "string",
154
+ "minLength": 1,
155
+ "description": "Optional producer page type used for fallback matching only."
156
+ },
157
+ "page_url": {
158
+ "type": "string",
159
+ "minLength": 1,
160
+ "description": "Optional producer/spec route used for fallback matching after Page Kit route normalization."
161
+ },
162
+ "source_hash": {
163
+ "type": "string",
164
+ "pattern": "^[0-9a-f]{64}$",
165
+ "description": "Optional sha256 of the source HTML file at manifest generation time."
166
+ },
167
+ "screenshots": {
168
+ "$ref": "#/$defs/sourceScreenshotList",
169
+ "description": "Operator-authored source screenshot proof for this page, consumed by prepare-build when it synthesizes the Design Source Package. A renderable primary-design page clears DESIGN_SOURCE_PACKAGE_NOT_READY with one available desktop source_screenshot record and one available mobile source_screenshot record, unless an accepted screenshot-absence Source Gap or an approved waiver recorded in the package covers it. The runtime manifest validator does not read this key; the producer normalizes it and is more tolerant than this declaration (it lowercases viewport and drops or nulls malformed values rather than failing). See docs/design-source-package.md, section 'Clearing DESIGN_SOURCE_PACKAGE_NOT_READY'."
170
+ },
171
+ "screenshot_refs": {
172
+ "$ref": "#/$defs/sourceScreenshotList",
173
+ "description": "Alias for screenshots; read by the same producer channel."
174
+ },
175
+ "source_screenshot_refs": {
176
+ "$ref": "#/$defs/sourceScreenshotList",
177
+ "description": "Alias for screenshots; read by the same producer channel."
178
+ }
179
+ }
180
+ }
181
+ }
182
+ },
183
+ "$defs": {
184
+ "sourceScreenshotList": {
185
+ "type": "array",
186
+ "items": {
187
+ "anyOf": [
188
+ {
189
+ "type": "string",
190
+ "minLength": 1,
191
+ "description": "Id of a visual record already registered for this package. An unresolved id contributes no proof."
192
+ },
193
+ { "$ref": "#/$defs/sourceScreenshot" }
194
+ ]
195
+ }
196
+ },
197
+ "sourceScreenshot": {
198
+ "type": "object",
199
+ "additionalProperties": true,
200
+ "description": "One source screenshot record. Only an available source_screenshot record with a recognized viewport counts toward readiness. A record without a recognized viewport, or with a kind outside the enum, is dropped by the producer and counts as nothing; an unavailable record is retained as evidence of an absence and satisfies no viewport. Field aliases the producer also accepts: viewport_key for viewport; artifact_path or file_path for path; canonical_url for url; artifact_hash or hash for sha256; a nested dimensions object for width/height; capture_timestamp for captured_at; reason for unavailable_reason.",
201
+ "properties": {
202
+ "id": {
203
+ "type": "string",
204
+ "minLength": 1,
205
+ "description": "Optional stable record id. When omitted the producer derives one from the page surface, viewport, and a content digest."
206
+ },
207
+ "kind": {
208
+ "type": "string",
209
+ "enum": ["source_screenshot", "unavailable_render"],
210
+ "description": "Defaults to source_screenshot, the only kind that counts as proof. unavailable_render is accepted and retained but never satisfies a viewport. Any other kind is dropped for this channel rather than promoted to source proof."
211
+ },
212
+ "viewport": {
213
+ "type": "string",
214
+ "enum": ["desktop", "mobile", "tablet"],
215
+ "description": "Required for the record to count as proof; desktop and mobile are the readiness-required viewports and tablet is optional in v0."
216
+ },
217
+ "availability": {
218
+ "type": "string",
219
+ "enum": ["available", "unavailable"],
220
+ "description": "Defaults to available when path or url is present. An unavailable record requires unavailable_reason."
221
+ },
222
+ "path": {
223
+ "type": "string",
224
+ "minLength": 1,
225
+ "description": "Screenshot file path relative to the source HTML root, not to the .campaigns-os directory. The producer records this path; it does not open the file."
226
+ },
227
+ "url": {
228
+ "type": "string",
229
+ "minLength": 1,
230
+ "description": "Screenshot URL, when the capture is hosted rather than local."
231
+ },
232
+ "sha256": {
233
+ "type": "string",
234
+ "pattern": "^(sha256:)?[0-9a-f]{64}$",
235
+ "description": "Optional sha256 of the screenshot bytes, bare or sha256:-prefixed. The producer records it; it does not recompute or verify it."
236
+ },
237
+ "width": { "type": "integer", "minimum": 1 },
238
+ "height": { "type": "integer", "minimum": 1 },
239
+ "device_profile": { "type": "string", "minLength": 1 },
240
+ "scale_factor": { "type": "number", "exclusiveMinimum": 0 },
241
+ "browser": { "type": "string", "minLength": 1 },
242
+ "captured_at": { "type": "string", "minLength": 1 },
243
+ "unavailable_reason": {
244
+ "type": "string",
245
+ "minLength": 1,
246
+ "description": "Why no capture exists. Required when availability is unavailable."
247
+ },
248
+ "notes": { "type": ["string", "null"] }
249
+ }
250
+ }
251
+ }
252
+ }
@@ -0,0 +1,73 @@
1
+ ---
2
+ name: next-campaigns-build
3
+ version: 1.0.2
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
+ ---
6
+
7
+ # Next Campaigns Build
8
+
9
+ ## Recommended Build Loop
10
+
11
+ For campaign builds, follow **build → independent review → repair → verification**.
12
+ The main session owns the plan, integration, and final acceptance. Choose subagent
13
+ assignments and models for the task's required capabilities and the consequences
14
+ of failure, especially for SDK-owned commerce, payments, offers, and theme wiring.
15
+ Among suitable models, prefer cheaper ones for bounded implementation, inspection,
16
+ and repair.
17
+
18
+ Have a fresh reviewer inspect the result against the source material and actual
19
+ rendered or runtime evidence, without the builder's rationale. Keep one writer at
20
+ a time. Resolve concrete findings and rerun the relevant checks before declaring
21
+ completion. After two repair-and-verification rounds that leave the targeted
22
+ finding or failing required check unresolved, reassess the approach or surface
23
+ the blocker. Scale review depth to the task and preserve the existing checks and
24
+ approval boundaries. Carry review and verification through the existing Polish
25
+ and QA stages; assembly review does not replace them.
26
+
27
+ If delegation is unavailable or disallowed, perform a distinct self-review in the
28
+ current session and disclose that no independent agent reviewed the result.
29
+
30
+ ## Inputs and Build Rules
31
+
32
+ Inputs:
33
+
34
+ - `campaign-runtime.build.json`
35
+ - `.campaign-runtime/build-context.json`
36
+ - `.campaign-runtime/assembly-report.json`
37
+ - local CampaignSpec JSON
38
+ - prepared HTML/assets source
39
+ - target page-kit repo
40
+ - starter-template commerce catalog
41
+
42
+ Build rules:
43
+
44
+ - Read `families[template_family].agentContract` before editing commerce surfaces.
45
+ - Use `sharedFrontmatterVocabulary` to identify values that come from CampaignSpec/API.
46
+ - Replace `frontmatter.demoOnlyValues`.
47
+ - Replace values named by `frontmatter.replaceFromSpecOrApi`.
48
+ - Remove unsupported surfaces named by `frontmatter.removeWhenUnsupported`.
49
+ - Preserve SDK-owned checkout/cart/upsell/receipt/payment/address/totals/submit surfaces.
50
+ - If `doctor` reports `derived.scope.mode = "partial"`, build the pages listed in `derived.scope.built_pages` from their prepared source. A page in `derived.scope.out_of_scope_pages` whose assembly-report decision `dec_page_scope_<page>` carries `template_stock: true` is template stock: materialise it from the locked family's own page for that role (`decision.template_family`; the `next build` prompt lists them), copied atomically with its dependent `_includes/`, `_layouts/`, and assets, and wired from CampaignSpec — a pre-checkout `select` step first, because it seeds the cart the runtime pages read. Do not look for prepared source HTML for it, and do not attest a screenshot of it as a design source. Once its built HTML exists at the page's route, doctor lists it among the previewable routes and lifts the runtime-QA block for it. An out-of-scope page without that marker stays unbuilt: carry its `skip_reason` into the assembly report and label the preview as route/visual-testable rather than full-funnel launch-ready.
51
+ - 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.
52
+ - Prepared source HTML means page-kit-ready markup, not a wholesale Liquid rewrite. 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.
53
+ - 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.
54
+ - 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` or record an explicit skipped reason before applying a new brand layer.
55
+ - Generated brand-theme v0 is root-variable-only. It may skin commerce pages through next-core custom properties, but it is not permission to edit SDK-owned selectors, package controls, payment fields, totals, submit controls, receipt templates, route meta tags, or SDK JavaScript.
56
+ - Payment, express checkout, bundle selectors, and order bumps must start from the selected family's canonical component DOM/classes, not from raw custom/source HTML with `data-next-*` added afterward. For payment specifically, preserve the family payment-method wrapper, hosted field classes, and iframe geometry assumptions (for example `input-flds spreedly-field` in shop-style templates). Skin these components with campaign tokens; do not rebuild Spreedly/card fields as arbitrary divs.
57
+ - When a checkout page declares `exit_intent.enabled`, wire the popup as an offer application surface: use `offer_ref_id`/`offer_code` from CampaignSpec, apply the code through the SDK/API coupon/voucher path, and render applied-state copy with SDK conditionals such as `cart.hasCoupon("FREESHIP")`.
58
+ - When a checkout page declares `promo_code_input.enabled`, wire the template/source promo-code surface to accept the mapped CampaignSpec `offer_code`, submit it through SDK/API, and let SDK/API reprice selectors, totals, and discount rows.
59
+ - When the selected family includes or copies a default exit-pop but CampaignSpec has no checkout `exit_intent` or `promo_code_input`, strip the widget during build; do not leave blank modals or default coupon-code controls in output.
60
+ - Do not hardcode exit-pop or promo-code discount math, static post-discount prices, or campaign-specific JavaScript that mutates pricing display outside SDK-owned display regions.
61
+ - If setup/build needs starter-template files, copy the template family atomically with its dependent pages, `_includes/`, `_layouts/`, `assets/css/`, and `assets/js/`; copying only checkout/receipt pages is incomplete.
62
+ - Resolve SDK routing meta tags to deployed campaign-root paths, not spec literals. For example, `next-success-url: upsell/` in the spec should become `/<public_route_slug>/upsell/` in built HTML.
63
+ - If an order bump package comes from `packages.prepurchase_*` and is not one of the main `bundles[]`, default `package_sync=false` and `show_line_total_price=false` unless the CampaignSpec explicitly says the add-on quantity must sync with the main bundle.
64
+ - For two-step package-selection-before-checkout flows, use the selector page as the pre-checkout step, encode the selected cart with `forcePackageId`, preserve attribution/tracking params, and strip `forcePackageId` from the visible checkout URL after SDK initialization.
65
+ - Record intentional drops from source HTML in the assembly report, especially payment/provider changes such as "PayPal removed because CampaignSpec available_payment_methods excludes it." Polish must inherit these decisions.
66
+ - Preserve any existing Build Context `theme` inspection state and Assembly Report `theme` application state. If build applies, skips, or invalidates generated theme CSS, update `report.theme` rather than leaving stale evidence.
67
+ - After page-kit build, inspect rendered `_site` output: body exists, Campaign Cart runtime markers exist, `sdk_hints.meta_tags` rendered, route meta points at the campaign root, and copied funnel attribution/runtime baggage is gone.
68
+ - For `shop-three-step`, shipping methods are dynamic through `window.next.getShippingMethods()`; do not add static Olympus-style `shipping_methods` frontmatter.
69
+ - Run page-kit build and SDK/template lint available in the target repo.
70
+ - 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.
71
+ - Update the assembly report with commands, evidence, warnings, blockers, and next owner. If a brand theme was applied, record `report.theme.status`, `css_path`, `commerce_pages`, `load_order=after-next-core`, evidence, and any first repair-loop defect.
72
+
73
+ Build does not replace polish or QA. Hand off to `next-campaigns-polish` when the campaign is runnable.
@@ -0,0 +1,101 @@
1
+ ---
2
+ name: next-campaigns-os
3
+ version: 1.0.16
4
+ description: Coordinate Campaigns OS lifecycle workflows from CampaignSpec, Build Packet, starter-template contracts, stage reports, deploy evidence, and QA proof depth.
5
+ ---
6
+
7
+ # Campaigns OS
8
+
9
+ Use this skill to orient a campaign build, run preflight, decide the next stage, and keep the lifecycle honest.
10
+
11
+ ## Public Lifecycle Boundary
12
+
13
+ The public `campaigns-os` package owns portable workflow semantics: Build
14
+ Packet generation, Build Context, Assembly Report validation, doctor/readiness
15
+ decisions, public build/polish/QA guidance, and browser QA runner behavior.
16
+ It also owns CampaignSpec validation through the public
17
+ `@nextcommerce/campaigns-os/campaign-spec` subpath; Map Builder, the public
18
+ doctor, and agency tooling should consume that same rule registry instead of
19
+ vendoring or reimplementing spec rules.
20
+ Internal orchestration may wrap this workflow for the Map Builder,
21
+ issue-tracker projection, QA routing, dashboards, and promotion decisions,
22
+ but those wrappers should not redefine the public contract.
23
+
24
+ Workflow:
25
+
26
+ 1. Confirm the campaign was configured in Campaigns App and exported from Campaign Map Builder as current CampaignSpec JSON. Current authoring is v4.3+ while preserving the v4.2 `funnels[]` topology as the compatibility shape.
27
+ 2. Run `campaigns-os start` or `campaigns-os prepare-build` with a local CampaignSpec, prepared HTML/assets source, target page-kit repo, and explicit template family. The family must be certified (commerce catalog + brand contract; the CLI lists them on rejection) — an uncertified/custom family requires `--allow-uncertified-template "<reason>"` and forfeits deterministic assembly, residue QA, and pricing contracts. The entry point auto-opens the run session in the target repo; do not skip `campaigns-os run end` at the finish. If intake blocks with `DESIGN_SOURCE_PACKAGE_NOT_READY`, the source material carries no desktop/mobile screenshot proof: supply it through `pages[].screenshots[]` in `<source-root>/.campaigns-os/source-html-manifest.json` and follow "Clearing `DESIGN_SOURCE_PACKAGE_NOT_READY`" in `docs/design-source-package.md`, which also gives the recovery for the package a blocked run left behind.
28
+ 3. Brand-theme discovery runs in inspect-only mode by default and records `context.theme`. When it proves a brand theme is generatable and the campaign ships commerce pages, the theme gate BLOCKS polish/deploy/QA until the brand layer is applied after `next-core.css` or explicitly waived (`campaigns-os theme waive --packet <p> --reason "<why>" --waived-by "<named human>"`, the same named-human rule as `checkpoint waive`). Run `campaigns-os theme generate` and apply it during build; do not defer the decision.
29
+ 4. Run `campaigns-os doctor --packet <packet>`.
30
+ 5. Resolve the registered **Page Kit** checkpoints before runtime work. The CampaignSpec is the authority for the target's `_data/campaigns.json` entry, and the reconcile is a command, not a hand edit: `campaigns-os page-kit sync --packet <p>` (add `--dry-run` to see the field-by-field diff first) writes the spec's `campaign.store_*` fields into the entry for the packet's route and seeds the released SDK pin (`global_config.sdk_version` is canonical, `runtime.sdk_version` an accepted alias) while the entry is still in scaffold state or behind the spec; it never moves a configured campaign's pin backwards (on an existing campaign the repo pin moves first and the Map is stale: run `campaigns-os spec derive --packet <p>`, which writes the repo pin — and the page routes and analytics ids the repo carries — into the local CampaignSpec with a field-by-field diff, and add `--write-map` to record the pin in the saved Map's Build hints too (it reads the Map back and moves only the pin, forward or not at all; a Map pin ahead of the repo is refused as a warning), or re-save the Map by hand; a hand edit of the spec is never the answer for a derived field; the `campaign.store_*` fields are derived from the store itself with `spec derive --packet <p> --from-store <subdomain>`, the Admin API read token in `<SUBDOMAIN>_ADMIN_TOKEN`, and a field the store cannot state is reported and left as it is, never emptied), and touches nothing else; doctor and `next` print it as the gate's `repair_target` action, and after it `page_kit.store_profile` and `page_kit.sdk_version` pass without a waiver. Starter demo residue (a demo storefront URL or phone) in that entry is never waivable and must be replaced this way. A `PARTIAL` status means a field could not be made spec-authoritative (a spec value of the wrong type or shape, the demo value itself in the spec, demo residue in a field the spec does not carry, a conflicting or non-released pin, or a gate under an active waiver); the warnings name the spec field to fix, then sync again. Missing/malformed Store Profile or SDK evidence, invalid types or semantic versions, and conflicting dual SDK declarations are not waivable. An exact valid mismatch may be accepted with named-human attribution and a bound: `campaigns-os checkpoint waive --packet <p> --gate <page_kit.store_profile|page_kit.sdk_version> --reason "<why>" --waived-by "<named human>" --review-condition "<trigger>"` (or `--expires-at <future ISO timestamp>`). The package-owned hidden eager-media checkpoint is produced and resolved during Polish in step 9.
31
+ 6. On any doctor run that sees built output, resolve `built_output.upsell_selector_scope`. A `data-next-bundle-selector` on a page whose funnel role is `upsell` or `downsell` writes to the shopper's LIVE CART unless it carries `data-next-upsell-context`; loading the page then adds that package with no click, and it is charged at the next checkout without appearing in that checkout's rendered order summary. Being hidden does not help — the write happens at init. Fix it by adding `data-next-upsell-context` to the named selector, or by deleting a selector that exists only to display a price. This gate runs on EVERY doctor invocation, not only after assembly, because the defect it was written for was introduced by a later review round. If a cart-scoped selector on a post-purchase page is genuinely intended, record it: `campaigns-os checkpoint waive --packet <p> --gate built_output.upsell_selector_scope --reason "<why>" --waived-by "<named human>" --review-condition "<trigger>"`. On the same runs, resolve `built_output.campaign_identity`: every page must name the same campaign — one API key (`next-api-key` meta or the `config.js` / `window.nextConfig` `apiKey`), one `next-funnel`, and any `setAttribution({ funnel })` call agreeing with the tag of the page that makes it. A page copied from another funnel that still carries the other campaign's key, tag, or call binds and renders without complaint and puts the order on the wrong campaign. Each error names the two files and the two values; make the one-line edit it describes. Not waivable — there is no `checkpoint waive` lane for it. Parked `-backup-` / `-old-` copies are skipped and listed, not scanned. Also resolve `built_output.sdk_markup`: its blockers (`SWAP_WITH_ADD_TO_CART`, `CHECKOUT_NOT_FORM`, `WRONG_FIELD_NAME`, `MISSING_SELECTOR_ID_MATCH`) are markup the SDK binds and then silently no-ops or double-writes on — fix the markup the message names (it gives the SDK spelling for a wrong field name); its warnings (`DOUBLE_SELECTED`, `TEMPLATE_DOUBLE_BRACE`) are advisory. Neither is waivable. A `data-next-*` name the SDK does not read shows up as one advisory line naming the attribute index version, not a warning.
32
+ 7. If doctor's `next` block says `doctor-blocked` or `prepare-build` (it names the same stage `campaigns-os next` would), stop and resolve the named blockers.
33
+ 8. If doctor returns `build`, hand off with `campaigns-os next build --packet <packet>` and follow `next-campaigns-build`'s recommended **build → independent review → repair → verification** loop.
34
+ 9. After build, require polish and a preview deploy before QA. During Polish,
35
+ install the package-owned browser once with `npm run qa:install-browser`,
36
+ serve the current build, and run `campaigns-os polish capture --packet <p> --base-url <served-build-url>` before recording a terminal Polish status.
37
+ The package-owned producer attaches `visual_review.page_load`; never
38
+ hand-author it. Nonwaivable incomplete evidence blocks. A complete hidden
39
+ eager-media finding may receive an exact bound decision through
40
+ `campaigns-os checkpoint waive --packet <p> --gate polish.hidden_eager_media ...`.
41
+ Doctor/next report `ready_with_waivers`; QA
42
+ retains each attributed exception as `ready_with_exceptions`, and one
43
+ exception never suppresses another blocker.
44
+ 10. Run the package-owned proof path in sequence: ensure `npm run qa:install-browser` has completed, run `campaigns-os qa resolve --packet <packet>`, then `campaigns-os qa run --packet <packet> --base-url <url> --browser --test-order common`.
45
+ 11. Treat typed-card proof coverage as the control. Global test cards bypass the gateway and create no transactions, so no permission/approval is needed. `common` runs checkout, first-offer accept and decline, and a deduplicated shortest real receipt path when that adds coverage (at most four orders). `full` walks every actual terminal path in the selected checkout topology; cycles, missing routes, and reachable nonterminals block exhaustive proof before browser launch. The accidental-flood cap remains `6`, and an overflow names the exact explicit `--max-test-orders` raise. Localhost on any port is a Campaigns App Development domain for SDK QA with analytics suppressed; non-localhost preview/production origins still need SDK origin allowlist confirmation.
46
+ 12. Discuss launch only from recorded build, polish, deploy, browser QA, and test-order evidence, or from explicit blockers.
47
+
48
+ ## Session Intake
49
+
50
+ When a Campaigns OS session starts, classify the starting path before handing
51
+ off to setup, build, polish, QA, or promotion. The operator should separate:
52
+
53
+ - Intent: build, partial page update, existing campaign update, QA only, repair from verdict, design/source assembly, or promotion.
54
+ - Source truth: CampaignSpec/Map Builder export, Figma/design file, prepared HTML, existing campaign repo, deployed URL, or target deployment system.
55
+ - Runtime truth: Build Packet, Build Context, Assembly Report, doctor JSON, tested URL, API key source, and SDK origin allowlist state (localhost is already a Development domain; non-localhost origins still need confirmation).
56
+ - Change policy: what may change and what must be preserved, especially checkout, offer logic, routes, legal copy, and live campaign behavior.
57
+ - Proof depth: visual preview, doctor, browser QA, QA portal/local verdict policy, typed-card test-order depth, market coverage, and repair routing.
58
+
59
+ Return a compact brief before acting:
60
+
61
+ ```text
62
+ Mode:
63
+ Intent:
64
+ Source truth:
65
+ Runtime truth:
66
+ Change policy:
67
+ Proof depth:
68
+ Next skill/command:
69
+ Missing inputs:
70
+ ```
71
+
72
+ Use `references/session-intake.md` when the mode, allowed changes, or proof
73
+ depth is unclear. Ask only for fields needed by the selected starting path; a
74
+ QA-only session should not require design files, and a partial landing update
75
+ should not force full checkout/test-order depth unless commerce or routing can be
76
+ affected.
77
+
78
+ Rules:
79
+
80
+ - This is contract-backed guidance and preflight, not full automated readiness.
81
+ - Preserve CampaignSpec as the source of truth. Do not make CampaignSpec absorb source-export paths, target repo paths, template decisions, deploy status, or test-order depth; those belong in the Build Packet and stage reports.
82
+ - Treat `spec.validation` doctor findings as public CampaignSpec rule findings. When JSON output carries `detail.ruleId`, `detail.path`, and `detail.data`, use those fields for UI/repair routing instead of parsing message text.
83
+ - CampaignSpec/API own live commerce values.
84
+ - Treat checkout `exit_intent` and `promo_code_input` as optional CampaignSpec launch contracts. If present, build must wire the mapped offer surface and QA must exercise the accept/apply path.
85
+ - Keep offer application surfaces out of pricing logic: they validate/apply codes through SDK/API, while Campaigns API/SDK own repricing, totals, and discount rows.
86
+ - Starter-template `agentContract` owns reusable commerce structure and protected SDK surfaces.
87
+ - Promoted starter-template families must also have `contracts/template-brand-contract.<family>.v0.json` with family inventory, brand/residue, pricing, and exit-pop rules. Missing family contracts are gates, not advisory gaps.
88
+ - Designed source owns visual composition and page-level content.
89
+ - Brand-theme evidence is workflow-order neutral. Do not assume a Figma export came first; consume `context.theme` and `.campaign-runtime/theme/theme-report.json` when present. A truly missing/ungeneratable theme stays a warning, but a generatable-and-unapplied theme on a commerce-page campaign is a gate: apply it or waive it explicitly before polish/deploy/QA.
90
+ - Follow `campaigns-os next` literally. Every `next` response carries its applicable Store Profile, SDK, hidden eager-media, theme, and broad Polish gates plus `next_actions` with exact commands — execute those instead of improvising. With an active run session, pipeline-advancing commands that don't match the last `next` recommendation are recorded to `.campaign-runtime/agent-deviations.jsonl`; declare an intentional detour with `--deviation-reason "<why>"`.
91
+ - Close the loop: when `next` reports `done` (or QA has published its verdict and the PR is up), finish with `campaigns-os run end` so the Run Record is assembled and the run session clears. `campaigns-os run status` shows incomplete stages and the exact next command at any point.
92
+ - Do not copy demo refs or unsupported optional surfaces into the target campaign.
93
+ - Use SDK conditionals such as `cart.hasCoupon("CODE")` for code-specific presentation; do not mutate visible prices from campaign-specific JavaScript.
94
+ - Build Packet, Build Context, and Assembly Report paths should be repo-relative when possible so handoff artifacts can be committed without machine-local absolute paths.
95
+ - Preserve Build Context `theme` inspection state and Assembly Report `theme` application state when present; they are public v0 contract fields and should not be dropped by wrappers, setup reruns, or repair passes.
96
+ - Store Profile fields are operator-entered storefront/legal metadata for page-kit `campaigns.json`; they do not come from the Campaigns API and should be collected in the CampaignSpec before build.
97
+ - Treat `campaigns-os checkpoint waive` as a staged generic registry, not a universal waiver command. This release registers Store Profile, the Page Kit SDK pin, `polish.hidden_eager_media`, and `built_output.upsell_selector_scope`. The broad Polish Source Freshness gate remains on its existing artifact handling, and theme/QA keep their existing `theme waive` / `qa waive` lanes until those gates are explicitly registered. A checkpoint waiver needs a named human, non-empty reason, and at least one future expiry or non-empty review condition; a waiver remains visible, applies only to its exact checkpoint state, and never turns the checkpoint into a clean pass. Hidden eager-media measurement completeness is never waivable.
98
+ - Keep the lifecycle in a tight sequence. Pause only for missing inputs, doctor blockers, deploy blockers, out-of-scope runtime pages, or merchant-specific uncertainty.
99
+ - `campaigns-os standardize` audits the campaign ecosystem read-only: it recognizes Page Kit roots and non-Page-Kit Campaign Cart applications (Vite/React/Express apps, static HTML funnels) via portable evidence, classifies each root (`implementation.kind`), validates checkout field bindings against the Campaign Cart field contract, and evaluates loader versions against the SDK support policy contract. Findings carry `confidence` (`static_contract`, `static_inference`, `runtime_proof_required`); treat `runtime_proof_required` findings as missing proof, never as confirmed defects, and route them to browser QA rather than static repair.
100
+ - Launch readiness is separate from Campaigns OS proof. Surface production storefront URL, live payment methods, shipping markets, legal/support URLs, analytics expectations, and merchant-side configuration as real-shopper readiness items, not Campaigns OS build blockers.
101
+ - Browser QA and test-order proof are owned by Campaigns OS through Playwright. Do not route the core QA path through external browser skills or hand-built backend orders.
@@ -0,0 +1,160 @@
1
+ # Campaigns OS Session Intake
2
+
3
+ Use this reference when a Campaigns OS session begins without an already-clear
4
+ Build Packet, QA verdict, or promotion task. The goal is to make the operator
5
+ separate intent, source truth, runtime truth, change policy, and proof policy.
6
+
7
+ ## Intake Envelope
8
+
9
+ Return this compact brief before running a specialist skill or command:
10
+
11
+ ```text
12
+ Mode:
13
+ Intent:
14
+ Source truth:
15
+ Runtime truth:
16
+ Change policy:
17
+ Proof policy:
18
+ Next skill/command:
19
+ Missing inputs:
20
+ ```
21
+
22
+ Definitions:
23
+
24
+ - Intent: what the user wants done, such as build, update, QA, repair, or promote.
25
+ - Source truth: CampaignSpec/Map Builder export, Figma/design file, prepared HTML, existing campaign, target repo, or deployed URL.
26
+ - Runtime truth: Build Packet, Build Context, Assembly Report, optional `context.theme` / `.campaign-runtime/theme/theme-report.json`, doctor JSON, repo state, tested URL, Campaigns API key source, SDK origin state (localhost is a Development domain; non-localhost origins need allowlist confirmation), and test-order depth choice.
27
+ - Change policy: what may change and what must be preserved, especially checkout, offer logic, live campaign routes, and legal/merchant copy.
28
+ - Proof depth: visual preview, doctor, browser QA, QA portal/local verdict policy, typed-card test-order depth, market coverage, and repair routing.
29
+
30
+ Ask only for the fields needed by the selected mode. Do not force a full-funnel
31
+ build prompt when the user only needs QA, a partial page update, or repair from
32
+ an existing verdict.
33
+
34
+ ## Starting Paths
35
+
36
+ ### Full Campaign Build
37
+
38
+ Use when the user has CampaignSpec plus source/design material and wants an
39
+ end-to-end campaign.
40
+
41
+ Required before build:
42
+
43
+ - Map ID or CampaignSpec path/URL.
44
+ - Public route slug and target repo/output directory.
45
+ - Source type and source files: Figma, exported HTML, prepared HTML, existing campaign, or other.
46
+ - Pages in scope and any pages to preserve.
47
+ - Template family if known; otherwise infer and ask before locking commerce surfaces.
48
+ - Proof depth, including browser QA and the typed-card test-order depth to run.
49
+
50
+ Route to Build Packet preparation, doctor, setup when scaffold is missing,
51
+ build, polish, then QA.
52
+
53
+ ### Design Or Source Assembly
54
+
55
+ Use when design/source material exists but repo/tooling context is incomplete.
56
+
57
+ Collect:
58
+
59
+ - Source authority: Figma link/file, exported HTML, AI-generated HTML, existing campaign, or assets folder.
60
+ - Intended page map and any commerce surfaces represented in the source.
61
+ - CampaignSpec or Map Builder status, if available.
62
+ - Target implementation uncertainty: repo, template family, public route, deployment target.
63
+
64
+ Output a Build Packet or source-adapter findings. Ask before changing checkout,
65
+ offer, upsell, or receipt behavior when template family or runtime contracts are
66
+ unknown.
67
+
68
+ ### Partial Page Build
69
+
70
+ Use when only landing, presell, checkout skin, upsell, downsell, receipt, or a
71
+ specific component is in scope.
72
+
73
+ Collect:
74
+
75
+ - Page(s) in scope and pages explicitly out of scope.
76
+ - Whether commerce logic, SDK attributes, routing, checkout submit behavior, or offer logic may change.
77
+ - Source authority for the selected page(s).
78
+ - Proof needed for affected surfaces.
79
+
80
+ Route to build or polish for scoped changes, then QA only the affected page
81
+ paths plus downstream runtime paths that may have been affected.
82
+
83
+ ### Existing Campaign Update
84
+
85
+ Use when a deployed or repo-backed campaign already exists.
86
+
87
+ Collect:
88
+
89
+ - Existing repo/branch and preview/production URL.
90
+ - Current Build Packet, pass log, Assembly Report, or doctor output if present.
91
+ - Exact allowed changes and preservation rules.
92
+ - Whether live offer logic, checkout, routes, tracking, or legal copy may change.
93
+
94
+ Run doctor when a packet exists. If no packet exists, reconstruct enough runtime
95
+ truth before editing. Do not infer permission to alter commerce logic from a
96
+ visual update request.
97
+
98
+ ### QA Only
99
+
100
+ Use when the user wants evidence on a deployed campaign and no source edit.
101
+
102
+ Collect:
103
+
104
+ - Map ID and deployed base URL.
105
+ - Build Packet path if local; otherwise enough info to resolve topology.
106
+ - Whether browser QA should run.
107
+ - Whether verdict should use the default QA portal publish path or stay local-only.
108
+ - Typed-card test-order depth (`common`/explicit/`full`).
109
+
110
+ Route to QA. Do not patch campaign code from the QA-only path.
111
+
112
+ ### Repair From QA Verdict
113
+
114
+ Use when a posted/local verdict or QA dashboard run exists.
115
+
116
+ Collect:
117
+
118
+ - Verdict path or dashboard URL/run ID.
119
+ - Build Packet and Assembly Report paths when local.
120
+ - Whether repair may edit source, and which surfaces are protected.
121
+ - The typed-card test-order depth to re-run for the retest.
122
+
123
+ The public verdict is the source of repair truth. Route repairable items to
124
+ specialist skills, ask only the needed clarification questions, and keep
125
+ typed-card order failures as manual/specialist handoffs unless the owner and
126
+ the test-order depth to re-run are clear.
127
+
128
+ ### Promotion Or Experiment
129
+
130
+ Use when the user wants to interpret performance evidence or promote a funnel.
131
+
132
+ Collect:
133
+
134
+ - CampaignSpec path and funnel IDs.
135
+ - Performance by Page evidence or date range.
136
+ - Winner, confidence notes, and any exceptions.
137
+ - Deployment/routing target and whether config changes should become a PR.
138
+
139
+ Route through decision creation, promotion, and generated routing config. Do not
140
+ hand-edit deployed routing config as the primary promotion path.
141
+
142
+ ## Test-Order Proof Policy
143
+
144
+ Treat test orders as cheap, repeatable proof: global test cards bypass the
145
+ gateway and create no transactions, so they need no permission or approval. The
146
+ only real choice is coverage. Record:
147
+
148
+ - Coverage: `common` (checkout, first-offer accept/decline, and a deduplicated shortest real receipt path when needed; at most four orders), `off`, `checkout`, `decline`, `accept`, `both`, `full`, or explicit paths such as `decline-decline-accept`.
149
+ - Cart matrix: base cart, base plus bump, specific package refs/quantities.
150
+ - SDK origin state (so the SDK loads): localhost Development domain, non-localhost allowlisted, or unknown — separate from test-order permission.
151
+ - Max order cap: the accidental-flood guard; raise `--max-test-orders` for exhaustive proof.
152
+ - Market coverage: default market only or at least one non-default country/currency path.
153
+ - Customer email: reuse one inbox via `--test-email`/`CAMPAIGNS_OS_QA_TEST_EMAIL` (the customer record is not deletable).
154
+
155
+ `--test-order common` covers checkout, the first-offer actions, and a shortest
156
+ real receipt path when that adds coverage. Use `full` for every actual terminal
157
+ path in the selected checkout topology. Cycles, missing routes, and reachable
158
+ nonterminals block exhaustive proof before browser launch. The default
159
+ `--max-test-orders 6` cap remains in place; an overflow names the exact explicit
160
+ raise.
@@ -0,0 +1,22 @@
1
+ ---
2
+ name: next-campaigns-os-setup
3
+ version: 2.0.0
4
+ description: Bootstrap or prepare a target page-kit campaign repo from a doctor-cleared Campaigns OS Build Packet before full build wiring. Formerly installed as next-campaigns-setup; renamed 2026-08 to stop colliding with the published NextCommerceCo/skills scaffolder of that name.
5
+ ---
6
+
7
+ # Next Campaigns OS Setup
8
+
9
+ Use this skill when the Build Packet doctor says setup is required before assembly.
10
+
11
+ Responsibilities:
12
+
13
+ - Confirm the target repo exists and has or can install `next-campaign-page-kit`.
14
+ - Create the campaign output directory only through page-kit-compatible structure.
15
+ - When copying a selected starter template family, copy the family as an atomic page-kit slice: pages plus required `_includes/`, `_layouts/`, `assets/css/`, and `assets/js/`. Do not copy only `checkout.html` and `receipt.html`.
16
+ - Public families resolve from the default `public` starter-templates source. A **private** family (one whose source lives in an access-controlled repo, e.g. a certified family not present in the public picker) is scaffolded via page-kit's template-source mechanism (`next-campaign-page-kit` >= 0.2.0): add a named source to the target repo's `_data/template-sources.json` (a `git` source with the SSH `url` + optional `ref`, or a `local` source `path`), then `campaign-init --source <name> --template <slug>`. The source repo must expose a root `templates.json` catalog + `src/<slug>/` tree. page-kit holds no family→repo mapping; the source config lives in the (private) consuming repo, and this skill (plus the family's certified contract) is where that source is known.
17
+ - Install or reference `.campaign-runtime/agent-context` without overwriting existing root agent files.
18
+ - Record setup status in both `.campaign-runtime/build-context.json` (`scaffold.required`, `scaffold.mode`, handoff fields) and `.campaign-runtime/assembly-report.json` (`stages.setup`).
19
+ - Preserve existing Build Context `theme` inspection data and Assembly Report `theme` application data when setup is rerun against an existing campaign directory.
20
+ - Hand off to `next-campaigns-build`.
21
+
22
+ Do not wire checkout, upsell, receipt, payment, package, voucher, or shipping behavior in setup. Build owns that work after the template contract is locked.