@nextcommerce/campaigns-os 1.54.0 → 1.55.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/CHANGELOG.md +84 -0
  2. package/CONTEXT.md +8 -5
  3. package/README.md +26 -12
  4. package/compatibility.json +1 -1
  5. package/contracts/release-ledger.json +441 -0
  6. package/contracts/supported-surface.json +2 -2
  7. package/docs/brand-theme-bridge.md +10 -0
  8. package/docs/build-packet.md +35 -19
  9. package/docs/campaigns-os-build-flow.md +1 -1
  10. package/docs/effects.md +2 -5
  11. package/docs/local-setup.md +1 -1
  12. package/docs/orientation-contract-reference.md +1 -1
  13. package/docs/qa-and-test-orders.md +55 -11
  14. package/docs/runtime-readiness.md +1 -1
  15. package/docs/skills-revision.md +10 -10
  16. package/docs/supported-surface.md +1 -1
  17. package/docs/workflow-findings-sidecar.md +57 -2
  18. package/package.json +3 -1
  19. package/schemas/campaigns-os-run-record.v0.schema.json +20 -15
  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 +3 -3
  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 +4 -4
  29. package/skills.json +10 -10
  30. package/src/adapter-decision-contract.mjs +26 -12
  31. package/src/brand-theme.mjs +44 -8
  32. package/src/campaign-identity.mjs +33 -4
  33. package/src/cli.mjs +36 -59
  34. package/src/consent.mjs +3 -2
  35. package/src/design-source-publication.mjs +1 -1
  36. package/src/deviation.mjs +2 -1
  37. package/src/doctor/checks.mjs +16 -6
  38. package/src/doctor/next-step.mjs +16 -6
  39. package/src/invocation.mjs +4 -3
  40. package/src/lifecycle.mjs +88 -6
  41. package/src/local-preview-policy.mjs +6 -0
  42. package/src/login.mjs +2 -1
  43. package/src/polish-browser.mjs +8 -2
  44. package/src/polish-node.mjs +6 -1
  45. package/src/polish-readability.mjs +2 -2
  46. package/src/qa-browser.mjs +521 -92
  47. package/src/qa-cart-entry.mjs +29 -6
  48. package/src/qa-node.mjs +144 -39
  49. package/src/qa-verdict-publish.mjs +2 -1
  50. package/src/run-record.mjs +46 -34
  51. package/src/sdk-markup.mjs +41 -1
  52. package/src/stage-ledger.mjs +14 -2
  53. package/src/stage-record.mjs +50 -13
@@ -6530,6 +6530,447 @@
6530
6530
  }
6531
6531
  ],
6532
6532
  "entry_sha256": "5ab33ca302fa671ac78c3e9b752ed7b251e756b05256f97ff75acd08c58ad5ba"
6533
+ },
6534
+ {
6535
+ "id": "RL-0246",
6536
+ "sequence": 235,
6537
+ "date": "2026-10-07",
6538
+ "kind": "release",
6539
+ "surface_version": null,
6540
+ "changelog_section": "1.54.0+agent.2",
6541
+ "changelog_sha256": "55155add247bb47b07b43252e374b504ac85aef51f6b3315b8b21e85c615df15",
6542
+ "agent_impact": "None for package consumers: this changes repository CI and contributor scripts only. A contributor can run npm run check:fast before pushing, or install it as a pre-push hook with npm run hooks:install; CI runs the same gates on every pull request.",
6543
+ "compatibility": "compatible",
6544
+ "migration": "none",
6545
+ "changes": [
6546
+ {
6547
+ "class": "workflow",
6548
+ "path": ".github/workflows/ci.yml",
6549
+ "surface_entry": null,
6550
+ "summary": "Run the unit and browser lanes as two shards each on separate runners, and cancel a pull request's older run when a newer push arrives; pushes to main are never cancelled."
6551
+ },
6552
+ {
6553
+ "class": "package_export",
6554
+ "path": "package.json",
6555
+ "surface_entry": null,
6556
+ "summary": "Add the contributor scripts check:fast and hooks:install; exports, bin, files and dependencies are unchanged."
6557
+ }
6558
+ ],
6559
+ "entry_sha256": "ea7360b560411019e58bf65a1b389cbed5ec9589b7da6f09b7cee1b08b46aed8"
6560
+ },
6561
+ {
6562
+ "id": "RL-0247",
6563
+ "sequence": 236,
6564
+ "date": "2026-10-07",
6565
+ "kind": "release",
6566
+ "surface_version": null,
6567
+ "changelog_section": "1.54.0+agent.4",
6568
+ "changelog_sha256": "320b31d293424ab65875a6b05f1d1f2b79ace291914e8311e69fb52738f584b1",
6569
+ "agent_impact": "Treat ready_with_exceptions as passing QA proof and report every exception to the operator without clearing or waiving it or changing markup just to make it pass. Keep the done closeout action. Repeat build work with record build; follow the deploy prompt for hosted deploy recording. A recorded theme waive needs --waived-by with a named human; qa run --theme-waive is one-run only. Unless the operator has already said test orders are fine for this campaign, ask once, up front, before typed-card test orders because they create real store order records, although no transaction or money movement occurs. No command, gate, flag or verdict-schema behavior changes.",
6570
+ "compatibility": "compatible",
6571
+ "migration": "none",
6572
+ "changes": [
6573
+ {
6574
+ "class": "documentation",
6575
+ "path": "CONTEXT.md",
6576
+ "surface_entry": "CONTEXT.md",
6577
+ "summary": "Explain that typed-card test orders create real store order records and require a once-up-front operator question."
6578
+ },
6579
+ {
6580
+ "class": "named_surface",
6581
+ "path": "docs/build-packet.md",
6582
+ "surface_entry": "docs/build-packet.md",
6583
+ "summary": "The done guidance names record build for repeat build work and distinguishes local-serve recording from hosted deploy instructions."
6584
+ },
6585
+ {
6586
+ "class": "named_surface",
6587
+ "path": "docs/campaigns-os-build-flow.md",
6588
+ "surface_entry": "docs/campaigns-os-build-flow.md",
6589
+ "summary": "Explain the real order record and once-up-front operator question before typed-card test orders."
6590
+ },
6591
+ {
6592
+ "class": "named_surface",
6593
+ "path": "docs/qa-and-test-orders.md",
6594
+ "surface_entry": "docs/qa-and-test-orders.md",
6595
+ "summary": "Explain the real store order record and the once-up-front operator question before test orders."
6596
+ },
6597
+ {
6598
+ "class": "named_surface",
6599
+ "path": "docs/skills-revision.md",
6600
+ "surface_entry": "docs/skills-revision.md",
6601
+ "summary": "Publish the 1.54.0+skills.2 bundle revision."
6602
+ },
6603
+ {
6604
+ "class": "skill",
6605
+ "path": "skills.json",
6606
+ "surface_entry": null,
6607
+ "summary": "Publish the 1.54.0+skills.2 bundle revision."
6608
+ },
6609
+ {
6610
+ "class": "skill",
6611
+ "path": "skills/campaign-lifecycle-orientation/SKILL.md",
6612
+ "surface_entry": null,
6613
+ "summary": "Publish the 1.54.0+skills.2 bundle revision."
6614
+ },
6615
+ {
6616
+ "class": "skill",
6617
+ "path": "skills/campaign-readback-classification/SKILL.md",
6618
+ "surface_entry": null,
6619
+ "summary": "Publish the 1.54.0+skills.2 bundle revision."
6620
+ },
6621
+ {
6622
+ "class": "skill",
6623
+ "path": "skills/campaign-run-evidence/SKILL.md",
6624
+ "surface_entry": null,
6625
+ "summary": "Publish the 1.54.0+skills.2 bundle revision."
6626
+ },
6627
+ {
6628
+ "class": "skill",
6629
+ "path": "skills/contribution-intake/SKILL.md",
6630
+ "surface_entry": null,
6631
+ "summary": "Publish the 1.54.0+skills.2 bundle revision."
6632
+ },
6633
+ {
6634
+ "class": "skill",
6635
+ "path": "skills/next-campaigns-build/SKILL.md",
6636
+ "surface_entry": null,
6637
+ "summary": "Publish the 1.54.0+skills.2 bundle revision."
6638
+ },
6639
+ {
6640
+ "class": "skill",
6641
+ "path": "skills/next-campaigns-os-setup/SKILL.md",
6642
+ "surface_entry": null,
6643
+ "summary": "Publish the 1.54.0+skills.2 bundle revision."
6644
+ },
6645
+ {
6646
+ "class": "skill",
6647
+ "path": "skills/next-campaigns-os/SKILL.md",
6648
+ "surface_entry": null,
6649
+ "summary": "Publish the 1.54.0+skills.2 bundle revision."
6650
+ },
6651
+ {
6652
+ "class": "skill",
6653
+ "path": "skills/next-campaigns-polish/SKILL.md",
6654
+ "surface_entry": null,
6655
+ "summary": "Publish the 1.54.0+skills.2 bundle revision."
6656
+ },
6657
+ {
6658
+ "class": "skill",
6659
+ "path": "skills/next-campaigns-qa/SKILL.md",
6660
+ "surface_entry": null,
6661
+ "summary": "Name the recorded theme waiver with the named-human argument and distinguish the one-run ephemeral QA form."
6662
+ },
6663
+ {
6664
+ "class": "cli_surface",
6665
+ "path": "src/cli.mjs",
6666
+ "surface_entry": "next",
6667
+ "summary": "Clarify passing QA exceptions, stage re-recording, recorded versus ephemeral theme waivers, and the test-order operator question in prompts and notices."
6668
+ },
6669
+ {
6670
+ "class": "cli_surface",
6671
+ "path": "src/doctor/next-step.mjs",
6672
+ "surface_entry": "next",
6673
+ "summary": "Keep the done closeout action alongside the passing-QA exception report instruction."
6674
+ }
6675
+ ],
6676
+ "entry_sha256": "05712ef5b61b5e84a2937c2528612206dffde439f2929bb853bd72c015538514"
6677
+ },
6678
+ {
6679
+ "id": "RL-0248",
6680
+ "sequence": 237,
6681
+ "date": "2026-10-07",
6682
+ "kind": "release",
6683
+ "surface_version": null,
6684
+ "changelog_section": "1.54.0+agent.5",
6685
+ "changelog_sha256": "b76dfa416d6d20c2ec5e9c94802e2b811ba7133bf248e9430c283f06e3882398",
6686
+ "agent_impact": "qa run --test-order now drives a bundle-card checkout by each card's data-next-bundle-items. --select-package <pkg>:<qty> and --cart <pkg>:<qty> select the card one of whose declared items is that package at that quantity, preferring a card that declares it alone, even when no inner node repeats the package id; a kit card declaring several items is found by any of them. --cart reads the cards again before each ref. Beside --select-package, --cart never clicks another card in the chosen card's selector group (bundle or plain package cards; a card in no recognised selector container counts as in that group): a ref the chosen card carries is left alone, a ref an order bump or a card in another selector group carries is applied through that control, and any other ref is left unapplied and named in the selected_bundle detail as '--cart <ref:qty> not applied: <reason>'. Read that note as a conflict between the two flags; the order and its reconciliation are those of the card --select-package chose. The browser-order-display-parity row reconciles against the packages and quantities every selected bundle card declares, not its data-next-bundle-id, and, without --select-package, fails when an explicit --cart <ref:qty> is not in the order at that quantity, naming requested and persisted units or saying the order carries no line for the package. Read a failing row whose message says the ordered quantity differs from the request as a wrong-tier order, not a stray charge.",
6687
+ "compatibility": "compatible",
6688
+ "migration": "none",
6689
+ "changes": [
6690
+ {
6691
+ "class": "named_surface",
6692
+ "path": "docs/qa-and-test-orders.md",
6693
+ "surface_entry": "docs/qa-and-test-orders.md",
6694
+ "summary": "Say that --select-package and --cart resolve a bundle card by any one of its data-next-bundle-items, that --cart reads the cards again before each ref, that --cart beside --select-package never clicks another card in the chosen card's selector group (a card in no recognised selector container counts as in it) and names a ref it leaves unapplied, and that display parity reconciles against every selected card's declared packages and, without --select-package, fails on an explicit --cart <ref:qty> the order did not carry at that quantity."
6695
+ }
6696
+ ],
6697
+ "entry_sha256": "dbb47405a3d96886de22e8ad85dcf9a703da0ef122eccb33b6c64ecb66ea4b38"
6698
+ },
6699
+ {
6700
+ "id": "RL-0249",
6701
+ "sequence": 238,
6702
+ "date": "2026-10-07",
6703
+ "kind": "release",
6704
+ "surface_version": null,
6705
+ "changelog_section": "1.54.0+agent.6",
6706
+ "changelog_sha256": "e49fec365f247824e1af1863ce8124a8ec62dbda64c8c94c68fc7734b83833f0",
6707
+ "agent_impact": "Doctor blocks receipt order lines hidden by cart state, including when the CampaignSpec alone identifies the receipt page. When the Build Packet or CampaignSpec supplies the campaign API key directly, or Build Packet campaign.api_key_source names an environment variable, doctor compares it with built keys even when all pages agree. Correct these findings before test orders.",
6708
+ "compatibility": "compatible",
6709
+ "migration": "none",
6710
+ "changes": [
6711
+ {
6712
+ "class": "cli_surface",
6713
+ "path": "src/doctor/checks.mjs",
6714
+ "surface_entry": "doctor",
6715
+ "summary": "Block receipt order items hidden by cart-state visibility and compare built API keys with the packet, spec, or environment key declared by the packet."
6716
+ }
6717
+ ],
6718
+ "entry_sha256": "b56a454c0160f664fd473cbc834146630c207885c2cbf5c2c8e37d294208da4e"
6719
+ },
6720
+ {
6721
+ "id": "RL-0250",
6722
+ "sequence": 239,
6723
+ "date": "2026-10-07",
6724
+ "kind": "release",
6725
+ "surface_version": null,
6726
+ "changelog_section": "1.54.0+agent.7",
6727
+ "changelog_sha256": "8c43339dac5e7fc33ad1bdff344c5db50b2e7b7f8a5d7b631f309676d70e79ce",
6728
+ "agent_impact": "qa run takes --currency <code> to run QA in one currency of a multi-currency campaign: the run adds ?currency=<CODE> to each funnel entry URL it fetches and loads and to the first page load of each test-order path, keeping the existing query; later loads in that tab and a receipt reload carry none, because Campaign Cart keeps the currency for the tab's session. The code must be three letters and is upper-cased; anything else, an empty value included, is refused before any request. The flag takes one code per run (given twice, the last is used): run qa run once per currency. qa parity --currency, and --currency with --legacy-api-test-order, are refused. Read the run currency from evidence.currency on the entry page http:<page_id> assertion of the full verdict; the stored verdict removes URL queries. An entry URL that does not parse carries evidence.currency_not_applied with the reason instead. A run without the flag is unchanged.",
6729
+ "compatibility": "compatible",
6730
+ "migration": "none",
6731
+ "changes": [
6732
+ {
6733
+ "class": "cli_surface",
6734
+ "path": "src/cli.mjs",
6735
+ "surface_entry": "qa",
6736
+ "summary": "The qa run usage line lists --currency <code>; keep the existing QA recommendation command set while next routes owed Polish and QA stages; show an open adapter-decision template in the build prompt and document the single-list behavior, local proof environment, and build fingerprint source in help."
6737
+ },
6738
+ {
6739
+ "class": "named_surface",
6740
+ "path": "docs/qa-and-test-orders.md",
6741
+ "surface_entry": "docs/qa-and-test-orders.md",
6742
+ "summary": "Describe qa run --currency: one code per run, ?currency=<CODE> on the entry URL and on each test-order path's first load with the existing query kept, the three-letter refusal, the qa parity and legacy-order refusals, and evidence.currency (or evidence.currency_not_applied) on the entry page http row."
6743
+ }
6744
+ ],
6745
+ "entry_sha256": "ca7d3c91091fd6c5c857820ffe3ea6b9a62a9f428c0eab26cbf0b1df098fc942"
6746
+ },
6747
+ {
6748
+ "id": "RL-0251",
6749
+ "sequence": 240,
6750
+ "date": "2026-10-07",
6751
+ "kind": "release",
6752
+ "surface_version": null,
6753
+ "changelog_section": "1.54.0+agent.8",
6754
+ "changelog_sha256": "57049338b1514529ff826c0477082d1f9e31de77f0a1308473ab0d7cafb8c01b",
6755
+ "agent_impact": "Next asks for Polish when a local preview theme waiver or changed build leaves it owed, and asks for QA again when the last recorded QA build differs from the current output. A packet preview URL does not replace record deploy. Help invocations never journal, and later start is valid re-intake. Follow next before recording downstream work.",
6756
+ "compatibility": "compatible",
6757
+ "migration": "none",
6758
+ "changes": [
6759
+ {
6760
+ "class": "cli_surface",
6761
+ "path": "src/doctor/next-step.mjs",
6762
+ "surface_entry": "next",
6763
+ "summary": "Pick Polish after a local theme waiver or rebuild, and re-owe QA for a different build while still requiring recorded deploy."
6764
+ },
6765
+ {
6766
+ "class": "named_surface",
6767
+ "path": "docs/build-packet.md",
6768
+ "surface_entry": "docs/build-packet.md",
6769
+ "summary": "Explain the deploy record and QA order after a changed build; list recordable values, explain wrapper_policy intake and read precedence, and document one-list behavior and the report-only write."
6770
+ }
6771
+ ],
6772
+ "entry_sha256": "7ffb028e273e591d224628ceea618df57233286a273e7813ec3a1fb0e47479c4"
6773
+ },
6774
+ {
6775
+ "id": "RL-0252",
6776
+ "sequence": 241,
6777
+ "date": "2026-10-07",
6778
+ "kind": "release",
6779
+ "surface_version": null,
6780
+ "changelog_section": "1.54.0+agent.9",
6781
+ "changelog_sha256": "14a10e9c78458f100c075cff330d5a72364dcd5b00c720a3bf5809843269f542",
6782
+ "agent_impact": "After a page-kit build, record the true scalar adapter choices in one record build --adapter-decision list; a repeated flag keeps only the last list. wrapper_policy remains an intake choice. Doctor reads the effective report, context, then packet conversion status for leftover wrappers and its adapter warnings name the recording command. The Build Packet and Build Context are not written by record build.",
6783
+ "compatibility": "additive",
6784
+ "migration": "none",
6785
+ "changes": [
6786
+ {
6787
+ "class": "cli_surface",
6788
+ "path": "src/doctor/checks.mjs",
6789
+ "surface_entry": "doctor",
6790
+ "summary": "Check leftover source document wrappers against the effective report, context, then packet conversion status."
6791
+ }
6792
+ ],
6793
+ "entry_sha256": "2604e105b3c308004f617b3fd839acc01f32e75dbe4ebf28324f23569aebc5db"
6794
+ },
6795
+ {
6796
+ "id": "RL-0253",
6797
+ "sequence": 242,
6798
+ "date": "2026-10-07",
6799
+ "kind": "release",
6800
+ "surface_version": null,
6801
+ "changelog_section": "1.54.0+agent.10",
6802
+ "changelog_sha256": "c693a2482b40ae5bc570dc591927fc60c2193d339a2c36df8489c885d0028fdd",
6803
+ "agent_impact": "Theme inspection excludes decorative selector subjects from primary and CTA selection while keeping the primary and CTA matching used on main. An accent-only CTA fallback asks the operator to confirm its colour.",
6804
+ "compatibility": "compatible",
6805
+ "migration": "none",
6806
+ "changes": [
6807
+ {
6808
+ "class": "named_surface",
6809
+ "path": "docs/brand-theme-bridge.md",
6810
+ "surface_entry": "docs/brand-theme-bridge.md",
6811
+ "summary": "Explain decorative subject exclusions, main-compatible primary and CTA matching, and the accent-only fallback warning."
6812
+ }
6813
+ ],
6814
+ "entry_sha256": "446b7cc41c5af2352fecedebc543e9bb38a31b025afe2b60848d912e615f902b"
6815
+ },
6816
+ {
6817
+ "id": "RL-0254",
6818
+ "sequence": 243,
6819
+ "date": "2026-10-07",
6820
+ "kind": "release",
6821
+ "surface_version": "1.55.0",
6822
+ "changelog_section": "1.55.0",
6823
+ "changelog_sha256": "cfd5709d45e917e8e4ee92e42b8ceb09d560c9fbf023ca4c6552a55874877e7b",
6824
+ "agent_impact": "Run Records carry QA publish reason, closing path, QA verdict/build binding, prompt wait, bounded doctor/QA codes, and separate needs-input/failure invocation counts. Legacy journal entries keep wait unknown. Agent usage input is gone. Re-emitting a record with agent_usage replaces it with a fresh record without carrying its prior remit state; qa publish posts but cannot stamp that older record as published.",
6825
+ "compatibility": "breaking",
6826
+ "migration": "Stop passing agent usage flags. Re-emitting a legacy agent_usage record replaces it and drops its prior remit state; qa publish posts but cannot stamp it.",
6827
+ "changes": [
6828
+ {
6829
+ "class": "compatibility_policy",
6830
+ "path": "contracts/supported-surface.json",
6831
+ "surface_entry": "contracts/supported-surface.json",
6832
+ "summary": "Advance surface_version to 1.55.0 and record the Run Record schema hash, including lifecycle telemetry fields."
6833
+ },
6834
+ {
6835
+ "class": "named_surface",
6836
+ "path": "docs/effects.md",
6837
+ "surface_entry": "docs/effects.md",
6838
+ "summary": "Remove the obsolete agent usage flag validation description."
6839
+ },
6840
+ {
6841
+ "class": "named_surface",
6842
+ "path": "docs/qa-and-test-orders.md",
6843
+ "surface_entry": "docs/qa-and-test-orders.md",
6844
+ "summary": "Name the nullable QA publish decision reason in the Run Record."
6845
+ },
6846
+ {
6847
+ "class": "compatibility_policy",
6848
+ "path": "docs/supported-surface.md",
6849
+ "surface_entry": "docs/supported-surface.md",
6850
+ "summary": "Mark 1.55.0 breaking: add publish, closeout, QA observation, lifecycle stage wait and finding-code, and run-level exit-count fields; remove agent_usage."
6851
+ },
6852
+ {
6853
+ "class": "named_surface",
6854
+ "path": "docs/workflow-findings-sidecar.md",
6855
+ "surface_entry": "docs/workflow-findings-sidecar.md",
6856
+ "summary": "Document the publish reason, closing path, QA verdict/build binding, prompt wait, code sources, and exit buckets."
6857
+ },
6858
+ {
6859
+ "class": "generated_runtime",
6860
+ "path": "package-lock.json",
6861
+ "surface_entry": null,
6862
+ "summary": "Advance the package version to 1.55.0."
6863
+ },
6864
+ {
6865
+ "class": "package_export",
6866
+ "path": "package.json",
6867
+ "surface_entry": null,
6868
+ "summary": "Advance the package version to 1.55.0 with exports unchanged."
6869
+ },
6870
+ {
6871
+ "class": "schema",
6872
+ "path": "schemas/campaigns-os-run-record.v0.schema.json",
6873
+ "surface_entry": "schemas/campaigns-os-run-record.v0.schema.json",
6874
+ "summary": "Add optional QA publish, closeout, and currency fields plus lifecycle wait, finding codes, and exit buckets; remove agent_usage."
6875
+ },
6876
+ {
6877
+ "class": "cli_surface",
6878
+ "path": "src/cli.mjs",
6879
+ "surface_entry": "run-record",
6880
+ "summary": "Pass each closer through internal options, route prompt wait and finding codes to lifecycle capture, and remove agent usage flags."
6881
+ },
6882
+ {
6883
+ "class": "named_surface",
6884
+ "path": "docs/runtime-readiness.md",
6885
+ "surface_entry": "docs/runtime-readiness.md",
6886
+ "summary": "Regenerate at surface 1.55.0."
6887
+ },
6888
+ {
6889
+ "class": "documentation",
6890
+ "path": "docs/orientation-contract-reference.md",
6891
+ "surface_entry": "docs/orientation-contract-reference.md",
6892
+ "summary": "Regenerate at surface 1.55.0."
6893
+ },
6894
+ {
6895
+ "class": "compatibility_policy",
6896
+ "path": "compatibility.json",
6897
+ "surface_entry": null,
6898
+ "summary": "Advance the declared version to 1.55.0."
6899
+ },
6900
+ {
6901
+ "class": "named_surface",
6902
+ "path": "docs/local-setup.md",
6903
+ "surface_entry": "docs/local-setup.md",
6904
+ "summary": "Pin the 1.55.0 package in the local setup install command."
6905
+ },
6906
+ {
6907
+ "class": "named_surface",
6908
+ "path": "docs/skills-revision.md",
6909
+ "surface_entry": "docs/skills-revision.md",
6910
+ "summary": "Restamp to skills bundle 1.55.0+skills.1."
6911
+ },
6912
+ {
6913
+ "class": "skill",
6914
+ "path": "skills.json",
6915
+ "surface_entry": null,
6916
+ "summary": "Advance bundle_revision to 1.55.0+skills.1 and the patch version of each restamped skill."
6917
+ },
6918
+ {
6919
+ "class": "skill",
6920
+ "path": "skills/campaign-lifecycle-orientation/SKILL.md",
6921
+ "surface_entry": null,
6922
+ "summary": "Restamp to skills bundle 1.55.0+skills.1."
6923
+ },
6924
+ {
6925
+ "class": "skill",
6926
+ "path": "skills/campaign-readback-classification/SKILL.md",
6927
+ "surface_entry": null,
6928
+ "summary": "Restamp to skills bundle 1.55.0+skills.1."
6929
+ },
6930
+ {
6931
+ "class": "skill",
6932
+ "path": "skills/campaign-run-evidence/SKILL.md",
6933
+ "surface_entry": null,
6934
+ "summary": "Restamp to skills bundle 1.55.0+skills.1."
6935
+ },
6936
+ {
6937
+ "class": "skill",
6938
+ "path": "skills/contribution-intake/SKILL.md",
6939
+ "surface_entry": null,
6940
+ "summary": "Restamp to skills bundle 1.55.0+skills.1."
6941
+ },
6942
+ {
6943
+ "class": "skill",
6944
+ "path": "skills/next-campaigns-build/SKILL.md",
6945
+ "surface_entry": null,
6946
+ "summary": "Restamp to skills bundle 1.55.0+skills.1."
6947
+ },
6948
+ {
6949
+ "class": "skill",
6950
+ "path": "skills/next-campaigns-os-setup/SKILL.md",
6951
+ "surface_entry": null,
6952
+ "summary": "Restamp to skills bundle 1.55.0+skills.1."
6953
+ },
6954
+ {
6955
+ "class": "skill",
6956
+ "path": "skills/next-campaigns-os/SKILL.md",
6957
+ "surface_entry": null,
6958
+ "summary": "Restamp to skills bundle 1.55.0+skills.1."
6959
+ },
6960
+ {
6961
+ "class": "skill",
6962
+ "path": "skills/next-campaigns-polish/SKILL.md",
6963
+ "surface_entry": null,
6964
+ "summary": "Restamp to skills bundle 1.55.0+skills.1."
6965
+ },
6966
+ {
6967
+ "class": "skill",
6968
+ "path": "skills/next-campaigns-qa/SKILL.md",
6969
+ "surface_entry": null,
6970
+ "summary": "Restamp to skills bundle 1.55.0+skills.1."
6971
+ }
6972
+ ],
6973
+ "entry_sha256": "cdd823b095d9a05eb39d751c20396d25303dcc00dc1a2c12baeb15ac580e6819"
6533
6974
  }
6534
6975
  ]
6535
6976
  }
@@ -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.54.0",
3
+ "surface_version": "1.55.0",
4
4
  "package_exports": [
5
5
  "./commercial-journey",
6
6
  "./commercial-parity",
@@ -96,7 +96,7 @@
96
96
  "sha256": "d7521fe0ab4deb62485f92286cb890ee548ea290793a6ce7444ecc42ba336d49"
97
97
  },
98
98
  "schemas/campaigns-os-run-record.v0.schema.json": {
99
- "sha256": "00dc9bcec79c12ea22a27f636188bcc33c6811df2d646ac7b49d4cc076e97355"
99
+ "sha256": "390cbc9debacfbfb17d999961baa041a2138fa20a116ec463fbbefbbb05f622d"
100
100
  },
101
101
  "schemas/campaigns-os-runtime-recipe.v1.schema.json": {
102
102
  "sha256": "f8a2ab5eadbb71fb6d5653b670ee71e4471c3df74dd04000d3dbd3d9ae9e71fc"
@@ -22,6 +22,16 @@ It compares source tokens against known `figma-sections-export` scaffold
22
22
  defaults, maps real brand values onto a local versioned next-core target-token
23
23
  contract, and writes evidence into a theme report.
24
24
 
25
+ A rule whose selector subject has a whole sale, discount, badge, rating, star,
26
+ strike, border or announcement name part does not supply primary or CTA unless
27
+ that subject also has a brand, primary, cta, button or btn part, or is a `button`
28
+ element or a submit input. In comma lists,
29
+ the other selectors still count. Primary keeps the header, navigation, brand
30
+ and hero matching used on main, including element selectors and ancestors;
31
+ button backgrounds keep the same CTA matching, including cart, buy, order and
32
+ submit names and IDs. If no CTA token or button background exists, the CTA uses
33
+ the accent fallback and the warning asks the operator to confirm it.
34
+
25
35
  `campaigns-os theme generate` writes:
26
36
 
27
37
  ```text
@@ -1253,25 +1253,39 @@ coverage blocks source readiness.
1253
1253
 
1254
1254
  ## Adapter And Proof Fields
1255
1255
 
1256
- Fresh packets now include `source_html.adapter_contract`. Build Context and
1257
- Assembly Report carry the same values as `adapter_decisions`, and build agents
1258
- should update the report as they complete work.
1256
+ Fresh packets include `source_html.adapter_contract`. Build Context and
1257
+ Assembly Report carry the same values as `adapter_decisions`. After building,
1258
+ record the true scalar decisions with `record build --adapter-decision
1259
+ <key>=<value>[,<key>=<value>...]` (one flag, comma-separated `key=value`
1260
+ pairs). For example, set `raw_html_conversion_status=completed` after source
1261
+ HTML conversion, or `not_required` when there is no source HTML to convert.
1262
+ A repeated `--adapter-decision` flag keeps only the last list. The command
1263
+ writes the Assembly Report only. Doctor's adapter gates and leftover-wrapper
1264
+ check read the effective decisions in report → Build Context → packet order;
1265
+ doctor still validates each copy's shape separately. Source preparation reads
1266
+ the packet's `wrapper_policy`, which is selected at intake with
1267
+ `prepare-build --wrapper-policy` or the source-html manifest's `wrapper_policy`
1268
+ option. The record flag refuses that key, an unknown key, or a value outside
1269
+ the allowed values below. The object-valued
1270
+ `template_files_copied` has no flag: its `status`, `required_groups`, `groups`,
1271
+ and `paths` remain required proof in the report and keep their existing doctor
1272
+ checks.
1259
1273
 
1260
1274
  Required adapter decisions:
1261
1275
 
1262
- | Field | Purpose |
1263
- | --- | --- |
1264
- | `raw_html_conversion_status` | Whether prepared HTML has been converted into page-kit-ready source. |
1265
- | `source_asset_strategy` | How images/fonts/CSS/JS are moved and referenced. Prefer `pagekit_campaign_asset_root`. |
1266
- | `commerce_shell_adoption` | Whether checkout/upsell/downsell/receipt use a template-clone-first SDK surface. |
1267
- | `route_rewrite_policy` | How page links, CTAs, and SDK routing values were rewritten from CampaignSpec routes. |
1268
- | `template_files_copied` | Whether the selected template family was copied/verified as one atomic page-kit slice. |
1269
- | `config_script_strategy` | How campaign config scripts are loaded. |
1270
- | `wrapper_policy` | Whether document wrappers are stripped, preserved, or not required. |
1271
- | `frontmatter_policy` | How Page Kit YAML frontmatter is created or preserved. |
1272
- | `script_style_reference_policy` | How scripts/styles move into frontmatter, campaign assets, inline blocks, or passthrough. |
1273
- | `cta_rewrite_policy` | How CTA destinations are rewritten from CampaignSpec routes. |
1274
- | `layout_choice` | Which Page Kit layout strategy wraps the prepared source. |
1276
+ | Field | Purpose | `record build` allowed values |
1277
+ | --- | --- | --- |
1278
+ | `raw_html_conversion_status` | Whether prepared HTML has been converted into page-kit-ready source. | `pending`, `in_progress`, `completed`, `not_required`, `blocked` |
1279
+ | `source_asset_strategy` | How images/fonts/CSS/JS are moved and referenced. | `pagekit_campaign_asset_root`, `external_cdn`, `raw_passthrough`, `not_applicable`, `unknown` |
1280
+ | `commerce_shell_adoption` | Whether checkout/upsell/downsell/receipt use a template-clone-first SDK surface. | `not_required`, `template_clone_first_required`, `template_clone_first_verified`, `sdk_surfaces_preserved`, `custom_html_experimental` |
1281
+ | `route_rewrite_policy` | How page links, CTAs, and SDK routing values were rewritten from CampaignSpec routes. | `campaignspec_routes_via_campaign_link`, `pagekit_public_routes`, `raw_passthrough`, `not_applicable`, `unknown` |
1282
+ | `template_files_copied` | Whether the selected template family was copied/verified as one atomic page-kit slice. | Object-valued proof; no flag |
1283
+ | `config_script_strategy` | How campaign config scripts are loaded. | `campaign_asset`, `frontmatter_script`, `inline`, `not_required`, `unknown` |
1284
+ | `wrapper_policy` | Whether document wrappers are stripped, preserved, or not required. | Intake only: `strip_document_wrappers`, `preserve_document_wrappers`, `not_required`, `unknown` |
1285
+ | `frontmatter_policy` | How Page Kit YAML frontmatter is created or preserved. | `pagekit_yaml_frontmatter`, `raw_passthrough`, `not_required`, `unknown` |
1286
+ | `script_style_reference_policy` | How scripts/styles move into frontmatter, campaign assets, inline blocks, or passthrough. | `frontmatter_or_campaign_asset`, `frontmatter`, `campaign_asset`, `inline`, `raw_passthrough`, `not_required`, `unknown` |
1287
+ | `cta_rewrite_policy` | How CTA destinations are rewritten from CampaignSpec routes. | `campaignspec_routes_via_campaign_link`, `pagekit_public_routes`, `raw_passthrough`, `not_applicable`, `unknown` |
1288
+ | `layout_choice` | Which Page Kit layout strategy wraps the prepared source. | `campaign_layout`, `page_layout`, `raw_passthrough`, `not_applicable`, `unknown` |
1275
1289
 
1276
1290
  Fresh build context also includes `source.asset_crawl`
1277
1291
  (`source-asset-crawl/v0`). `prepare-build` scans the source HTML files and
@@ -1737,7 +1751,7 @@ hand-editing `.campaign-runtime/` JSON:
1737
1751
  | Command | Writes | Refused (nothing written) when |
1738
1752
  |---|---|---|
1739
1753
  | `campaigns-os record setup --packet <p>` | Build Context `scaffold.required=false` (`handoff_skill` next-campaigns-build) and `stages.setup` completed | the campaign output directory (`assembly.output_dir`) does not exist, or there is no Build Context or Assembly Report |
1740
- | `campaigns-os record build --packet <p> [--build-environment <development\|production>]` | `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 `stages.polish` reset 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 is reset 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, or `stages.setup` is not terminal |
1754
+ | `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 |
1741
1755
  | `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 |
1742
1756
  | `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` |
1743
1757
  | `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 |
@@ -1773,7 +1787,9 @@ check exits non-zero with the problems listed, one per line; a value outside a
1773
1787
  schema enum (for example an `adapter_decisions` policy) is listed with the
1774
1788
  values the schema allows and the value it got. Re-run `record
1775
1789
  build` after every page-kit build; a rebuild that changes the output needs
1776
- `polish capture` and `record polish` again.
1790
+ `polish capture` and `record polish` again. After deploy is recorded for the
1791
+ rebuilt output, `next` asks for QA again if the last QA record names the
1792
+ previous build fingerprint, even while its stage status still says completed.
1777
1793
 
1778
1794
  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, 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.
1779
1795
 
@@ -1808,7 +1824,7 @@ Result shape (with `--json`):
1808
1824
  Terminal states:
1809
1825
 
1810
1826
  - **`stage: "doctor-blocked"`** — doctor returned errors. Resolve the blockers and re-run `campaigns-os doctor` to confirm before calling `next` again.
1811
- - **`stage: "done"`** — every stage is in a terminal status. Pipeline is complete. To re-run a specific stage, set its status back to `"pending"` in the assembly report and call `next` again.
1827
+ - **`stage: "done"`** — every stage is in a terminal status. 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; for a hosted deploy, record the URL and stage outcome as the deploy prompt describes. Then call `next` again.
1812
1828
  - **`stage_blocked: true`** — the picker returned a stage whose recorded status is `blocked`. Don't run the prompt as-is; clear the blocker first.
1813
1829
 
1814
1830
  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.
@@ -12,7 +12,7 @@ The happy path is intentionally tight:
12
12
  8. Run polish, serve the current built output, and run `campaigns-os polish capture --packet <packet> --base-url <served-current-build-url>`. Do not mark Polish terminal or begin deploy/QA until this package-owned page-load evidence passes or has an exact finding waiver.
13
13
  9. Deploy a preview.
14
14
  10. Run `campaigns-os qa resolve --packet <packet>`, then `campaigns-os qa run --packet <packet> --browser --test-order common` with the tested URL. Saved-Map QA uses the existing consent and publication controls; pass `--no-post-verdict` to keep its verdict local. Local-spec QA always keeps verdicts and progress local, even with `--post-verdict`, and `qa publish` refuses local-spec packets. Run Telemetry retains its consent controls.
15
- 11. Treat test-order depth as the control: global test cards bypass the gateway and create no transactions, so no approval is needed. Localhost on any port is a Campaigns App Development domain (SDK allowed, analytics suppressed); non-localhost preview/production origins must still be allowlisted for the campaign API key so the SDK loads.
15
+ 11. Global test cards bypass the gateway and create no transactions, but each test order leaves a real store order record. Unless the operator has already said test orders are fine for this campaign, ask once, up front, before placing test orders; then proceed. There is no permission flag; test-order depth controls coverage. Localhost on any port is a Campaigns App Development domain (SDK allowed, analytics suppressed); non-localhost preview/production origins must still be allowlisted for the campaign API key so the SDK loads.
16
16
  12. Promote, block, or iterate from the recorded build, polish, deploy, QA, and test-order evidence.
17
17
 
18
18
  Pause only for missing inputs, doctor blockers, blocked deploys, out-of-scope runtime pages that block checkout proof, or merchant-specific uncertainty. The default path should not branch into external browser skills or hand-built backend order creation.
package/docs/effects.md CHANGED
@@ -209,9 +209,7 @@ template family is certified, and whether a named brief can be read, depend on
209
209
  file content: those checks still run in the handler and are journaled.
210
210
  The operator-facing `run-record` and `run end` commands refuse bare, empty, or
211
211
  whitespace-only values for every value-taking inherited run-record flag before
212
- packet work. The five agent
213
- token and elapsed-time flags retain their non-negative-integer diagnostics;
214
- `--surfaces` rejects unknown values, and `--dry-run` rejects a value. The
212
+ packet work. `--surfaces` rejects unknown values, and `--dry-run` rejects a value. The
215
213
  inherited boolean flags (`--no-remit`, `--no-write`, `--dry-run`, and `--json`)
216
214
  retain their bare-flag behavior. `run end` also rejects `--new-run` and
217
215
  `--run-id` because the saved session fixes its run ID. `run-record` also
@@ -225,8 +223,7 @@ literal relative path, so the default context file is not read. Bare or empty
225
223
  `--context` or `--report` still makes QA auto-end fail and leaves the session
226
224
  open; bare or empty `--qa-verdict` fails a Run Record closeout when inherited,
227
225
  though QA auto-end supplies its own verdict path. The underlying run-record
228
- handler still rejects invalid agent
229
- integers, unknown `--surfaces`, and any valued `--dry-run` that reaches it. QA
226
+ handler still rejects unknown `--surfaces` and any valued `--dry-run` that reaches it. QA
230
227
  auto-end drops `--dry-run` from inherited flags; if another inherited value
231
228
  fails in the handler, auto-end is skipped and the session stays open. QA's own
232
229
  journal entry is unaffected because auto-end runs after QA persistence. A named
@@ -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.54.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.55.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.54.0`
29
+ Supported surface at generation time: `1.55.0`
30
30
 
31
31
  ## Forward compatibility
32
32