@nextcommerce/campaigns-os 1.57.0 → 1.59.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/campaign-spec/dist/checkout-flow.d.ts +7 -0
  3. package/campaign-spec/dist/checkout-flow.js +17 -1
  4. package/compatibility.json +1 -1
  5. package/contracts/campaign-cart-sdk-support-policy.v0.json +2 -2
  6. package/contracts/commerce-surface-catalog.json +26 -27
  7. package/contracts/effects.v1.json +5 -5
  8. package/contracts/release-ledger.json +432 -0
  9. package/contracts/supported-surface.json +4 -4
  10. package/contracts/template-brand-contract.shared-commerce.v0.json +1 -1
  11. package/docs/build-packet.md +22 -8
  12. package/docs/local-setup.md +1 -1
  13. package/docs/orientation-contract-reference.md +1 -1
  14. package/docs/qa-and-test-orders.md +54 -12
  15. package/docs/runtime-readiness.md +1 -1
  16. package/docs/skills-revision.md +10 -10
  17. package/package.json +1 -1
  18. package/schemas/campaign-runtime-build-context.v0.schema.json +2 -1
  19. package/schemas/campaign-runtime-build-packet.v0.schema.json +2 -1
  20. package/skills/campaign-lifecycle-orientation/SKILL.md +3 -3
  21. package/skills/campaign-readback-classification/SKILL.md +3 -3
  22. package/skills/campaign-run-evidence/SKILL.md +3 -3
  23. package/skills/contribution-intake/SKILL.md +3 -3
  24. package/skills/next-campaigns-build/SKILL.md +6 -6
  25. package/skills/next-campaigns-os/SKILL.md +3 -3
  26. package/skills/next-campaigns-os-setup/SKILL.md +3 -3
  27. package/skills/next-campaigns-polish/SKILL.md +3 -3
  28. package/skills/next-campaigns-qa/SKILL.md +3 -3
  29. package/skills.json +10 -10
  30. package/src/built-site-scope.mjs +91 -0
  31. package/src/cli.mjs +15 -23
  32. package/src/doctor/checks.mjs +73 -3
  33. package/src/doctor/next-step.mjs +3 -14
  34. package/src/polish-node.mjs +5 -4
  35. package/src/qa-browser.mjs +137 -2
  36. package/src/qa-cart-entry.mjs +105 -0
  37. package/src/qa-node.mjs +3 -1
  38. package/src/qa-verdict.mjs +24 -1
  39. package/src/sdk-attribute-index.mjs +8 -7
  40. package/src/source-html-intake.mjs +27 -18
  41. package/src/stage-record.mjs +200 -33
@@ -7676,6 +7676,438 @@
7676
7676
  }
7677
7677
  ],
7678
7678
  "entry_sha256": "00e7dc8146ae7c1e860f2496ade44d5f4e98f3f25120d1a313021e5ff5d28e7c"
7679
+ },
7680
+ {
7681
+ "id": "RL-0262",
7682
+ "sequence": 251,
7683
+ "date": "2026-10-08",
7684
+ "kind": "release",
7685
+ "surface_version": null,
7686
+ "changelog_section": "1.57.0+agent.1",
7687
+ "changelog_sha256": "b6aff356276059f9f4447507b1e179895c45019b53fd9b4c5d0b57adbe6d79f0",
7688
+ "agent_impact": "Reading a 4.2/4.3 spec now carries a retyped checkout_step's forward link onto next_page, so a v4 checkout chain linked through success_url upgrades into a valid v5 path instead of failing CheckoutStepReachesCheckout.",
7689
+ "compatibility": "additive",
7690
+ "migration": "none",
7691
+ "changes": [
7692
+ {
7693
+ "class": "generated_runtime",
7694
+ "path": "campaign-spec/checkout-flow.ts",
7695
+ "surface_entry": null,
7696
+ "summary": "upgradeCampaignSpec writes a retyped page's resolved forward target to next_page and drops its success_url."
7697
+ }
7698
+ ],
7699
+ "entry_sha256": "6ff873f77bcaa4d939ab8693932adf69a450c37d202a86414a201ace8d4787ef"
7700
+ },
7701
+ {
7702
+ "id": "RL-0263",
7703
+ "sequence": 252,
7704
+ "date": "2026-10-09",
7705
+ "kind": "release",
7706
+ "surface_version": "1.58.0",
7707
+ "changelog_section": "1.58.0",
7708
+ "changelog_sha256": "d62aaaeb0c36220ab53768ac465d8471bed051738eeea979a3e1f7a786b6c00a",
7709
+ "agent_impact": "On select and checkout_step pages, Build Context page_kit.frontmatter.next_url is now the Checkout's post-payment destination (for next-success-url) and the new next_step is the page's forward link (for data-next-checkout-step and the select checkout link). success_url is no longer emitted. Landing pages keep next_url as their call-to-action target. Refresh the bundled skills to 1.58.0+skills.1.",
7710
+ "compatibility": "breaking",
7711
+ "migration": "Wire a select or checkout_step page's forward navigation from frontmatter next_step, not next_url, and render next_url as next-success-url. Build against starter templates that include campaign-cart-starter-templates#223. Update the pinned package and bundled skills together.",
7712
+ "changes": [
7713
+ {
7714
+ "class": "compatibility_policy",
7715
+ "path": "compatibility.json",
7716
+ "surface_entry": "compatibility.json",
7717
+ "summary": "Name 1.58.0 as the package version."
7718
+ },
7719
+ {
7720
+ "class": "compatibility_policy",
7721
+ "path": "contracts/supported-surface.json",
7722
+ "surface_entry": "contracts/supported-surface.json",
7723
+ "summary": "Advance surface_version to 1.58.0 and record the two schema hashes."
7724
+ },
7725
+ {
7726
+ "class": "named_surface",
7727
+ "path": "docs/build-packet.md",
7728
+ "surface_entry": "docs/build-packet.md",
7729
+ "summary": "Document next_url and next_step on select and checkout_step pages, the landing-page exception, and success_url no longer emitted."
7730
+ },
7731
+ {
7732
+ "class": "named_surface",
7733
+ "path": "docs/local-setup.md",
7734
+ "surface_entry": "docs/local-setup.md",
7735
+ "summary": "Pin the documented toolkit install to 1.58.0."
7736
+ },
7737
+ {
7738
+ "class": "documentation",
7739
+ "path": "docs/orientation-contract-reference.md",
7740
+ "surface_entry": "docs/orientation-contract-reference.md",
7741
+ "summary": "Regenerate the orientation reference at surface 1.58.0."
7742
+ },
7743
+ {
7744
+ "class": "named_surface",
7745
+ "path": "docs/runtime-readiness.md",
7746
+ "surface_entry": "docs/runtime-readiness.md",
7747
+ "summary": "Regenerate runtime readiness at surface 1.58.0."
7748
+ },
7749
+ {
7750
+ "class": "named_surface",
7751
+ "path": "docs/skills-revision.md",
7752
+ "surface_entry": "docs/skills-revision.md",
7753
+ "summary": "Show the current 1.58.0+skills.1 bundle identity in preflight examples."
7754
+ },
7755
+ {
7756
+ "class": "generated_runtime",
7757
+ "path": "package-lock.json",
7758
+ "surface_entry": null,
7759
+ "summary": "Advance both package version stamps to 1.58.0."
7760
+ },
7761
+ {
7762
+ "class": "package_export",
7763
+ "path": "package.json",
7764
+ "surface_entry": null,
7765
+ "summary": "Advance the package version to 1.58.0."
7766
+ },
7767
+ {
7768
+ "class": "schema",
7769
+ "path": "schemas/campaign-runtime-build-context.v0.schema.json",
7770
+ "surface_entry": "schemas/campaign-runtime-build-context.v0.schema.json",
7771
+ "summary": "Allow next_step in page_kit.frontmatter; describe success_url as no longer emitted."
7772
+ },
7773
+ {
7774
+ "class": "schema",
7775
+ "path": "schemas/campaign-runtime-build-packet.v0.schema.json",
7776
+ "surface_entry": "schemas/campaign-runtime-build-packet.v0.schema.json",
7777
+ "summary": "Allow next_step in page_kit.frontmatter; describe success_url as no longer emitted."
7778
+ },
7779
+ {
7780
+ "class": "skill",
7781
+ "path": "skills.json",
7782
+ "surface_entry": "skills.json",
7783
+ "summary": "Advance the bundle to 1.58.0+skills.1 and each bundled skill by one patch."
7784
+ },
7785
+ {
7786
+ "class": "skill",
7787
+ "path": "skills/campaign-lifecycle-orientation/SKILL.md",
7788
+ "surface_entry": null,
7789
+ "summary": "Bump the skill one patch and stamp bundle 1.58.0+skills.1."
7790
+ },
7791
+ {
7792
+ "class": "skill",
7793
+ "path": "skills/campaign-readback-classification/SKILL.md",
7794
+ "surface_entry": null,
7795
+ "summary": "Bump the skill one patch and stamp bundle 1.58.0+skills.1."
7796
+ },
7797
+ {
7798
+ "class": "skill",
7799
+ "path": "skills/campaign-run-evidence/SKILL.md",
7800
+ "surface_entry": null,
7801
+ "summary": "Bump the skill one patch and stamp bundle 1.58.0+skills.1."
7802
+ },
7803
+ {
7804
+ "class": "skill",
7805
+ "path": "skills/contribution-intake/SKILL.md",
7806
+ "surface_entry": null,
7807
+ "summary": "Bump the skill one patch and stamp bundle 1.58.0+skills.1."
7808
+ },
7809
+ {
7810
+ "class": "skill",
7811
+ "path": "skills/next-campaigns-build/SKILL.md",
7812
+ "surface_entry": null,
7813
+ "summary": "Read next_step for the step form and select link and next_url for next-success-url on select and checkout_step pages; take an express landing page's next-success-url from the Checkout's next_url; bump one patch and stamp bundle 1.58.0+skills.1."
7814
+ },
7815
+ {
7816
+ "class": "skill",
7817
+ "path": "skills/next-campaigns-os-setup/SKILL.md",
7818
+ "surface_entry": null,
7819
+ "summary": "Bump the skill one patch and stamp bundle 1.58.0+skills.1."
7820
+ },
7821
+ {
7822
+ "class": "skill",
7823
+ "path": "skills/next-campaigns-os/SKILL.md",
7824
+ "surface_entry": null,
7825
+ "summary": "Bump the skill one patch and stamp bundle 1.58.0+skills.1."
7826
+ },
7827
+ {
7828
+ "class": "skill",
7829
+ "path": "skills/next-campaigns-polish/SKILL.md",
7830
+ "surface_entry": null,
7831
+ "summary": "Bump the skill one patch and stamp bundle 1.58.0+skills.1."
7832
+ },
7833
+ {
7834
+ "class": "skill",
7835
+ "path": "skills/next-campaigns-qa/SKILL.md",
7836
+ "surface_entry": null,
7837
+ "summary": "Bump the skill one patch and stamp bundle 1.58.0+skills.1."
7838
+ },
7839
+ {
7840
+ "class": "cli_surface",
7841
+ "path": "src/cli.mjs",
7842
+ "surface_entry": null,
7843
+ "summary": "Build prompt wires the step form and select link from next_step and next-success-url from next_url, and names no success_url frontmatter key."
7844
+ }
7845
+ ],
7846
+ "entry_sha256": "437ff972f3680e3bd4e46090fbe67833fb8c988e9ad7dd2aa12c566319afae01"
7847
+ },
7848
+ {
7849
+ "id": "RL-0265",
7850
+ "sequence": 253,
7851
+ "date": "2026-10-09",
7852
+ "kind": "release",
7853
+ "surface_version": null,
7854
+ "changelog_section": "1.58.0+agent.2",
7855
+ "changelog_sha256": "3ef901948a1144f1464052911e651a3637c3ebf8001830de91fb5fb0a941fe9b",
7856
+ "agent_impact": "Doctor (and start/build) warns template_contract.select_step_missing before build when the family puts package selection on a select page, its checkout has no selector, and no select page in the Map leads to a Checkout; the fix is adding a Select page between the entry page and checkout in Map Builder. copy.hardcoded_phone ignores digits in HTML comments, <style> blocks and CSS comments.",
7857
+ "compatibility": "additive",
7858
+ "migration": "none",
7859
+ "changes": [
7860
+ {
7861
+ "class": "cli_surface",
7862
+ "path": "src/doctor/checks.mjs",
7863
+ "surface_entry": "doctor",
7864
+ "summary": "Warn template_contract.select_step_missing when a select-step family's Map declares no select page leading to a Checkout, and mask HTML comments, <style> content and CSS comments in the hardcoded phone scan."
7865
+ }
7866
+ ],
7867
+ "entry_sha256": "19f5719805e5419f0ea78731e98e67adf3fba310dca00f9827d26b90dad4cf33"
7868
+ },
7869
+ {
7870
+ "id": "RL-0266",
7871
+ "sequence": 254,
7872
+ "date": "2026-10-09",
7873
+ "kind": "release",
7874
+ "surface_version": null,
7875
+ "changelog_section": "1.58.0+agent.3",
7876
+ "changelog_sha256": "9bef01116d1c80113af92aea5cb07791aec016cfe203e2cd5ac7759ac5786e73",
7877
+ "agent_impact": "doctor built_output.fingerprint_stale and the polish capture fingerprint refusal now list the extra, missing and changed paths (capped at 20 per list) and flag macOS/iCloud sync conflict copies; record build writes the additive stages.assembly.build_manifest that makes the diff possible. Builds recorded earlier refuse as before and say to re-run record build.",
7878
+ "compatibility": "additive",
7879
+ "migration": "none",
7880
+ "changes": [
7881
+ {
7882
+ "class": "named_surface",
7883
+ "path": "docs/build-packet.md",
7884
+ "surface_entry": "docs/build-packet.md",
7885
+ "summary": "Document stages.assembly.build_manifest and the drift paths named on a fingerprint mismatch."
7886
+ },
7887
+ {
7888
+ "class": "cli_surface",
7889
+ "path": "src/doctor/checks.mjs",
7890
+ "surface_entry": null,
7891
+ "summary": "built_output.fingerprint_stale names extra, missing and changed paths against the recorded manifest and flags sync conflict copies."
7892
+ }
7893
+ ],
7894
+ "entry_sha256": "bf5bf930aecd1ff7c31b5fee33a696236114fe5839c5bffb375be5d0eb5e3ff9"
7895
+ },
7896
+ {
7897
+ "id": "RL-0267",
7898
+ "sequence": 255,
7899
+ "date": "2026-10-09",
7900
+ "kind": "release",
7901
+ "surface_version": null,
7902
+ "changelog_section": "1.58.0+agent.4",
7903
+ "changelog_sha256": "4c5b0cd0c5f605b3511ef07e2927ffd1258f586cd82b52105eb56b4e09566d09",
7904
+ "agent_impact": "QA verdict test_orders[] entries now carry attempt (1-based) beside plan_id, so a re-run of a planned path is distinguishable from another path. purchase_proof gains test_order_attempts and order_paths_executed counts planned paths, not attempts. Read paths, attempts and created orders as three separate counts.",
7905
+ "compatibility": "additive",
7906
+ "migration": "none",
7907
+ "changes": [
7908
+ {
7909
+ "class": "named_surface",
7910
+ "path": "docs/qa-and-test-orders.md",
7911
+ "surface_entry": "docs/qa-and-test-orders.md",
7912
+ "summary": "Document the per-entry attempt number, the paths/attempts/orders summary line, and test_order_attempts in purchase_proof."
7913
+ }
7914
+ ],
7915
+ "entry_sha256": "99c2bba07b9cbe7860b60a5af237081c995eee317586b7f06e86e4f8876d9bb5"
7916
+ },
7917
+ {
7918
+ "id": "RL-0269",
7919
+ "sequence": 256,
7920
+ "date": "2026-10-09",
7921
+ "kind": "release",
7922
+ "surface_version": null,
7923
+ "changelog_section": "1.58.0+agent.6",
7924
+ "changelog_sha256": "0b2061ee2bfd66eca93384feda523af157d96767b47c54dca8988d53740fab42",
7925
+ "agent_impact": "qa run --test-order now chooses a select page's bundle-slot variants before clicking the checkout control: a field showing an os-dropdown UI is picked by clicking its toggle and a row (the row matching the select's current value when in stock, else the first in-stock row), even when the select is pre-filled; a native-only select is filled with its first in-stock option only when empty. Choices are recorded as entered_via_landing evidence variant_selections [{ bundle_id, slot, variant_code, value, via }]. A field with no in-stock row or option, or a row that does not show within 2s of opening the dropdown or cannot be clicked, fails before Next with the new cart-entry code cart_entry_variant_unfilled (classified not_created) instead of cart_entry_no_navigation. Pages whose filled selects have no dropdown UI are unchanged.",
7926
+ "compatibility": "additive",
7927
+ "migration": "none",
7928
+ "changes": [
7929
+ {
7930
+ "class": "named_surface",
7931
+ "path": "docs/qa-and-test-orders.md",
7932
+ "surface_entry": "docs/qa-and-test-orders.md",
7933
+ "summary": "Document slot variant choice on select-page cart entry (dropdown row click or native fill), the variant_selections evidence, and the cart_entry_variant_unfilled code."
7934
+ }
7935
+ ],
7936
+ "entry_sha256": "3d4f8131b1d1d74e4a9f21e98bbbc721d6dd36ba98f8f2617f383adc253a9877"
7937
+ },
7938
+ {
7939
+ "id": "RL-0264",
7940
+ "sequence": 257,
7941
+ "date": "2026-10-09",
7942
+ "kind": "release",
7943
+ "surface_version": null,
7944
+ "changelog_section": "1.58.0+agent.7",
7945
+ "changelog_sha256": "560aa59b997b6acfb7f402654d8d449cdc1291f9823a2f48499a5ceaae3330ef",
7946
+ "agent_impact": "The starter catalog now pins campaign-cart-starter-templates d5ff501: multi-step templates read next_step and render next_url as next-success-url, matching 1.58.0 frontmatter, and certified families ship Campaign Cart SDK 0.4.42. The checkout field-name check reads the v0.4.42 index, and pages pinned to 0.4.42 pass the cart placeholder check.",
7947
+ "compatibility": "compatible",
7948
+ "migration": "none",
7949
+ "changes": [
7950
+ {
7951
+ "class": "named_surface",
7952
+ "path": "docs/build-packet.md",
7953
+ "surface_entry": "docs/build-packet.md",
7954
+ "summary": "Name v0.4.42 as the vendored SDK attribute index tag."
7955
+ }
7956
+ ],
7957
+ "entry_sha256": "d4ba96493d2eaabcb0174df8069fd4636824fd65e94d9eb286167a8ddf595cb1"
7958
+ },
7959
+ {
7960
+ "id": "RL-0268",
7961
+ "sequence": 258,
7962
+ "date": "2026-10-09",
7963
+ "kind": "release",
7964
+ "surface_version": "1.59.0",
7965
+ "changelog_section": "1.59.0",
7966
+ "changelog_sha256": "1c4bd4b6e52a716737ac149211ac9a4f9c26281d1290455c70ae10ec9072f047",
7967
+ "agent_impact": "The 1.59.0 package publishes the untagged 1.58.0 multi-step checkout frontmatter change, its five same-surface follow-ups and a hosted record deploy. record deploy now records an https preview on a hosted packet after checking every built page answers 200 and every same-origin script and stylesheet matches the build; the hosted all-template preview no longer skips the deploy stage. Consumers also gain the select-step doctor warning, named files on a stale build fingerprint, attempt-aware QA verdicts, slot variant choice in QA cart entry and the d5ff501 starter catalog; refresh the bundled skills to 1.59.0+skills.1.",
7968
+ "compatibility": "breaking",
7969
+ "migration": "From the last published 1.57.0, wire a select or checkout_step page forward navigation from frontmatter next_step (not next_url), render next_url as next-success-url, and build against starter templates that include campaign-cart-starter-templates#223. On a hosted target run record deploy --base-url <https preview url> after deploying instead of hand-editing stages.deploy. Update the pinned package and bundled skills together.",
7970
+ "changes": [
7971
+ {
7972
+ "class": "compatibility_policy",
7973
+ "path": "compatibility.json",
7974
+ "surface_entry": "compatibility.json",
7975
+ "summary": "Name 1.59.0 as the published package version."
7976
+ },
7977
+ {
7978
+ "class": "compatibility_policy",
7979
+ "path": "contracts/supported-surface.json",
7980
+ "surface_entry": "contracts/supported-surface.json",
7981
+ "summary": "Advance surface_version to 1.59.0 and record the effects contract hash."
7982
+ },
7983
+ {
7984
+ "class": "named_surface",
7985
+ "path": "docs/local-setup.md",
7986
+ "surface_entry": "docs/local-setup.md",
7987
+ "summary": "Pin the documented toolkit install to 1.59.0."
7988
+ },
7989
+ {
7990
+ "class": "documentation",
7991
+ "path": "docs/orientation-contract-reference.md",
7992
+ "surface_entry": "docs/orientation-contract-reference.md",
7993
+ "summary": "Regenerate the orientation reference at surface 1.59.0."
7994
+ },
7995
+ {
7996
+ "class": "named_surface",
7997
+ "path": "docs/runtime-readiness.md",
7998
+ "surface_entry": "docs/runtime-readiness.md",
7999
+ "summary": "Regenerate runtime readiness at surface 1.59.0."
8000
+ },
8001
+ {
8002
+ "class": "named_surface",
8003
+ "path": "docs/skills-revision.md",
8004
+ "surface_entry": "docs/skills-revision.md",
8005
+ "summary": "Show the current 1.59.0+skills.1 bundle identity in preflight examples."
8006
+ },
8007
+ {
8008
+ "class": "generated_runtime",
8009
+ "path": "package-lock.json",
8010
+ "surface_entry": null,
8011
+ "summary": "Advance both package version stamps to 1.59.0."
8012
+ },
8013
+ {
8014
+ "class": "package_export",
8015
+ "path": "package.json",
8016
+ "surface_entry": null,
8017
+ "summary": "Advance the package version to 1.59.0."
8018
+ },
8019
+ {
8020
+ "class": "skill",
8021
+ "path": "skills.json",
8022
+ "surface_entry": "skills.json",
8023
+ "summary": "Advance the bundle to 1.59.0+skills.1 and each bundled skill by one patch."
8024
+ },
8025
+ {
8026
+ "class": "skill",
8027
+ "path": "skills/campaign-lifecycle-orientation/SKILL.md",
8028
+ "surface_entry": null,
8029
+ "summary": "Bump the skill one patch and stamp bundle 1.59.0+skills.1."
8030
+ },
8031
+ {
8032
+ "class": "skill",
8033
+ "path": "skills/campaign-readback-classification/SKILL.md",
8034
+ "surface_entry": null,
8035
+ "summary": "Bump the skill one patch and stamp bundle 1.59.0+skills.1."
8036
+ },
8037
+ {
8038
+ "class": "skill",
8039
+ "path": "skills/campaign-run-evidence/SKILL.md",
8040
+ "surface_entry": null,
8041
+ "summary": "Bump the skill one patch and stamp bundle 1.59.0+skills.1."
8042
+ },
8043
+ {
8044
+ "class": "skill",
8045
+ "path": "skills/contribution-intake/SKILL.md",
8046
+ "surface_entry": null,
8047
+ "summary": "Bump the skill one patch and stamp bundle 1.59.0+skills.1."
8048
+ },
8049
+ {
8050
+ "class": "skill",
8051
+ "path": "skills/next-campaigns-build/SKILL.md",
8052
+ "surface_entry": null,
8053
+ "summary": "Bump the skill one patch and stamp bundle 1.59.0+skills.1."
8054
+ },
8055
+ {
8056
+ "class": "skill",
8057
+ "path": "skills/next-campaigns-os-setup/SKILL.md",
8058
+ "surface_entry": null,
8059
+ "summary": "Bump the skill one patch and stamp bundle 1.59.0+skills.1."
8060
+ },
8061
+ {
8062
+ "class": "skill",
8063
+ "path": "skills/next-campaigns-os/SKILL.md",
8064
+ "surface_entry": null,
8065
+ "summary": "Bump the skill one patch and stamp bundle 1.59.0+skills.1."
8066
+ },
8067
+ {
8068
+ "class": "skill",
8069
+ "path": "skills/next-campaigns-polish/SKILL.md",
8070
+ "surface_entry": null,
8071
+ "summary": "Bump the skill one patch and stamp bundle 1.59.0+skills.1."
8072
+ },
8073
+ {
8074
+ "class": "skill",
8075
+ "path": "skills/next-campaigns-qa/SKILL.md",
8076
+ "surface_entry": null,
8077
+ "summary": "Bump the skill one patch and stamp bundle 1.59.0+skills.1."
8078
+ },
8079
+ {
8080
+ "class": "compatibility_policy",
8081
+ "path": "contracts/effects.v1.json",
8082
+ "surface_entry": "contracts/effects.v1.json",
8083
+ "summary": "record deploy (and --dry-run) declare the hosted https probe: each built page and each same-origin script and stylesheet, compared by sha256. A record build between the probe and the write refuses on either deploy target."
8084
+ },
8085
+ {
8086
+ "class": "named_surface",
8087
+ "path": "docs/build-packet.md",
8088
+ "surface_entry": "docs/build-packet.md",
8089
+ "summary": "Document hosted record deploy, its refusals and evidence, and drop the hosted all-template deploy skip from the stage order and done outcome."
8090
+ },
8091
+ {
8092
+ "class": "named_surface",
8093
+ "path": "docs/qa-and-test-orders.md",
8094
+ "surface_entry": "docs/qa-and-test-orders.md",
8095
+ "summary": "A hosted all-template preview records its deploy with record deploy before QA."
8096
+ },
8097
+ {
8098
+ "class": "cli_surface",
8099
+ "path": "src/cli.mjs",
8100
+ "surface_entry": null,
8101
+ "summary": "record deploy help names the hosted https rules; the hosted deploy prompt and next actions hand off record deploy instead of hand-editing stages.deploy."
8102
+ },
8103
+ {
8104
+ "class": "cli_surface",
8105
+ "path": "src/doctor/next-step.mjs",
8106
+ "surface_entry": "doctor",
8107
+ "summary": "Remove the hosted_template_preview deploy skip and the hosted_preview_satisfies_deploy done outcome."
8108
+ }
8109
+ ],
8110
+ "entry_sha256": "54697c8b2c8e0857687a01f4ac43942202f8e6f9a523fc1151070ac890a0133d"
7679
8111
  }
7680
8112
  ]
7681
8113
  }
@@ -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.57.0",
3
+ "surface_version": "1.59.0",
4
4
  "package_exports": [
5
5
  "./commercial-journey",
6
6
  "./commercial-parity",
@@ -64,10 +64,10 @@
64
64
  "sha256": "625a6f2ed6bee726f9cddad750e64a54a7e03744c777f5a70afe4a39afdd9848"
65
65
  },
66
66
  "schemas/campaign-runtime-build-context.v0.schema.json": {
67
- "sha256": "1f9bd6cced44a8ba6b29cc650f2b071db67ad710c5a9e9dfe47287eac11e0ebf"
67
+ "sha256": "2aa8f652f6bb602cdbadada34b5793da1bb8842223fcae2fd24700aac14f4de6"
68
68
  },
69
69
  "schemas/campaign-runtime-build-packet.v0.schema.json": {
70
- "sha256": "f0952f64fe9f5ae6147649e5e99b24f215c8d080fca4e330d73f54e49a00d0e2"
70
+ "sha256": "e57d31f190a7ddfbf63afb39bc67762a09dff25707c841e84a4e1c6ee9afd9ed"
71
71
  },
72
72
  "schemas/campaign-spec.v4.schema.json": {
73
73
  "sha256": "af56c3de638d3c4e1fd5df8c2d733754d9ad16caa23b5bec92ce3a6f71bd0271"
@@ -124,7 +124,7 @@
124
124
  "sha256": "dfc9abed38d456969e47a21f606d308a03bdf036f3466f7d6e47a602747dacf4"
125
125
  },
126
126
  "contracts/effects.v1.json": {
127
- "sha256": "10a9020aaba5780e2ee2f3ddf6d81127047f6caec0de774c48540d9b664e0a6a"
127
+ "sha256": "9c1d69e44eab7403ca3ff80f850214d89b0a02fdc51544beef37dbd0a653eeaa"
128
128
  },
129
129
  "schemas/campaigns-os-effects.v1.schema.json": {
130
130
  "sha256": "3eadd22169ab98bc7c2f682af2751267605170581182158d96be035b0cfe44dc"
@@ -55,7 +55,7 @@
55
55
  },
56
56
  "asset_pin": {
57
57
  "repo": "NextCommerceCo/campaign-cart-starter-templates",
58
- "sha": "783329017c6994a94d11e46580c33bd052aabdb0",
58
+ "sha": "d5ff501ab57aef160a7108341de8a952006a28a4",
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
  },
@@ -828,7 +828,7 @@ Blockers (not waivable — the markup provably does not do what it says):
828
828
  - `CHECKOUT_NOT_FORM` — `data-next-checkout` on an element that is not `<form>`.
829
829
  - `WRONG_FIELD_NAME` — `data-next-checkout-field` with a value the SDK does not
830
830
  map. The set is vendored from the SDK at a named tag
831
- (`src/sdk-attribute-index.mjs`, currently v0.4.41: `email`, `fname`, `lname`,
831
+ (`src/sdk-attribute-index.mjs`, currently v0.4.42: `email`, `fname`, `lname`,
832
832
  `phone`, `address1`, `address2`, `city`, `province`, `postal`, `country`,
833
833
  `payment-method`, `accepts_marketing`, `cc-number`, `cc-month`, `cc-year`,
834
834
  `exp-month`, `exp-year`, `cvv`, the legacy `card-*` spellings, and any
@@ -1207,6 +1207,20 @@ recorded build). `polish capture` refuses by name when the built route root is
1207
1207
  missing, unreadable, or drifted; symbolic links are never build output and are
1208
1208
  skipped by the walk.
1209
1209
 
1210
+ `record build` also keeps the manifest itself on `stages.assembly.build_manifest`,
1211
+ a sorted list of `{ "path", "sha256" }` entries that hashes to `build_fingerprint`.
1212
+ When the output drifts, `built_output.fingerprint_stale` and the `polish capture`
1213
+ refusal name the paths that are extra, missing, or changed against it, at most 20
1214
+ per list followed by `(+N more)`; doctor's issue `detail.drift` carries the counts
1215
+ and the same capped lists. An extra path shaped like a macOS or iCloud sync
1216
+ conflict copy (`<name> 2.<ext>`, `<name> 3.<ext>`, ...) whose unsuffixed original
1217
+ also exists is marked `[sync conflict copy]` with a hint to remove those copies and
1218
+ rebuild; a trailing number alone (`chapter 12.html`) is not flagged. A record
1219
+ made before build kept a manifest, or a manifest that does not hash to the recorded
1220
+ fingerprint, refuses as before and says the manifest is unavailable; run
1221
+ `record build` again to record one. Cleaning `_site/` before a build is Page Kit's
1222
+ job, not this check's.
1223
+
1210
1224
  A stale or missing Assembly Source Package Fingerprint is waivable only as an
1211
1225
  exceptional Source Freshness Waiver. The waiver must be structured in
1212
1226
  `waivers[]`, with `scope: "assembly_source_package_freshness"` or an
@@ -1477,7 +1491,7 @@ Fresh `prepare-build` output also writes `source_html.pages[].page_kit` for mapp
1477
1491
  - `output_path` is the same target file relative to `assembly.target_repo`.
1478
1492
  - `public_route` is the rendered campaign-rooted route Page Kit should produce.
1479
1493
  - `page_type` is the CPK runtime/analytics vocabulary (`product`, `checkout`, `upsell`, `receipt`), not the richer CampaignSpec or producer page type. CampaignSpec `select` and `checkout_step` pages project as CPK `checkout` because they render the SDK checkout surface ahead of the page that takes payment.
1480
- - `frontmatter` names the Page Kit frontmatter fields the build should write or preserve. Beside `page_type`, `permalink`, `next_url` and `decline_url`, two keys wire multi-step checkout paths: `success_url`, on every page that leads into a Checkout (a `select` page, a `checkout_step`, or a landing page whose forward links reach one), is that Checkout's post-payment destination and feeds the page's `next-success-url` meta tag, which the SDK reads for express orders; `step_number`, on a `checkout_step` only, is its position on its path from 1, for the step form's `data-next-step-number`. The step form's `data-next-checkout-step` is the page's `next_url`.
1494
+ - `frontmatter` names the Page Kit frontmatter fields the build should write or preserve. Beside `page_type`, `permalink`, `next_url` and `decline_url`, multi-step checkout paths follow the starter-template contract. On a `select` or `checkout_step` page on a path to a Checkout, `next_url` is that Checkout's post-payment destination, the meaning `next_url` has on every checkout page, and feeds the page's `next-success-url` meta tag, which the SDK reads for express orders; `next_step` is the page's forward link, rendered as the step form's `data-next-checkout-step` or the select page's checkout link; `step_number`, on a `checkout_step` only, is its position on its path from 1, for the step form's `data-next-step-number`. A landing page keeps `next_url` as its call-to-action target, so an express landing page takes its `next-success-url` from the Checkout's `next_url`. `success_url` is no longer emitted; the schema still accepts it so packets written by 1.56.0 and 1.57.0 validate.
1481
1495
  - `permalink_required` is true when Page Kit's filename-derived route would not match `public_route`.
1482
1496
 
1483
1497
  An entry page (`is_entry: true`) declares the campaign root when `page_url` is
@@ -1786,7 +1800,7 @@ hand-editing `.campaign-runtime/` JSON:
1786
1800
  | `campaigns-os record build --packet <p> [--build-environment <development\|production>] [--adapter-decision <key>=<value>[,<key>=<value>...]]` | `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, `evidence.build_environment` = the `--build-environment` value when given (kept from the last record otherwise), and the specified scalar `report.adapter_decisions`; all recordable decisions go in one comma-separated flag (a repeated flag keeps only the last list); `wrapper_policy` stays an intake choice. `stages.polish` resets to `required` (`required_by` build, `required_for` qa) unless its evidence is bound to this exact output; a completed `stages.deploy` whose `source_build_fingerprint` names other output resets to `required` the same way, without the old probe's `outputs` and `evidence`, and its prior record is kept in `stages.deploy.history` (a deploy with no `source_build_fingerprint`, recorded before deploy stamped it, is kept) | doctor cannot compute the fingerprint (no `_site/<public_route_slug>/`), setup is still required, `stages.setup` is not terminal, or an adapter decision key/value is invalid |
1787
1801
  | `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 |
1788
1802
  | `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` |
1789
- | `campaigns-os record deploy --packet <p> --base-url <url>` | the packet's `deploy.preview_url` and `stages.deploy` completed with the URL in `outputs`, one evidence line per built page that answered (each page is requested under the URL first), and `source_build_fingerprint` = the recorded `stages.assembly.build_fingerprint` it probed, so a later `record build` of different output makes deploy owed again and `next` routes back to `record deploy` before QA; a byte-identical rebuild keeps it current | 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 |
1803
+ | `campaigns-os record deploy --packet <p> --base-url <url>` | the packet's `deploy.preview_url` and `stages.deploy` completed with the URL in `outputs`, one evidence line per built page that answered (each page is requested under the URL first) and, on a hosted target, one per script or stylesheet served as built, and `source_build_fingerprint` = the recorded `stages.assembly.build_fingerprint` it probed, so a later `record build` of different output makes deploy owed again and `next` routes back to `record deploy` before QA; a byte-identical rebuild keeps it current | the URL does not name the campaign's route root; on a `local-serve` packet, the URL is not a loopback origin or a built page does not answer 2xx; on any other deploy target, the URL is not https (plain http only on a loopback host), a built page does not answer 200, or a script or stylesheet the built pages load from that origin is missing or served with other bytes (sha256) than the built output (each one named; HTML is not compared, since hosts inject markup); polish is not recorded, the built output changed since build was recorded, or the theme gate is blocked |
1790
1804
 
1791
1805
  Each command also refuses a stage `next` has not reached: while doctor's
1792
1806
  prepare-build gate is set (`next` answers prepare-build) or while an earlier
@@ -1795,9 +1809,9 @@ makes: on the local preview, a polish doctor carries forward (never recorded
1795
1809
  for this build) does not hold `record deploy` back, as it does not hold `next`;
1796
1810
  polish stays owed and QA reports it. If every mapped page is template stock on
1797
1811
  a hosted preview, doctor carries the same missing-evidence shape forward.
1798
- `record deploy` remains local-only: record an unset hosted preview URL with
1799
- `campaigns-os qa policy set --packet <p> --preview-url <url>`, then run
1800
- `campaigns-os next --packet <p>`. The hosted preview must be a non-loopback
1812
+ On a hosted target, record an unset hosted preview URL with
1813
+ `campaigns-os qa policy set --packet <p> --preview-url <url>`, then record the
1814
+ deploy with `campaigns-os record deploy --packet <p> --base-url <preview url>`. The hosted preview must be a non-loopback
1801
1815
  HTTP(S) URL whose origin or QA-resolved campaign route path differs from `deploy.production_url`;
1802
1816
  query and fragment text does not make the production page a preview. With
1803
1817
  `deploy.preview_url` recorded, run `campaigns-os next qa --packet <p>` and
@@ -1835,7 +1849,7 @@ build` after every page-kit build; a rebuild that changes the output needs
1835
1849
  rebuilt output, `next` asks for QA again if the last QA record names the
1836
1850
  previous build fingerprint, even while its stage status still says completed.
1837
1851
 
1838
- Stage order: `setup → build → polish → deploy → qa`. The picker walks this list and returns the first stage whose recorded status isn't terminal (`completed`, `completed_with_warnings`, `skipped`), except that a carried-forward all-template hosted preview with a recorded `deploy.preview_url` satisfies deploy without a report record. During Polish, when a design route exists, install the package-owned browser first, then run `campaigns-os polish capture` against the served current build before recording a terminal `stages.polish.status` or proceeding to deploy/QA; the producer attaches package-owned `visual_review.page_load` evidence and never marks the stage complete itself. Template-stock campaigns with no design route have no capture to run and follow the preview policy above.
1852
+ Stage order: `setup → build → polish → deploy → qa`. The picker walks this list and returns the first stage whose recorded status isn't terminal (`completed`, `completed_with_warnings`, `skipped`). During Polish, when a design route exists, install the package-owned browser first, then run `campaigns-os polish capture` against the served current build before recording a terminal `stages.polish.status` or proceeding to deploy/QA; the producer attaches package-owned `visual_review.page_load` evidence and never marks the stage complete itself. Template-stock campaigns with no design route have no capture to run and follow the preview policy above.
1839
1853
 
1840
1854
  | Stage | Report key | Owner |
1841
1855
  |---|---|---|
@@ -1868,7 +1882,7 @@ Result shape (with `--json`):
1868
1882
  Terminal states:
1869
1883
 
1870
1884
  - **`stage: "doctor-blocked"`** — doctor returned errors. Resolve the blockers and re-run `campaigns-os doctor` to confirm before calling `next` again.
1871
- - **`stage: "done"`** — every stage is terminal, or a carried-forward all-template hosted preview satisfies deploy with a recorded `deploy.preview_url` and current-build QA verdict. Pipeline is complete. To repeat build work, do the work and use `record build`; it makes downstream stages owed as needed. Use `record setup` or `record polish` after repeating those stages, and `qa run` for QA. `record deploy` records a local-serve target; other hosted deploys record the URL and stage outcome as the deploy prompt describes. Then call `next` again.
1885
+ - **`stage: "done"`** — every stage is terminal. Pipeline is complete. To repeat build work, do the work and use `record build`; it makes downstream stages owed as needed. Use `record setup` or `record polish` after repeating those stages, and `qa run` for QA. `record deploy` records the served deploy, a loopback URL for a local-serve target or an https URL for a hosted one. Then call `next` again.
1872
1886
  - **`stage_blocked: true`** — the picker returned a stage whose recorded status is `blocked`. Don't run the prompt as-is; clear the blocker first.
1873
1887
 
1874
1888
  The legacy form `campaigns-os next <stage>` (e.g. `next build`) still works and is the way to force a specific stage when you want to override the picker.
@@ -3,7 +3,7 @@
3
3
  For a new campaign, create an empty working folder and run this from it:
4
4
 
5
5
  ```sh
6
- npm init -y && npm install --save-exact next-campaign-page-kit@0.2.0 && npm install --save-dev --save-exact @nextcommerce/campaigns-os@1.57.0 && npx --no-install campaigns-os tooling setup --target . --platform claude
6
+ npm init -y && npm install --save-exact next-campaign-page-kit@0.2.0 && npm install --save-dev --save-exact @nextcommerce/campaigns-os@1.59.0 && npx --no-install campaigns-os tooling setup --target . --platform claude
7
7
  ```
8
8
 
9
9
  `npm init -y` gives the folder its own `package.json`. Without one, npm
@@ -26,7 +26,7 @@ Ledger schema id: `campaigns-os-release-ledger/v1`
26
26
  Change policy version: `1.0.0`
27
27
  Reason-code vocabulary version: `1.0.0`
28
28
  Limits version: `1.0.0`
29
- Supported surface at generation time: `1.57.0`
29
+ Supported surface at generation time: `1.59.0`
30
30
 
31
31
  ## Forward compatibility
32
32