@nextcommerce/campaigns-os 1.34.1 → 1.37.1

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 (115) hide show
  1. package/AGENTS.md +42 -13
  2. package/CHANGELOG.md +87 -0
  3. package/README.md +39 -20
  4. package/contracts/agent-relevant-change-policy.v1.json +1 -0
  5. package/contracts/fixtures/progress/observation.v0.json +89 -0
  6. package/contracts/release-ledger.json +359 -0
  7. package/contracts/supported-surface.json +20 -5
  8. package/demo/apollo-v0/NOTICE.txt +51 -0
  9. package/demo/apollo-v0/assets/css/demo.css +2 -0
  10. package/demo/apollo-v0/assets/css/landing/tokens.css +35 -0
  11. package/demo/apollo-v0/assets/css/next-core.css +16124 -0
  12. package/demo/apollo-v0/assets/images/1x1_1.svg +19 -0
  13. package/demo/apollo-v0/assets/images/1x1_2.svg +19 -0
  14. package/demo/apollo-v0/assets/images/affirm-logo.svg +24 -0
  15. package/demo/apollo-v0/assets/images/apple-pay-logo.svg +4 -0
  16. package/demo/apollo-v0/assets/images/bancontact-logo.svg +1 -0
  17. package/demo/apollo-v0/assets/images/cc-visa.svg +28 -0
  18. package/demo/apollo-v0/assets/images/cc_amex.svg +20 -0
  19. package/demo/apollo-v0/assets/images/cc_discover.svg +21 -0
  20. package/demo/apollo-v0/assets/images/cc_master.svg +22 -0
  21. package/demo/apollo-v0/assets/images/credit-card-flags.svg +38 -0
  22. package/demo/apollo-v0/assets/images/demo-inline-40788e52a7c75b78.svg +1 -0
  23. package/demo/apollo-v0/assets/images/demo-inline-686e73c8840a0f0a.svg +1 -0
  24. package/demo/apollo-v0/assets/images/google-pay-logo.svg +7 -0
  25. package/demo/apollo-v0/assets/images/guarantee-badge.png +0 -0
  26. package/demo/apollo-v0/assets/images/icon-dollar.svg +5 -0
  27. package/demo/apollo-v0/assets/images/icon-guarantee.svg +5 -0
  28. package/demo/apollo-v0/assets/images/icon-shipping.svg +5 -0
  29. package/demo/apollo-v0/assets/images/icons8-lock-24_1icons8-lock-24.png +0 -0
  30. package/demo/apollo-v0/assets/images/ideal-logo.svg +30 -0
  31. package/demo/apollo-v0/assets/images/klarna-logo.svg +9 -0
  32. package/demo/apollo-v0/assets/images/landing/_shared/16x9.svg +19 -0
  33. package/demo/apollo-v0/assets/images/landing/_shared/1x1_1.svg +19 -0
  34. package/demo/apollo-v0/assets/images/landing/_shared/4x3.svg +19 -0
  35. package/demo/apollo-v0/assets/images/landing/_shared/arrow-right.svg +6 -0
  36. package/demo/apollo-v0/assets/images/landing/_shared/cta-guarantee-icon.png +0 -0
  37. package/demo/apollo-v0/assets/images/landing/benefits-2/benefits-2-icon-1.svg +8 -0
  38. package/demo/apollo-v0/assets/images/landing/benefits-2/benefits-2-icon-2.svg +10 -0
  39. package/demo/apollo-v0/assets/images/landing/benefits-2/benefits-2-icon-3.svg +13 -0
  40. package/demo/apollo-v0/assets/images/landing/benefits-2/benefits-2-icon-4.svg +11 -0
  41. package/demo/apollo-v0/assets/images/landing/benefits-2/benefits-2-quote.svg +6 -0
  42. package/demo/apollo-v0/assets/images/landing/benefits-2/benefits-2-verified.svg +10 -0
  43. package/demo/apollo-v0/assets/images/landing/bottomcta-1/check-bullet.svg +5 -0
  44. package/demo/apollo-v0/assets/images/landing/faq-1/faq-chevron.svg +6 -0
  45. package/demo/apollo-v0/assets/images/landing/footer-1/footer-logo.png +0 -0
  46. package/demo/apollo-v0/assets/images/landing/guarantee-1/guarantee-1-badge.svg +8 -0
  47. package/demo/apollo-v0/assets/images/landing/hero-1/icon-check.svg +5 -0
  48. package/demo/apollo-v0/assets/images/landing/hero-1/icon-star.svg +6 -0
  49. package/demo/apollo-v0/assets/images/landing/hero-1/icon-verified.svg +6 -0
  50. package/demo/apollo-v0/assets/images/landing/icons-5/icon-batteries.svg +7 -0
  51. package/demo/apollo-v0/assets/images/landing/icons-5/icon-cuff-checking.svg +6 -0
  52. package/demo/apollo-v0/assets/images/landing/icons-5/icon-dual-user.svg +5 -0
  53. package/demo/apollo-v0/assets/images/landing/icons-5/icon-fda-cleared.svg +5 -0
  54. package/demo/apollo-v0/assets/images/landing/icons-5/icon-heartbeat.svg +17 -0
  55. package/demo/apollo-v0/assets/images/landing/icons-5/icon-lcd-display.svg +10 -0
  56. package/demo/apollo-v0/assets/images/landing/icons-5/icon-movement-error.svg +7 -0
  57. package/demo/apollo-v0/assets/images/landing/icons-5/icon-portable.png +0 -0
  58. package/demo/apollo-v0/assets/images/landing/icons-5/icon-reading-memory.svg +6 -0
  59. package/demo/apollo-v0/assets/images/landing/icons-5/icon-wrist-comfort.svg +5 -0
  60. package/demo/apollo-v0/assets/images/landing/ingredients-3/ingredients-3-card-1.jpg +0 -0
  61. package/demo/apollo-v0/assets/images/landing/ingredients-3/ingredients-3-card-2.jpg +0 -0
  62. package/demo/apollo-v0/assets/images/landing/ingredients-3/ingredients-3-card-3.jpg +0 -0
  63. package/demo/apollo-v0/assets/images/landing/ingredients-3/ingredients-3-card-4.jpg +0 -0
  64. package/demo/apollo-v0/assets/images/landing/ingredients-3/ingredients-3-promise-1.png +0 -0
  65. package/demo/apollo-v0/assets/images/landing/ingredients-3/ingredients-3-promise-2.png +0 -0
  66. package/demo/apollo-v0/assets/images/landing/ingredients-3/ingredients-3-promise-3.png +0 -0
  67. package/demo/apollo-v0/assets/images/landing/ingredients-3/ingredients-3-promise-4.png +0 -0
  68. package/demo/apollo-v0/assets/images/landing/ingredients-3/ingredients-3-promise-5.png +0 -0
  69. package/demo/apollo-v0/assets/images/landing/ingredients-3/ingredients-3-promise-6.png +0 -0
  70. package/demo/apollo-v0/assets/images/landing/nav-1/flag-us.png +0 -0
  71. package/demo/apollo-v0/assets/images/landing/reviews-3/star-card.svg +3 -0
  72. package/demo/apollo-v0/assets/images/landing/reviews-3/star-lg.svg +3 -0
  73. package/demo/apollo-v0/assets/images/landing/reviews-3/star-sm.svg +3 -0
  74. package/demo/apollo-v0/assets/images/landing/reviews-3/verified.svg +10 -0
  75. package/demo/apollo-v0/assets/images/landing/testimonials-2/testimonials-2-reactions.svg +9 -0
  76. package/demo/apollo-v0/assets/images/landing/testimonials-2/testimonials-2-stars.svg +6 -0
  77. package/demo/apollo-v0/assets/images/link-logo.svg +1 -0
  78. package/demo/apollo-v0/assets/images/next-dark.svg +8 -0
  79. package/demo/apollo-v0/assets/images/paypal-logo.svg +5 -0
  80. package/demo/apollo-v0/assets/images/paypal-txt.svg +8 -0
  81. package/demo/apollo-v0/assets/images/paypal.svg +22 -0
  82. package/demo/apollo-v0/assets/images/sepa-logo.svg +275 -0
  83. package/demo/apollo-v0/assets/images/twint-logo.svg +1 -0
  84. package/demo/apollo-v0/assets/images/united-states-flag-icon.webp +0 -0
  85. package/demo/apollo-v0/assets/images/upsell-payment-logos.svg +38 -0
  86. package/demo/apollo-v0/assets/images/usps.png +0 -0
  87. package/demo/apollo-v0/checkout/index.html +1370 -0
  88. package/demo/apollo-v0/landing/index.html +1836 -0
  89. package/demo/apollo-v0/provenance.json +342 -0
  90. package/demo/apollo-v0/receipt/index.html +292 -0
  91. package/demo/apollo-v0/upsell-bundle-stepper/index.html +401 -0
  92. package/docs/activation-and-evidence.md +37 -0
  93. package/docs/demo-preview.md +63 -0
  94. package/docs/diagnostics.md +55 -0
  95. package/docs/orientation-contract-reference.md +2 -1
  96. package/docs/progress-snapshots.md +142 -0
  97. package/docs/runtime-readiness.md +1 -1
  98. package/docs/supported-surface.md +13 -1
  99. package/package.json +13 -3
  100. package/schemas/campaign-runtime-build-context.v0.schema.json +42 -0
  101. package/schemas/campaigns-os-progress-snapshot.v0.schema.json +370 -0
  102. package/skills/next-campaigns-build/SKILL.md +17 -1
  103. package/skills/next-campaigns-os/SKILL.md +19 -3
  104. package/skills/next-campaigns-os-setup/SKILL.md +17 -1
  105. package/skills/next-campaigns-polish/SKILL.md +18 -2
  106. package/skills/next-campaigns-qa/SKILL.md +24 -8
  107. package/skills.json +5 -5
  108. package/src/cli.mjs +74 -4
  109. package/src/consent.mjs +2 -2
  110. package/src/demo-artifact.mjs +97 -0
  111. package/src/demo.mjs +85 -0
  112. package/src/diagnostic.mjs +101 -0
  113. package/src/install-mode.mjs +13 -1
  114. package/src/progress-node.mjs +177 -0
  115. package/src/progress.mjs +133 -0
@@ -0,0 +1,142 @@
1
+ # Minimal progress observations
2
+
3
+ Candidate release **1.36.0** adds the portable `@nextcommerce/campaigns-os/progress`
4
+ export and `schemas/campaigns-os-progress-snapshot.v0.schema.json`. The currently
5
+ published install example does not include this feature. Progress is a compact
6
+ observation of the existing lifecycle, not a second workflow or proof of readiness.
7
+
8
+ `next --packet <packet>` records the canonical picker result after the same doctor
9
+ checks that supply its continuation and gates. Agents run `next` after setup,
10
+ assembly, polish and preview deployment so those committed stage reports become
11
+ visible. The CLI `build` command prepares inputs and runs doctor; it does not build
12
+ or deploy the campaign. Preview's existing stage is `deploy`. Arbitrary edits are
13
+ not tracked. `qa run --packet <packet>` observes its successfully committed or
14
+ unchanged QA report before the existing closeout: ready QA closes its run once,
15
+ blocked QA keeps it open. A progress delivery cannot close a run.
16
+
17
+ ## What is shared
18
+
19
+ The strict v0 object carries its schema, package version, observation timestamp,
20
+ producer (`next` or `qa`), opaque progress stream and sequence, prior snapshot ID,
21
+ content digest, Map ID and separate revision/spec/build hashes. Six independent
22
+ stage records retain observed status and explicit build binding. Continuation
23
+ retains the canonical stage, blocked/divergent flags, fixed action IDs and gate
24
+ states. Preview carries only presence and a hash of the URL. An optional QA block
25
+ retains the exact verdict ID, disposition (including `ready_with_exceptions`),
26
+ binding and publication state. Publication failure does not invalidate a locally
27
+ retained verdict; recovery uses `qa publish`, without repeating an order.
28
+
29
+ No commands, prompts, free text, content, local paths, URLs, query strings,
30
+ credentials, order values or customer payloads enter the wire. Unknown vocabulary
31
+ becomes a fixed `unknown` marker and cannot imply a passing continuation. A
32
+ stage's observed `completed` status is a ledger claim, not independent verification.
33
+ Only matching fingerprints carry `matching`; absent or unverifiable binding is
34
+ `unconfirmed`. A current local output hash never proves a deployment is current.
35
+
36
+ The identity algorithms are deliberately different:
37
+
38
+ - `map-store-v1` retains the original saved Map hash. A fresh Map fetch records
39
+ that hash and the fetched local semantic baseline in Build Context intake.
40
+ Saved revision alignment is `aligned` only while the local spec still matches
41
+ that baseline and the context names this packet and Map. Existing contexts,
42
+ offline caches and local exports without that provenance remain `unconfirmed`.
43
+ The saved hash may still be retained as identity; it alone proves no alignment.
44
+ - `campaign-spec-material-v1` hashes recursively key-sorted JSON after removing
45
+ top-level `spec_identity`, `slug`, `map_id` and `saved_at`, as existing
46
+ `specMaterialHash` does. It includes lifecycle and parent Map fields that the
47
+ saved Map producer excludes. It must never be compared as a Map-store hash.
48
+ Assembly Report `identity.spec_hash` is a raw-byte hash and is not this value.
49
+ - `sha256-manifest/v1` is the existing doctor's output fingerprint: SHA-256 of
50
+ the sorted relative-path and file-SHA-256 manifest under the built route.
51
+ Reported assembly/QA binding uses the doctor's actual observed output and its
52
+ recorded-fingerprint comparison. Missing output remains nullable/unconfirmed.
53
+
54
+ Different Map revisions, local specs, builds, packet/context/report bindings and
55
+ endpoint scopes have independent streams. Completed stages cannot be combined
56
+ across them. A progress stream is independent of a run-session ID.
57
+
58
+ ## Capture and delivery
59
+
60
+ Sanitized immutable snapshots are written under the target repository's
61
+ `.campaign-runtime/progress/` before any request. Allocation uses an exclusive
62
+ local lock with a process owner. Dead owners are recovered through an exclusive
63
+ recovery claim and an atomic rename; a live process is never evicted. An ownerless
64
+ crash gap is recoverable after ten seconds. If recovery itself is interrupted,
65
+ capture fails closed: stop all Campaigns OS writers for that target, then remove
66
+ the abandoned `.allocation-lock` directory in the affected progress scope before
67
+ retrying `next`. Do not remove a lock while a writer is active.
68
+
69
+ An unchanged projection reuses its ID, timestamp and sequence. Identity
70
+ changes start a new stream. Each local scope retains at most 32 snapshots and
71
+ separate remit metadata; retention can leave an incomplete history. There is no
72
+ daemon. A later observation retries its current pending delivery; old pending
73
+ snapshots remain in the bounded local history, without background sends.
74
+
75
+ `--no-write` disables both capture and delivery. `--no-remit` keeps capture local.
76
+ `--no-run-session` does not start a session. A missing/invalid Map ID keeps the
77
+ observation local with `map_id_missing`; a missing campaign key similarly yields
78
+ `campaign_key_missing`. Capture or delivery failures never alter the lifecycle
79
+ result or exit status.
80
+ Capture may wait up to 1.5 seconds for allocation. Delivery is awaited within
81
+ its separate two-second network budget. Unchanged lifecycle results mean the
82
+ command's output and status remain unchanged; these bounded waits can add latency.
83
+
84
+ The planned ops receiver is `POST /api/progress`. Destination precedence is an
85
+ explicit `--proxy-base`, then the bound Build Context's `intake.proxy_base`, then
86
+ the canonical NEXT endpoint only when there is no source binding. An invalid or
87
+ foreign source binding fails closed, including a context without a nonempty
88
+ matching packet pointer. An explicit endpoint override remains independent of
89
+ that context, and cannot confirm its saved revision.
90
+
91
+ HTTPS and plain HTTP loopback are accepted;
92
+ userinfo, query, fragment and other protocols are refused. Redirects are refused.
93
+ The existing campaign-key resolver supplies `X-Campaign-Key`; keys never enter
94
+ snapshots or metadata.
95
+
96
+ The same telemetry on/off choice governs sharing. Canonical delivery defaults on;
97
+ explicit off, malformed environment/configuration and scope mismatch keep delivery
98
+ off. Consent off still permits the sanitized local capture and sends no request.
99
+ Noncanonical progress delivery requires an explicit matching scoped file
100
+ opt-in (`telemetry on --proxy-base <endpoint>`). Unlike existing Run Record remit,
101
+ unscoped environment ON cannot bypass scope for progress; it yields
102
+ `scoped_consent_required`. Minimal stage observations are intended to be visible
103
+ in Workspace. This producer does not implement the receiver or Workspace UI.
104
+
105
+ Delivery uses a total two-second budget, at most one initial request and one retry
106
+ for transport errors, 429 or 5xx. Both requests use identical canonical JSON bytes,
107
+ ID and timestamp. A response body is bounded to 4 KiB. A 2xx or 409 succeeds only
108
+ with `{ "ok": true, "snapshot_id": "<id>", "digest": "<same-id>" }`. Other
109
+ 400/401/403/409 answers and nonmatching acknowledgments remain failed; a conflict
110
+ never silently counts as stored. Response error text is never copied to metadata.
111
+
112
+ ## Portable consumption
113
+
114
+ ```js
115
+ import {
116
+ verifyProgressSnapshot, groupProgressHistories, progressStorageKey,
117
+ } from '@nextcommerce/campaigns-os/progress';
118
+
119
+ const checked = await verifyProgressSnapshot(snapshot);
120
+ const histories = await groupProgressHistories(snapshots);
121
+ const key = progressStorageKey(snapshot, scopeHash);
122
+ ```
123
+
124
+ The export uses standard Web Crypto and TextEncoder; it has no Node, filesystem
125
+ or network dependency. `validateProgressSnapshot` checks bounded strict shape and
126
+ binding invariants; `verifyProgressSnapshot` also verifies the content digest.
127
+ `snapshot_id` hashes recursively key-sorted JSON of every field except itself.
128
+ Canonical transport JSON includes the ID, with no whitespace or newline.
129
+ The exported schema and supported example fixture agree byte-for-byte in tests.
130
+
131
+ `groupProgressHistories` accepts at most 256 snapshots, groups whole observations
132
+ by complete identity plus stream, removes exact duplicate IDs and sorts sequences.
133
+ Groups are `conflicted`, `incomplete`, `unconfirmed` or `observed`. It neither
134
+ chooses a lifecycle stage nor merges completion claims. `observed` confers no
135
+ receiver trust or readiness. Invalid members are rejected with fixed reason codes.
136
+
137
+ The planned immutable receiver key is
138
+ `progress:v0:<scope-hex>:<map-id>:<revision-hex>:<stream>:<sequence>:<digest-hex>`.
139
+ `progressStorageKey` returns null without a valid shape, scope hash, Map or saved
140
+ revision. A key match identifies scope; it is not authentication or trust. The
141
+ receiver must verify the digest and authorized Map scope and stamp its own trust.
142
+ Unknown, incomplete or conflicted histories must never yield a ready workspace.
@@ -8,7 +8,7 @@
8
8
 
9
9
  How a checkout of this repository at one commit becomes a usable installed runtime, and how a consumer decides whether a prepared one is still trustworthy. Everything below is generated from `contracts/runtime-recipe.campaigns-os-node-v1.json`, which is the only authority for these values.
10
10
 
11
- Recipe kind `campaigns-os-node-v1`, revision `1.0.2`, validated by `schemas/campaigns-os-runtime-recipe.v1.schema.json` (`Campaigns OS Runtime Recipe v1`). Supported surface at generation time: `1.34.1`.
11
+ Recipe kind `campaigns-os-node-v1`, revision `1.0.2`, validated by `schemas/campaigns-os-runtime-recipe.v1.schema.json` (`Campaigns OS Runtime Recipe v1`). Supported surface at generation time: `1.37.1`.
12
12
 
13
13
  ## What this is
14
14
 
@@ -14,7 +14,7 @@ implementation detail, however stable it looks.
14
14
  | Surface | Contract | Change discipline |
15
15
  |---|---|---|
16
16
  | `schemas/*.schema.json` (all of them) | The portable contract catalog: CampaignSpec, Design Source Package, Build Packet, Build Context, Assembly Report, Doctor Output, sidecar-bundle conformance, Run Record, Workflow Finding, Build Brief, Source-HTML Manifest, Tooling Orientation, Release Ledger, QA Verdict, the QA Verdict sidecar projection, Runtime Recipe, and the legacy-migration inventory/plan/receipt trio. | Hashed. Any content change requires updating the recorded hash **and** bumping `surface_version` in the same PR. A shape change that alters meaning gets a new schema-version const — one version identifier must never cover two shapes (the 2026-08 assembly-report drift is the incident this rule encodes). Additions to an open `v0` schema are expected and consumers must tolerate unknown fields; the security-sensitive legacy-migration schemas are closed, so additions there require a new lineage. 1.28.0 (RL entry `surface_version: 1.28.0`, breaking) removed the two required Build Packet booleans `qa.test_orders_allowed` and `qa.sandbox_test_card_confirmed` (nothing read them; test orders run from `--test-order <mode>` alone), added `local-serve` to the `deploy.target` enum, and added the optional `remit_result` / `remit_base_kind` fields to the Run Record. 1.30.0 (additive) added the optional `data_layer` record to the QA Verdict's `test_orders[]` entries — the order's `dl_purchase` reading (#325). 1.33.0 (additive) added the optional `qa_verdict_publish` block to the Run Record — which verdict was posted to the QA portal, by `qa run` or `qa publish`, and what the portal answered, in the `remit_result` vocabulary (#328). |
17
- | CLI commands: `start`, `prepare-build`, `build`, `polish`, `checkpoint`, `page-kit`, `spec`, `doctor`, `bundle`, `next`, `theme`, `tooling`, `install-skills`, `install-agent-context`, `validate-assembly-report`, `telemetry`, `standardize`, `qa`, `findings`, `run-record`, `run`, `sdk` | Scriptable entry points. The founding list (1.0.0) was the argv surface Campaigns Agent's remit fixture pins; 1.25.0 adds the partner entry path the public guides instruct — `install-skills` (skill install), `tooling status` (preflight), `next --packet` (the runtime cursor) — plus `theme`, `install-agent-context`, `validate-assembly-report`, and `telemetry`, since consent is part of the partner contract. `validate-build-packet`, formerly an undocumented and unsupported alias of `doctor`, was removed in 1.25.0+agent.7 (RL-0036) and now gets the unknown-command error; use `doctor`. `standardization-report`, a supported but redundant second spelling of `standardize` — same flags, same output, same exit codes — was removed in 1.27.0 and now gets the same unknown-command error; use `standardize`. Removing a supported command is a breaking change and is why that release moved the minor. `bundle check` validates the canonical JSON readback set and makes QA required only under `--require-qa`. `polish capture` owns page-load evidence production. `checkpoint waive` currently accepts four registered gates: `page_kit.store_profile`, `page_kit.sdk_version`, `polish.hidden_eager_media`, and `built_output.upsell_selector_scope`. `page-kit sync` (added in 1.29.0) writes the CampaignSpec's Store Profile fields and SDK pin into the target's `_data/campaigns.json` entry — the repair the first two gates name — and is the only `page-kit` subcommand. `spec derive` (added in 1.31.0) is the reverse write for the repo-derived field class (#432): the target's SDK pin, page routes and analytics ids into the packet's local CampaignSpec; it is the only `spec` subcommand, and the `page_kit.sdk_version.repo_newer` advisory names it; its `--write-map` flag (1.33.0+agent.2) also records the derived pin in the saved Map's Build hints field through the proxy Worker, never moving a Map pin backwards. `qa publish` (added in 1.33.0) posts an already-stored verdict to the QA portal without a re-run or an order, refusing a stale `spec_hash` or a verdict its Run Record already records as published (#328). Within Polish, only the broader Source Freshness waiver remains on its existing report lane; theme and QA decisions also retain their existing lanes. | Any change to this list — adding, renaming, or removing a command — bumps `surface_version` in the same PR, and since 1.25.0 `check-supported-surface.mjs --base` enforces that (before, only hashed and named entries owed a bump, so `checkpoint` landed unbumped). Subcommands, registered gates, and flags may grow freely beneath a listed command. Removing a listed command from dispatch fails the gate outright. Do not infer support for an unregistered checkpoint from the top-level command. |
17
+ | CLI commands: `start`, `prepare-build`, `build`, `polish`, `checkpoint`, `page-kit`, `spec`, `doctor`, `bundle`, `next`, `theme`, `tooling`, `install-skills`, `install-agent-context`, `validate-assembly-report`, `telemetry`, `standardize`, `qa`, `findings`, `run-record`, `run`, `sdk`, `demo` | Scriptable entry points. The founding list (1.0.0) was the argv surface Campaigns Agent's remit fixture pins; 1.25.0 adds the partner entry path the public guides instruct — `install-skills` (skill install), `tooling status` (preflight), `next --packet` (the runtime cursor) — plus `theme`, `install-agent-context`, `validate-assembly-report`, and `telemetry`, since consent is part of the partner contract. `validate-build-packet`, formerly an undocumented and unsupported alias of `doctor`, was removed in 1.25.0+agent.7 (RL-0036) and now gets the unknown-command error; use `doctor`. `standardization-report`, a supported but redundant second spelling of `standardize` — same flags, same output, same exit codes — was removed in 1.27.0 and now gets the same unknown-command error; use `standardize`. Removing a supported command is a breaking change and is why that release moved the minor. `bundle check` validates the canonical JSON readback set and makes QA required only under `--require-qa`. `polish capture` owns page-load evidence production. `checkpoint waive` currently accepts four registered gates: `page_kit.store_profile`, `page_kit.sdk_version`, `polish.hidden_eager_media`, and `built_output.upsell_selector_scope`. `page-kit sync` (added in 1.29.0) writes the CampaignSpec's Store Profile fields and SDK pin into the target's `_data/campaigns.json` entry — the repair the first two gates name — and is the only `page-kit` subcommand. `spec derive` (added in 1.31.0) is the reverse write for the repo-derived field class (#432): the target's SDK pin, page routes and analytics ids into the packet's local CampaignSpec; it is the only `spec` subcommand, and the `page_kit.sdk_version.repo_newer` advisory names it; its `--write-map` flag (1.33.0+agent.2) also records the derived pin in the saved Map's Build hints field through the proxy Worker, never moving a Map pin backwards. `qa publish` (added in 1.33.0) posts an already-stored verdict to the QA portal without a re-run or an order, refusing a stale `spec_hash` or a verdict its Run Record already records as published (#328). Within Polish, only the broader Source Freshness waiver remains on its existing report lane; theme and QA decisions also retain their existing lanes. | Any change to this list — adding, renaming, or removing a command — bumps `surface_version` in the same PR, and since 1.25.0 `check-supported-surface.mjs --base` enforces that (before, only hashed and named entries owed a bump, so `checkpoint` landed unbumped). Subcommands, registered gates, and flags may grow freely beneath a listed command. Removing a listed command from dispatch fails the gate outright. Do not infer support for an unregistered checkpoint from the top-level command. |
18
18
  | `sdk storage-check` and `docs/sdk-storage-compatibility.md` | Read-only AST compatibility report for explicitly scoped tracked campaign HTML/JS before an SDK bump; consumes the supplied SDK-owned manifest and records its SHA-256 and verified or unverified local Git provenance. Incompatible and unknown findings exit 2; a clean scan is static source evidence only. | Additive supported CLI and named documentation; no automatic merchant integration repair. |
19
19
  | `bin/campaigns-os.mjs` (`campaigns-os`) | The CLI entry itself. | Declared in `package.json` `bin`; the gate fails if it disappears. |
20
20
  | Package export `./campaign-spec` | The versioned campaign-spec rule registry, consumed as `@nextcommerce/campaigns-os` (pinned by consumers' lockfiles; lockstep policy — ADR-003 in the ops repo). | Behavior-guarded from the consumer side by their contract tests; the export path itself is gated here. |
@@ -82,3 +82,15 @@ the package a consumer installs."
82
82
  the PR body — downstream pins (Campaigns Agent context spine, ops-repo
83
83
  `public-contracts.manifest.json`) update on their own cadence against a
84
84
  version they can see move.
85
+
86
+ Candidate 1.36.0 adds the portable `./progress` export, its strict v0 JSON schema,
87
+ [progress observation reference](progress-snapshots.md), and supported example
88
+ fixture. Observations preserve canonical continuation and separate Map/spec/build
89
+ identities; consumers must not treat history presence or scope-key matching as
90
+ readiness or trust.
91
+
92
+ Candidate 1.37.0 adds the `demo` CLI command, [offline sample reference](demo-preview.md),
93
+ a hashed `demo/apollo-v0/provenance.json` and named attribution notice. The command
94
+ exclusively creates a new target with validated inert pages. Its internal static
95
+ files are covered by the provenance output hashes; they are not independent
96
+ consumer interfaces. No campaign proof or session authority is granted.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextcommerce/campaigns-os",
3
- "version": "1.34.1",
3
+ "version": "1.37.1",
4
4
  "description": "Toolkit for agent-assisted NEXT campaign builds.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -47,7 +47,12 @@
47
47
  "./schemas/campaigns-os-legacy-migration-inventory.v0.schema.json": "./schemas/campaigns-os-legacy-migration-inventory.v0.schema.json",
48
48
  "./schemas/campaigns-os-legacy-provisioning-plan.v0.schema.json": "./schemas/campaigns-os-legacy-provisioning-plan.v0.schema.json",
49
49
  "./schemas/campaigns-os-legacy-provisioning-receipt.v0.schema.json": "./schemas/campaigns-os-legacy-provisioning-receipt.v0.schema.json",
50
- "./package.json": "./package.json"
50
+ "./package.json": "./package.json",
51
+ "./progress": {
52
+ "import": "./src/progress.mjs",
53
+ "default": "./src/progress.mjs"
54
+ },
55
+ "./schemas/campaigns-os-progress-snapshot.v0.schema.json": "./schemas/campaigns-os-progress-snapshot.v0.schema.json"
51
56
  },
52
57
  "scripts": {
53
58
  "campaigns-os": "node ./bin/campaigns-os.mjs",
@@ -134,6 +139,11 @@
134
139
  "compatibility.json",
135
140
  "AGENTS.md",
136
141
  "CHANGELOG.md",
137
- "docs/sdk-storage-compatibility.md"
142
+ "docs/sdk-storage-compatibility.md",
143
+ "docs/activation-and-evidence.md",
144
+ "docs/diagnostics.md",
145
+ "docs/progress-snapshots.md",
146
+ "demo",
147
+ "docs/demo-preview.md"
138
148
  ]
139
149
  }
@@ -24,6 +24,48 @@
24
24
  },
25
25
  "description": "Context-relative reference to the normalized Design Source Package. sha256 hashes the exact artifact bytes; material_fingerprint drives freshness gates."
26
26
  },
27
+ "intake": {
28
+ "type": "object",
29
+ "additionalProperties": true,
30
+ "properties": {
31
+ "saved_map_revision": {
32
+ "anyOf": [
33
+ {
34
+ "type": "null"
35
+ },
36
+ {
37
+ "type": "object",
38
+ "additionalProperties": false,
39
+ "required": [
40
+ "map_id",
41
+ "hash",
42
+ "algorithm",
43
+ "local_spec_material_hash"
44
+ ],
45
+ "properties": {
46
+ "map_id": {
47
+ "type": "string",
48
+ "minLength": 1
49
+ },
50
+ "hash": {
51
+ "type": [
52
+ "string",
53
+ "null"
54
+ ]
55
+ },
56
+ "algorithm": {
57
+ "const": "map-store-v1"
58
+ },
59
+ "local_spec_material_hash": {
60
+ "type": "string",
61
+ "pattern": "^sha256:[0-9a-f]{64}$"
62
+ }
63
+ }
64
+ }
65
+ ]
66
+ }
67
+ }
68
+ },
27
69
  "spec": {
28
70
  "type": "object",
29
71
  "required": ["path", "hash", "active_pages"],
@@ -0,0 +1,370 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://nextcommerce.com/schemas/campaigns-os-progress-snapshot.v0.schema.json",
4
+ "title": "Campaigns OS minimal progress observation v0",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": [
8
+ "schema_version",
9
+ "snapshot_id",
10
+ "stream_id",
11
+ "sequence",
12
+ "previous_snapshot_id",
13
+ "observed_at",
14
+ "package_version",
15
+ "producer",
16
+ "identity",
17
+ "stages",
18
+ "preview",
19
+ "continuation",
20
+ "qa"
21
+ ],
22
+ "properties": {
23
+ "schema_version": {
24
+ "const": "campaigns-os-progress-snapshot/v0"
25
+ },
26
+ "snapshot_id": {
27
+ "type": "string",
28
+ "pattern": "^sha256:[0-9a-f]{64}$"
29
+ },
30
+ "stream_id": {
31
+ "type": "string",
32
+ "pattern": "^progress_[0-9a-f]{32}$"
33
+ },
34
+ "sequence": {
35
+ "type": "integer",
36
+ "minimum": 1,
37
+ "maximum": 2147483647
38
+ },
39
+ "previous_snapshot_id": {
40
+ "type": [
41
+ "string",
42
+ "null"
43
+ ],
44
+ "pattern": "^sha256:[0-9a-f]{64}$"
45
+ },
46
+ "observed_at": {
47
+ "type": "string",
48
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$"
49
+ },
50
+ "package_version": {
51
+ "type": "string",
52
+ "pattern": "^\\d{1,6}\\.\\d{1,6}\\.\\d{1,6}$"
53
+ },
54
+ "producer": {
55
+ "enum": [
56
+ "next",
57
+ "qa"
58
+ ]
59
+ },
60
+ "identity": {
61
+ "type": "object",
62
+ "additionalProperties": false,
63
+ "required": [
64
+ "map_id",
65
+ "map_revision_hash",
66
+ "map_revision_algorithm",
67
+ "saved_revision_alignment",
68
+ "local_spec_material_hash",
69
+ "local_spec_material_algorithm",
70
+ "build_fingerprint",
71
+ "build_fingerprint_algorithm"
72
+ ],
73
+ "properties": {
74
+ "map_id": {
75
+ "type": [
76
+ "string",
77
+ "null"
78
+ ],
79
+ "pattern": "^[A-Za-z0-9_-]{1,64}$"
80
+ },
81
+ "map_revision_hash": {
82
+ "type": [
83
+ "string",
84
+ "null"
85
+ ],
86
+ "pattern": "^sha256:[0-9a-f]{64}$"
87
+ },
88
+ "map_revision_algorithm": {
89
+ "const": "map-store-v1"
90
+ },
91
+ "saved_revision_alignment": {
92
+ "enum": [
93
+ "aligned",
94
+ "unconfirmed"
95
+ ]
96
+ },
97
+ "local_spec_material_hash": {
98
+ "type": [
99
+ "string",
100
+ "null"
101
+ ],
102
+ "pattern": "^sha256:[0-9a-f]{64}$"
103
+ },
104
+ "local_spec_material_algorithm": {
105
+ "const": "campaign-spec-material-v1"
106
+ },
107
+ "build_fingerprint": {
108
+ "type": [
109
+ "string",
110
+ "null"
111
+ ],
112
+ "pattern": "^sha256:[0-9a-f]{64}$"
113
+ },
114
+ "build_fingerprint_algorithm": {
115
+ "const": "sha256-manifest/v1"
116
+ }
117
+ }
118
+ },
119
+ "stages": {
120
+ "type": "array",
121
+ "minItems": 6,
122
+ "maxItems": 6,
123
+ "items": {
124
+ "type": "object",
125
+ "additionalProperties": false,
126
+ "required": [
127
+ "stage",
128
+ "status",
129
+ "build_binding",
130
+ "source_build_fingerprint"
131
+ ],
132
+ "properties": {
133
+ "stage": {
134
+ "enum": [
135
+ "prepare_build",
136
+ "setup",
137
+ "assembly",
138
+ "polish",
139
+ "deploy",
140
+ "qa"
141
+ ]
142
+ },
143
+ "status": {
144
+ "enum": [
145
+ "pending",
146
+ "required",
147
+ "blocked",
148
+ "completed",
149
+ "completed_with_warnings",
150
+ "skipped",
151
+ "unknown"
152
+ ]
153
+ },
154
+ "build_binding": {
155
+ "enum": [
156
+ "matching",
157
+ "unconfirmed"
158
+ ]
159
+ },
160
+ "source_build_fingerprint": {
161
+ "type": [
162
+ "string",
163
+ "null"
164
+ ],
165
+ "pattern": "^sha256:[0-9a-f]{64}$"
166
+ }
167
+ }
168
+ }
169
+ },
170
+ "preview": {
171
+ "type": "object",
172
+ "additionalProperties": false,
173
+ "required": [
174
+ "present",
175
+ "url_hash"
176
+ ],
177
+ "properties": {
178
+ "present": {
179
+ "type": "boolean"
180
+ },
181
+ "url_hash": {
182
+ "type": [
183
+ "string",
184
+ "null"
185
+ ],
186
+ "pattern": "^sha256:[0-9a-f]{64}$"
187
+ }
188
+ }
189
+ },
190
+ "continuation": {
191
+ "type": "object",
192
+ "additionalProperties": false,
193
+ "required": [
194
+ "stage",
195
+ "blocked",
196
+ "divergent",
197
+ "action_ids",
198
+ "gates"
199
+ ],
200
+ "properties": {
201
+ "stage": {
202
+ "enum": [
203
+ "prepare-build",
204
+ "doctor-blocked",
205
+ "setup",
206
+ "build",
207
+ "polish",
208
+ "deploy",
209
+ "qa",
210
+ "done",
211
+ "unknown"
212
+ ]
213
+ },
214
+ "blocked": {
215
+ "type": "boolean"
216
+ },
217
+ "divergent": {
218
+ "type": "boolean"
219
+ },
220
+ "action_ids": {
221
+ "type": "array",
222
+ "maxItems": 64,
223
+ "uniqueItems": true,
224
+ "items": {
225
+ "enum": [
226
+ "doctor_recheck",
227
+ "restore_prepare_build_binding",
228
+ "recheck",
229
+ "rerun_prepare_build",
230
+ "divergence_inspect",
231
+ "setup_skill",
232
+ "build_skill",
233
+ "build_local_proof",
234
+ "build_production_parity",
235
+ "polish_skill",
236
+ "deploy",
237
+ "advance",
238
+ "install_browser",
239
+ "qa_run",
240
+ "run_end",
241
+ "run_record_present",
242
+ "run_record_remit_recovery",
243
+ "run_record_closeout",
244
+ "purchase_proof_unknown",
245
+ "theme_gate.starter_palette_blocks_qa",
246
+ "theme_gate.brand_contract_unreadable",
247
+ "theme_gate.theme_generate",
248
+ "theme_gate.apply_brand_layer",
249
+ "theme_gate.waive_theme",
250
+ "theme_gate.fix_load_order",
251
+ "polish_gate.rerun_build",
252
+ "polish_gate.run_polish",
253
+ "polish_gate.repair_waiver",
254
+ "checkpoint.page_kit.sdk_version.repair_spec",
255
+ "checkpoint.page_kit.sdk_version.refresh_spec",
256
+ "checkpoint.page_kit.store_profile.repair_spec",
257
+ "checkpoint.built_output.upsell_selector_scope.repair_selectors",
258
+ "checkpoint.page_kit.sdk_version.repair_target",
259
+ "checkpoint.page_kit.sdk_version.align_store_profile",
260
+ "checkpoint.page_kit.sdk_version.align_sdk_version",
261
+ "checkpoint.page_kit.sdk_version.repair_waiver",
262
+ "checkpoint.page_kit.sdk_version.waive",
263
+ "checkpoint.page_kit.store_profile.repair_target",
264
+ "checkpoint.page_kit.store_profile.align_store_profile",
265
+ "checkpoint.page_kit.store_profile.align_sdk_version",
266
+ "checkpoint.page_kit.store_profile.repair_waiver",
267
+ "checkpoint.page_kit.store_profile.waive",
268
+ "checkpoint.built_output.upsell_selector_scope.repair_target",
269
+ "checkpoint.built_output.upsell_selector_scope.align_store_profile",
270
+ "checkpoint.built_output.upsell_selector_scope.align_sdk_version",
271
+ "checkpoint.built_output.upsell_selector_scope.repair_waiver",
272
+ "checkpoint.built_output.upsell_selector_scope.waive",
273
+ "checkpoint.polish.hidden_eager_media.capture",
274
+ "checkpoint.polish.hidden_eager_media.install_browser",
275
+ "checkpoint.polish.hidden_eager_media.repair",
276
+ "checkpoint.polish.hidden_eager_media.repair_authority",
277
+ "checkpoint.polish.hidden_eager_media.local_proof_rebuild",
278
+ "checkpoint.polish.hidden_eager_media.waive",
279
+ "unknown"
280
+ ]
281
+ }
282
+ },
283
+ "gates": {
284
+ "type": "array",
285
+ "maxItems": 16,
286
+ "items": {
287
+ "type": "object",
288
+ "additionalProperties": false,
289
+ "required": [
290
+ "id",
291
+ "state"
292
+ ],
293
+ "properties": {
294
+ "id": {
295
+ "enum": [
296
+ "doctor",
297
+ "prepare_build",
298
+ "theme_gate",
299
+ "polish_gate",
300
+ "page_kit.sdk_version",
301
+ "page_kit.store_profile",
302
+ "built_output.upsell_selector_scope",
303
+ "polish.hidden_eager_media",
304
+ "unknown"
305
+ ]
306
+ },
307
+ "state": {
308
+ "enum": [
309
+ "pass",
310
+ "blocked",
311
+ "waived",
312
+ "not_applicable",
313
+ "unknown"
314
+ ]
315
+ }
316
+ }
317
+ }
318
+ }
319
+ }
320
+ },
321
+ "qa": {
322
+ "anyOf": [
323
+ {
324
+ "type": "null"
325
+ },
326
+ {
327
+ "type": "object",
328
+ "additionalProperties": false,
329
+ "required": [
330
+ "verdict_id",
331
+ "disposition",
332
+ "binding",
333
+ "publish_state"
334
+ ],
335
+ "properties": {
336
+ "verdict_id": {
337
+ "type": [
338
+ "string",
339
+ "null"
340
+ ],
341
+ "pattern": "^[A-Za-z0-9_-]{1,64}$"
342
+ },
343
+ "disposition": {
344
+ "enum": [
345
+ "ready",
346
+ "ready_with_exceptions",
347
+ "blocked",
348
+ "unknown"
349
+ ]
350
+ },
351
+ "binding": {
352
+ "enum": [
353
+ "matching",
354
+ "unconfirmed"
355
+ ]
356
+ },
357
+ "publish_state": {
358
+ "enum": [
359
+ "skipped",
360
+ "ok",
361
+ "failed",
362
+ "unknown"
363
+ ]
364
+ }
365
+ }
366
+ }
367
+ ]
368
+ }
369
+ }
370
+ }
@@ -1,11 +1,27 @@
1
1
  ---
2
2
  name: next-campaigns-build
3
- version: 1.0.2
3
+ version: 1.0.3
4
4
  description: Assemble a NEXT campaign from a doctor-cleared Build Packet, CampaignSpec/API values, prepared HTML/assets, page-kit, and starter-template contracts.
5
5
  ---
6
6
 
7
7
  # Next Campaigns Build
8
8
 
9
+ ## Installed toolkit commands
10
+
11
+ Run from the campaign folder with an exact project-local devDependency and
12
+ committed lockfile. Orient on reviewed source before installation; check release
13
+ provenance or pin the full reviewed Git SHA. Preflight with `npx campaigns-os
14
+ tooling status --platform <claude|codex>` and refresh bundled skills for the same
15
+ profile. Use the invocation printed by status and `next` to avoid PATH shadowing.
16
+
17
+ In the instructions below, bare `campaigns-os …` means `npx campaigns-os …`
18
+ from that campaign folder. Global-only users substitute the global copy's printed invocation for
19
+ each `npx campaigns-os` example; toolkit contributors translate to `npm run campaigns-os -- …` in
20
+ the toolkit checkout. Browser installation is `npx campaigns-os qa
21
+ install-browser`, not a campaign npm script. `tooling diagnose --packet <p>
22
+ --json` provides a redacted support export without changing retained evidence.
23
+
24
+
9
25
  ## Recommended Build Loop
10
26
 
11
27
  For campaign builds, follow **build → independent review → repair → verification**.