@nextcommerce/campaigns-os 1.37.3 → 1.43.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 (76) hide show
  1. package/AGENTS.md +114 -10
  2. package/CHANGELOG.md +708 -0
  3. package/README.md +44 -31
  4. package/agents/claude/CLAUDE.md +5 -1
  5. package/campaign-spec/dist/types.d.ts +2 -0
  6. package/contracts/agent-relevant-change-policy.v1.json +11 -1
  7. package/contracts/effects.v1.json +4887 -0
  8. package/contracts/migration-sidecar-bundle.v0.json +9 -0
  9. package/contracts/release-ledger.json +1541 -0
  10. package/contracts/supported-surface.json +33 -12
  11. package/docs/build-packet.md +83 -22
  12. package/docs/campaigns-os-build-flow.md +2 -2
  13. package/docs/demo-preview.md +1 -1
  14. package/docs/diagnostics.md +7 -4
  15. package/docs/effects.md +350 -0
  16. package/docs/gateway-login.md +113 -0
  17. package/docs/local-setup.md +51 -0
  18. package/docs/migration-sidecar-bundle.md +6 -1
  19. package/docs/orientation-contract-reference.md +4 -1
  20. package/docs/progress-snapshots.md +9 -3
  21. package/docs/qa-and-test-orders.md +29 -13
  22. package/docs/readback.md +523 -0
  23. package/docs/runtime-readiness.md +1 -1
  24. package/docs/sdk-storage-compatibility.md +1 -1
  25. package/docs/skills-revision.md +364 -0
  26. package/docs/supported-surface.md +11 -3
  27. package/docs/versioning.md +8 -4
  28. package/package.json +10 -4
  29. package/schemas/campaign-runtime-assembly-report.v0.schema.json +6 -1
  30. package/schemas/campaign-runtime-build-packet.v0.schema.json +11 -1
  31. package/schemas/campaign-spec.v4.schema.json +4 -0
  32. package/schemas/campaigns-os-effects.v1.schema.json +211 -0
  33. package/schemas/campaigns-os-progress-snapshot.v0.schema.json +1 -0
  34. package/schemas/campaigns-os-qa-verdict-sidecar.v0.schema.json +1 -0
  35. package/schemas/campaigns-os-qa-verdict.v0.schema.json +1 -0
  36. package/schemas/campaigns-os-readback.v2.schema.json +267 -0
  37. package/schemas/campaigns-os-run-record.v0.schema.json +1 -0
  38. package/skills/campaign-lifecycle-orientation/SKILL.md +179 -0
  39. package/skills/campaign-readback-classification/SKILL.md +230 -0
  40. package/skills/campaign-run-evidence/SKILL.md +142 -0
  41. package/skills/contribution-intake/SKILL.md +85 -0
  42. package/skills/next-campaigns-build/SKILL.md +33 -12
  43. package/skills/next-campaigns-os/SKILL.md +59 -22
  44. package/skills/next-campaigns-os/references/session-intake.md +4 -4
  45. package/skills/next-campaigns-os-setup/SKILL.md +35 -14
  46. package/skills/next-campaigns-polish/SKILL.md +43 -17
  47. package/skills/next-campaigns-qa/SKILL.md +53 -28
  48. package/skills.json +40 -7
  49. package/src/admin-transport.mjs +123 -0
  50. package/src/cli.mjs +1178 -270
  51. package/src/credential-store.mjs +183 -0
  52. package/src/deviation.mjs +3 -2
  53. package/src/diagnostic.mjs +4 -1
  54. package/src/finding-cause.mjs +14 -10
  55. package/src/gate-actions.mjs +2 -2
  56. package/src/install-mode.mjs +17 -9
  57. package/src/lifecycle.mjs +96 -0
  58. package/src/login.mjs +152 -0
  59. package/src/package-install-fixture.mjs +3 -2
  60. package/src/polish-node.mjs +5 -2
  61. package/src/progress-node.mjs +3 -2
  62. package/src/progress.mjs +5 -3
  63. package/src/qa-node.mjs +105 -36
  64. package/src/qa-publish.mjs +112 -2
  65. package/src/qa-sidecar.mjs +2 -0
  66. package/src/qa-verdict-discovery.mjs +11 -0
  67. package/src/qa-verdict-publish.mjs +1 -0
  68. package/src/qa-verdict.mjs +8 -1
  69. package/src/readback.mjs +1937 -0
  70. package/src/remit.mjs +17 -3
  71. package/src/run-record-closeout.mjs +3 -4
  72. package/src/run-record.mjs +4 -0
  73. package/src/sidecar-bundle.mjs +21 -0
  74. package/src/spec-source-identity.mjs +44 -0
  75. package/src/stage-ledger.mjs +4 -1
  76. package/src/tooling-setup.mjs +160 -0
@@ -1,6 +1,6 @@
1
1
  {
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 \u2014 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 \u2014 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) \u2014 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.37.3",
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.43.1",
4
4
  "package_exports": [
5
5
  "./commercial-journey",
6
6
  "./commercial-parity",
@@ -40,11 +40,14 @@
40
40
  "findings",
41
41
  "run-record",
42
42
  "run",
43
- "demo"
43
+ "demo",
44
+ "login",
45
+ "logout",
46
+ "readback"
44
47
  ],
45
48
  "hashed": {
46
49
  "contracts/migration-sidecar-bundle.v0.json": {
47
- "sha256": "f5097f6cccaf211d442c1ebc584d2c76d5a07a44e587df130de02117a9412db0"
50
+ "sha256": "53269453dfdaac4b286124d445b60b0c46205dfbaf8037ac61b30254a32df53a"
48
51
  },
49
52
  "contracts/runtime-recipe.campaigns-os-node-v1.json": {
50
53
  "sha256": "90aaaaade90cf2525ea1aa05be5cb2d02b57e6e59f9278a946efa8a087946fd3"
@@ -56,16 +59,16 @@
56
59
  "sha256": "65bcd8b5f41f1e9ecfc36f3b8838cd4ed531bd74c5a318ee5147131f6c9b4a1c"
57
60
  },
58
61
  "schemas/campaign-runtime-assembly-report.v0.schema.json": {
59
- "sha256": "3fa085f2ad368567983cdc9c01e7c712682d02df9c28e69a2b7befb45d444468"
62
+ "sha256": "8a0d37be9a4bb34d0ed073c9d6bfa4406a7b499c801c34c5fbb26646e2665c0b"
60
63
  },
61
64
  "schemas/campaign-runtime-build-context.v0.schema.json": {
62
65
  "sha256": "f310c1b7844d9b1994864d15858ff0c6f17efc1e5285ba193d181bdb2dd4be2f"
63
66
  },
64
67
  "schemas/campaign-runtime-build-packet.v0.schema.json": {
65
- "sha256": "91853bbd1b14c080e2fe2ec32f1aa643f53e62df280b543093bf158ae924dd4b"
68
+ "sha256": "47c2899f409ed5927cf410bddd63e7bb8a9d154eabf7a07455777aed118212e9"
66
69
  },
67
70
  "schemas/campaign-spec.v4.schema.json": {
68
- "sha256": "12b57573739357acb2b007d00a737cd86face441c47f2719fc51b041dc8ea4a5"
71
+ "sha256": "af56c3de638d3c4e1fd5df8c2d733754d9ad16caa23b5bec92ce3a6f71bd0271"
69
72
  },
70
73
  "schemas/campaigns-os-legacy-migration-inventory.v0.schema.json": {
71
74
  "sha256": "d6edc4572900d15fdaf6b8c59916b0d885303c1d398bdadeb7c58285522c9049"
@@ -77,10 +80,10 @@
77
80
  "sha256": "1405c32bb9698030e9a40d754191e413cdd505dde91ac7de2e41c8887700f8f2"
78
81
  },
79
82
  "schemas/campaigns-os-qa-verdict-sidecar.v0.schema.json": {
80
- "sha256": "1bc53b9a75a6c19c89aee6e9664574980b09d2e13eb8826b157f5ab6ba82d0b0"
83
+ "sha256": "3c40fd79f218d1b95f0424f9a2b67db140a306329e2ca02793e2740d3afded59"
81
84
  },
82
85
  "schemas/campaigns-os-qa-verdict.v0.schema.json": {
83
- "sha256": "f7ce00e4f814d0ab7659b11fb2a14d3e4fafbf7c8e353449f25d7e87e1627acc"
86
+ "sha256": "ec4514e81a791a63bc0b358d7977aa823f3c5524e0f5caaba2712e66f262e18a"
84
87
  },
85
88
  "schemas/campaigns-os-doctor-output.v0.schema.json": {
86
89
  "sha256": "87866e619d2a18f01a208a1682cb14a2079f61df51c642f4e1902b6e6bce0ce5"
@@ -92,7 +95,7 @@
92
95
  "sha256": "08ca132134b9e4610370e88082a5e888d09ddec0d5ee4512d84cc57181da722e"
93
96
  },
94
97
  "schemas/campaigns-os-run-record.v0.schema.json": {
95
- "sha256": "2a073874ab6081dd6db48e90f1a9b2c3c7c3ae4af70779c604701d70bb12b46d"
98
+ "sha256": "00dc9bcec79c12ea22a27f636188bcc33c6811df2d646ac7b49d4cc076e97355"
96
99
  },
97
100
  "schemas/campaigns-os-runtime-recipe.v1.schema.json": {
98
101
  "sha256": "f8a2ab5eadbb71fb6d5653b670ee71e4471c3df74dd04000d3dbd3d9ae9e71fc"
@@ -107,10 +110,19 @@
107
110
  "sha256": "841c1f884260ce3eb3ddb518960a127bc915992a9539c818e5986ce156acff1f"
108
111
  },
109
112
  "schemas/campaigns-os-progress-snapshot.v0.schema.json": {
110
- "sha256": "c572756be7df03351843ffc361fc657e3fd819702b4e6f0a78a3c8efd0b0f046"
113
+ "sha256": "ef31b4f20e39dfc1614dd4b45e4cf1692a51760b008cb51d133659307bd2a954"
111
114
  },
112
115
  "demo/apollo-v0/provenance.json": {
113
116
  "sha256": "2e440be6513fe06b351c3a72c35424a04f807792621cb01e89803441fd925e06"
117
+ },
118
+ "schemas/campaigns-os-readback.v2.schema.json": {
119
+ "sha256": "dfc9abed38d456969e47a21f606d308a03bdf036f3466f7d6e47a602747dacf4"
120
+ },
121
+ "contracts/effects.v1.json": {
122
+ "sha256": "121779835c14d8d48390c57268b50a60fe808f5d9ba91ea2dde5df22a64f8aaf"
123
+ },
124
+ "schemas/campaigns-os-effects.v1.schema.json": {
125
+ "sha256": "3eadd22169ab98bc7c2f682af2751267605170581182158d96be035b0cfe44dc"
114
126
  }
115
127
  },
116
128
  "named": [
@@ -123,6 +135,7 @@
123
135
  "docs/supported-surface.md",
124
136
  "docs/campaigns-os-build-flow.md",
125
137
  "docs/build-packet.md",
138
+ "docs/gateway-login.md",
126
139
  "docs/migration-sidecar-bundle.md",
127
140
  "docs/design-source-package.md",
128
141
  "docs/campaign-build-brief.md",
@@ -192,6 +205,14 @@
192
205
  "docs/progress-snapshots.md",
193
206
  "contracts/fixtures/progress/observation.v0.json",
194
207
  "docs/demo-preview.md",
195
- "demo/apollo-v0/NOTICE.txt"
208
+ "demo/apollo-v0/NOTICE.txt",
209
+ "docs/readback.md",
210
+ "docs/effects.md",
211
+ "agents/claude/CLAUDE.md",
212
+ "agents/codex/AGENTS.md",
213
+ "agents/copilot/copilot-instructions.md",
214
+ "agents/cursor/campaigns-os.mdc",
215
+ "docs/skills-revision.md",
216
+ "docs/local-setup.md"
196
217
  ]
197
218
  }
@@ -4,7 +4,7 @@ The Build Packet is the campaign assembly handoff. It wraps, but does not replac
4
4
 
5
5
  It answers:
6
6
 
7
- - Which CampaignSpec and Map ID are we building?
7
+ - Which CampaignSpec and saved Map ID or local-spec ID are we building?
8
8
  - Which public route slug and campaign directory are expected?
9
9
  - Where are the prepared HTML/assets?
10
10
  - Which Campaign Build Brief is the merchandising/design presentation truth?
@@ -15,6 +15,56 @@ It answers:
15
15
 
16
16
  The current schema is `schemas/campaign-runtime-build-packet.v0.schema.json`.
17
17
 
18
+ ## Local-spec entry
19
+
20
+ A saved Map is optional for a prepared-HTML build. The coding agent authors an
21
+ ordinary CampaignSpec from the brief, source design and configured campaign's
22
+ real commerce values, following `schemas/campaign-spec.v4.schema.json`. The
23
+ operator supplies the selected store/campaign, public Campaigns API key, intended
24
+ pages and commercial choices, plus store contact details and policy URLs. Verify
25
+ the store/campaign binding and package/offer references; do not guess commerce
26
+ values. No gateway or Map provisioning is required for this entry.
27
+
28
+ Set `spec_identity.local_spec_id` to a new UUID once, commit it with the spec,
29
+ and keep it unchanged through revisions and fresh checkouts. It accepts 1–64
30
+ letters, digits, underscores or hyphens, with no surrounding whitespace. Local
31
+ IDs are checked exactly; the legacy normalization of saved Map IDs does not
32
+ apply. Malformed or conflicting local identities cannot be adopted into campaign
33
+ evidence; blocked diagnostic reports may still be written. Doctor reports local
34
+ identity failures as `spec.local_identity`, while
35
+ saved-Map failures retain `spec.map_id`. Set `spec_identity.public_route_slug`
36
+ to the intended route. Omit `map_id`, saved-Map URLs and saved-Map revision
37
+ metadata; a local ID is never a Map ID. A spec declaring both kinds is refused.
38
+ A separately authored campaign gets a new local ID even if its route matches.
39
+
40
+ ```sh
41
+ npx --no-install campaigns-os start --spec campaign-spec.json --source source-html --target . --template-family <certified-family> --deploy-target local-serve
42
+ npx --no-install campaigns-os next --packet campaign-runtime.build.json
43
+ ```
44
+
45
+ The packet and report retain `map_id: null` and carry `local_spec_id`. Doctor,
46
+ report writes, polish capture, progress, run closeout and QA compare that local
47
+ identity. Material spec hashes still bind the current revision; a changed ID or
48
+ content cannot reuse earlier proof. After a material revision, follow `next` to
49
+ refresh preparation and affected evidence. Keep the spec, source, dependency
50
+ pins and canonical sidecars in Git. Use `readback` and `next` after a fresh
51
+ checkout; identity survives the move, but proof freshness is assessed again.
52
+
53
+ Run QA through `--packet`. Local verdicts use the storage key
54
+ `local-spec-<local_spec_id>` and carry the explicit ID in the full verdict and
55
+ committed sidecar. A matching route alone cannot adopt a verdict. Local QA is
56
+ never posted to the Map portal: `qa run` suppresses publication even with
57
+ `--post-verdict`, while `qa publish` refuses with `local_spec`. Progress remains
58
+ local with `map_id_missing`. Run Telemetry retains
59
+ its existing consent controls. `spec derive --write-map` requires a real saved
60
+ Map. Moving to a saved Map requires fresh preparation and evidence; this entry
61
+ does not claim saved-Map revision alignment.
62
+
63
+ Existing saved-Map specs and packets continue to work. The identity change does
64
+ not relax template certification, source proof, store/SDK parity, polish,
65
+ commerce checks, or typed-card checkout proof. Resolve their reported gates;
66
+ localhost readiness is not production approval.
67
+
18
68
  ## Root-Served Campaigns (`campaign.route_root`)
19
69
 
20
70
  Most campaigns are served under a slug prefix (`/<public_route_slug>/...`), and
@@ -78,7 +128,7 @@ campaigns-os page-kit sync --packet campaign-runtime.build.json [--dry-run] [--j
78
128
  ```
79
129
 
80
130
  The CampaignSpec is the authority for the Store Profile: those values are
81
- authored in the Map, never in the repo, so `page-kit sync` writes the nine
131
+ authored in the saved Map or the repository-owned local spec, so `page-kit sync` writes the nine
82
132
  fields the spec carries (`campaign.store_*`) unconditionally. The SDK pin is
83
133
  different. On an existing campaign the repo pin moves first and the Map/spec
84
134
  is stale until someone re-saves it, so a spec → repo write would undo a bump
@@ -103,7 +153,7 @@ covers only the governed fields. `--dry-run` prints the same diff without
103
153
  writing. Exit 0 on success (including a no-op re-run); exit 2 with
104
154
  `page_kit.sync.*` error codes and nothing written when the packet cannot be
105
155
  read, the target entry or the spec is missing or not an object, the spec
106
- identifies another campaign (`spec_identity.public_route_slug` or `map_id`
156
+ identifies another campaign (`spec_identity.public_route_slug`, `map_id` or `local_spec_id`
107
157
  disagreeing with the packet: `page_kit.sync.spec_identity_mismatch`), or the
108
158
  resolved `_data/campaigns.json` lies outside the target repo through a symlink
109
159
  (`page_kit.sync.target_escapes_repo`).
@@ -444,17 +494,25 @@ network, which the default run never touches, so it is opt-in:
444
494
  campaigns-os spec derive --packet campaign-runtime.build.json --from-store <subdomain> [--store-token-source env:<VAR>] [--dry-run] [--json]
445
495
  ```
446
496
 
447
- `<subdomain>` is the store's `<store>.29next.store` subdomain (the Admin API
448
- lives at `https://<subdomain>.29next.store/api/admin/`). The read token is
449
- taken from the environment, never from the command line: from
450
- `<SUBDOMAIN>_ADMIN_TOKEN` (upper-cased, dashes as underscores) by default,
451
- or from the variable `--store-token-source env:<VAR>` names. An Admin API
452
- access token with the `store:read` and `content:read` scopes (Settings >
453
- API Access) is enough; the token is sent as a bearer and appears nowhere in
454
- the output, which names the variable instead (a value that is not one line
455
- of printable ASCII is refused unsent, `spec.derive.store_credential_invalid`,
456
- and a transport error that quotes a header is redacted). The store is only
457
- read.
497
+ `<subdomain>` is the store's `<store>.29next.store` subdomain. In the
498
+ 1.38.0 candidate, the default read uses gateway credentials saved by
499
+ `campaigns-os login --store <subdomain>`, through
500
+ `https://mcp.nextcommerce.com/admin/`. This is an admitted owned-store
501
+ private pilot, not general merchant availability. Missing, expired or uncertain
502
+ credentials require login; gateway failure never falls back to an environment
503
+ token. See [gateway login and migration](gateway-login.md).
504
+
505
+ **Migration for existing direct callers:** add
506
+ `--store-token-source env:<VAR>` explicitly, naming your existing environment
507
+ variable (for example `EXAMPLE_ADMIN_TOKEN`). The former implicit
508
+ `<SUBDOMAIN>_ADMIN_TOKEN` lookup is removed. This break-glass path warns that it
509
+ bypasses gateway custody and contacts
510
+ `https://<subdomain>.29next.store/api/admin/` directly. A `store:read` and
511
+ `content:read` Admin token is sufficient. Tokens are never CLI arguments or
512
+ output; invalid bearer values are refused unsent. Both paths only read the store.
513
+ Gateway page pagination is consolidated by custody into a bounded list; the CLI
514
+ does not follow an upstream cursor on this path. The explicit direct path keeps
515
+ its existing bounded cursor traversal.
458
516
 
459
517
  | Spec field | Store authority |
460
518
  |---|---|
@@ -489,14 +547,17 @@ return). A slug that is not one honest path segment (a separator, `.` or
489
547
  spec was stale and the diff is the correction, or `--from-store` names
490
548
  another merchant's store and the spec should be restored.
491
549
 
492
- The result carries a `store` block (`subdomain`, `admin_api`,
493
- `token_source`, `store_read`, `pages_read`, `primary_domain`), and the text
550
+ The result carries a `store` block (gateway reads add `transport: "gateway"`
551
+ and the actual gateway `endpoint`; `admin_api` remains the logical upstream
552
+ source), with `subdomain`, `admin_api`,
553
+ `token_source`, `store_read`, `pages_read`, `primary_domain`, and the text
494
554
  output a `Store:` line. After a write that moved a store field, `next` is
495
555
  `page-kit sync` first (doctor's `page_kit.store_profile` gate now sees the
496
556
  spec ahead of the repo and names sync as its repair), then doctor. A store
497
557
  that cannot be read is a refusal with nothing written, repo fields included,
498
- exit 2: `spec.derive.store_credential_missing` (the variable is unset or
499
- empty), `store_unauthorized` (401/403), `store_not_found` (404: no store at
558
+ exit 2: `spec.derive.store_credential_missing` (no gateway login, or the explicitly
559
+ selected variable is unset or empty), `store_credential_unavailable` (local
560
+ storage is busy or unavailable), `store_unauthorized` (401/403), `store_not_found` (404: no store at
500
561
  that subdomain), `store_unreachable` (transport, timeout, 5xx) or
501
562
  `store_response_invalid`. Local preconditions (packet, spec, target entry, spec boundary, page tree)
502
563
  are checked before the store is contacted, and a packet that names another
@@ -1103,12 +1164,12 @@ and report proof policy fields above.
1103
1164
 
1104
1165
  | Flag | Source | When to use |
1105
1166
  | --- | --- | --- |
1106
- | `--spec <path>` | Local JSON file | Offline work, CI runs against a fixture, or hand-edited spec drafts |
1107
- | `--map-id <id>` | Map Builder proxy (KV-backed) | Default agentic flow — KV is the source of truth, no file shuttling |
1167
+ | `--spec <path>` | Local JSON file | Agent-authored local specs, saved-Map exports, offline work or CI fixtures |
1168
+ | `--map-id <id>` | Map Builder proxy (KV-backed) | Saved-Map intake from the current KV revision |
1108
1169
 
1109
1170
  When `--map-id <id>` is set, the CLI fetches `GET <proxy>/api/spec/<id>` (default `<proxy>` is `https://campaign-map.nextcommerce.com`) and caches the response to `<target>/.campaign-runtime/fetched-specs/<id>.json`. The cached file is what downstream stages read, so the packet's `spec.local_path` always resolves to an on-disk artifact regardless of intake mode.
1110
1171
 
1111
- Retrieval behavior:
1172
+ Saved-Map retrieval behavior (`--map-id`):
1112
1173
 
1113
1174
  - **Re-fetch by default.** Every `start` / `prepare-build` invocation re-fetches from KV. KV is the source of truth; the cache file is a debug/inspection artifact, not a performance optimization.
1114
1175
  - **`--cached-spec`** reuses the cache without a network call. Use for offline iteration or when the proxy is temporarily unreachable.
@@ -1290,7 +1351,7 @@ doctor read for the locked template family (`required`, `family`, `version`,
1290
1351
  running). This is what `prepare-build` records by default. The catalog
1291
1352
  travels with the toolkit, not with the campaign, so the packet does not
1292
1353
  record where one machine's checkout or package install kept it, and the
1293
- same packet resolves on any machine and under `npx campaigns-os`.
1354
+ same packet resolves on any machine and under `npx --no-install campaigns-os`.
1294
1355
  - A string `path` is an operator-supplied `--commerce-catalog <path>`,
1295
1356
  recorded relative to the packet (keep it inside the campaign repo). Doctor
1296
1357
  resolves it against the packet's directory and blocks on
@@ -2,7 +2,7 @@
2
2
 
3
3
  The happy path is intentionally tight:
4
4
 
5
- 1. Export a saved local CampaignSpec JSON from Campaign Map Builder, including Map ID and public route slug.
5
+ 1. Use a saved Map export, or have the coding agent author a CampaignSpec from the brief and verified campaign values through the [local-spec entry](build-packet.md#local-spec-entry). Preserve its Map ID or stable `local_spec_id`, plus its public route slug.
6
6
  2. Run `campaigns-os start` with the CampaignSpec, prepared source files, target page-kit repo, and template family.
7
7
  3. Treat doctor as the first gate. If its `next` block says `doctor-blocked` or `prepare-build` (the same stage names `campaigns-os next` uses), stop and resolve the named blocker.
8
8
  4. Run setup when doctor asks for setup; otherwise continue to assembly.
@@ -11,7 +11,7 @@ The happy path is intentionally tight:
11
11
  7. Install the package-owned Playwright browser with `npm run qa:install-browser`.
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
- 10. Run `campaigns-os qa resolve`, then `campaigns-os qa run --browser --test-order common` with the tested URL. QA runs publish to the QA portal by default (the QA tab records browser QA plus typed-card proof and the run prints its portal link); pass `--no-post-verdict` only for offline / dev / CI runs.
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
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.
16
16
  12. Promote, block, or iterate from the recorded build, polish, deploy, QA, and test-order evidence.
17
17
 
@@ -6,7 +6,7 @@ release at least 1.37.0 (or a reviewed full-SHA source pin).
6
6
  From the folder containing your exact project-local toolkit installation:
7
7
 
8
8
  ```bash
9
- npx campaigns-os demo --target ./apollo-sample
9
+ npx --no-install campaigns-os demo --target ./apollo-sample
10
10
  ```
11
11
 
12
12
  Open the printed `landing/index.html` file directly. No server or browser
@@ -6,12 +6,15 @@ npm, install a reviewed full-SHA source pin as described in the quickstart.
6
6
  From the campaign folder:
7
7
 
8
8
  ```bash
9
- npx campaigns-os tooling diagnose --platform codex --packet campaign-runtime.build.json
10
- npx campaigns-os tooling diagnose --platform codex --packet campaign-runtime.build.json --json > diagnostic.json
9
+ npx --no-install campaigns-os tooling diagnose --platform codex --packet campaign-runtime.build.json
10
+ npx --no-install campaigns-os tooling diagnose --platform codex --packet campaign-runtime.build.json --json > diagnostic.json
11
11
  ```
12
12
 
13
- Omit `--packet` for installation and skill diagnostics only. Use `--platform
14
- claude` for a Claude-only profile. `--context` and `--report` may select existing
13
+ Omit `--packet` for installation and skill diagnostics only. Without
14
+ `--platform`, only the platforms where Campaigns OS skills are installed are
15
+ checked and the export reports `platform: installed` (or `all` when none are
16
+ installed, so every platform was checked); use `--platform claude` to
17
+ check one profile, or `--platform all` for every one. `--context` and `--report` may select existing
15
18
  local sidecars; `--target` selects a local skills directory. These inputs are
16
19
  never included in the export. The text and JSON forms are suitable for review
17
20
  and copying to a support request. The command itself sends nothing.