@nextcommerce/campaigns-os 1.53.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.
- package/CHANGELOG.md +145 -0
- package/CONTEXT.md +8 -5
- package/README.md +26 -11
- package/compatibility.json +1 -1
- package/contracts/campaign-cart-checkout-field-contract.v0.json +10 -0
- package/contracts/campaign-cart-sdk-support-policy.v0.json +2 -2
- package/contracts/commerce-surface-catalog.json +27 -27
- package/contracts/effects.v1.json +96 -37
- package/contracts/release-ledger.json +774 -0
- package/contracts/supported-surface.json +4 -4
- package/contracts/template-brand-contract.shared-commerce.v0.json +1 -1
- package/docs/brand-theme-bridge.md +10 -0
- package/docs/build-packet.md +45 -22
- package/docs/campaign-standardization-report.md +32 -0
- package/docs/campaigns-os-build-flow.md +1 -1
- package/docs/design-source-package.md +7 -3
- package/docs/effects.md +4 -6
- package/docs/local-setup.md +1 -1
- package/docs/orientation-contract-reference.md +1 -1
- package/docs/progress-snapshots.md +3 -1
- package/docs/qa-and-test-orders.md +83 -14
- package/docs/runtime-readiness.md +1 -1
- package/docs/sdk-storage-compatibility.md +15 -0
- package/docs/skills-revision.md +10 -10
- package/docs/supported-surface.md +2 -1
- package/docs/workflow-findings-sidecar.md +57 -2
- package/package.json +3 -1
- package/schemas/campaign-runtime-assembly-report.v0.schema.json +5 -1
- package/schemas/campaigns-os-run-record.v0.schema.json +20 -15
- package/skills/campaign-lifecycle-orientation/SKILL.md +3 -3
- package/skills/campaign-readback-classification/SKILL.md +3 -3
- package/skills/campaign-run-evidence/SKILL.md +3 -3
- package/skills/contribution-intake/SKILL.md +3 -3
- package/skills/next-campaigns-build/SKILL.md +3 -3
- package/skills/next-campaigns-os/SKILL.md +3 -3
- package/skills/next-campaigns-os-setup/SKILL.md +3 -3
- package/skills/next-campaigns-polish/SKILL.md +3 -3
- package/skills/next-campaigns-qa/SKILL.md +4 -4
- package/skills.json +10 -10
- package/src/adapter-decision-contract.mjs +26 -12
- package/src/brand-theme.mjs +44 -8
- package/src/campaign-ecosystem.mjs +153 -31
- package/src/campaign-identity.mjs +33 -4
- package/src/cli.mjs +58 -62
- package/src/consent.mjs +3 -2
- package/src/design-source-publication.mjs +1 -1
- package/src/deviation.mjs +2 -1
- package/src/directory-lock.mjs +79 -7
- package/src/doctor/checks.mjs +28 -8
- package/src/doctor/inspect.mjs +13 -0
- package/src/doctor/next-step.mjs +16 -6
- package/src/invocation.mjs +7 -4
- package/src/lifecycle.mjs +88 -6
- package/src/local-preview-policy.mjs +6 -0
- package/src/login.mjs +2 -1
- package/src/polish-browser.mjs +8 -2
- package/src/polish-node.mjs +6 -1
- package/src/polish-readability.mjs +2 -2
- package/src/progress-node.mjs +3 -2
- package/src/qa-browser.mjs +595 -95
- package/src/qa-cart-entry.mjs +29 -6
- package/src/qa-node.mjs +177 -43
- package/src/qa-verdict-publish.mjs +2 -1
- package/src/run-record.mjs +46 -34
- package/src/sdk-attribute-index.mjs +111 -23
- package/src/sdk-markup.mjs +89 -10
- package/src/sdk-repin.mjs +282 -0
- package/src/stage-ledger.mjs +15 -3
- package/src/stage-record.mjs +85 -17
- package/src/standardization-report.mjs +26 -1
- package/src/target-lock.mjs +9 -1
|
@@ -13,9 +13,10 @@ implementation detail, however stable it looks.
|
|
|
13
13
|
|
|
14
14
|
| Surface | Contract | Change discipline |
|
|
15
15
|
|---|---|---|
|
|
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). |
|
|
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). 1.55.0 (breaking) adds the optional publish decision `reason`, record `closed_by` closer, QA observation `verdict_run_id`, `build_fingerprint`, and `stale`, lifecycle `stages[].wait_ms` and `stages[].finding_codes`, and run-level `needs_input_count` and `failure_count` while removing the unused `agent_usage` field from the same v0 Run Record shape. |
|
|
17
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`, `login`, `logout` | 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 five registered gates: `page_kit.store_profile`, `page_kit.sdk_version`, `polish.hidden_eager_media`, `built_output.upsell_selector_scope`, and `source_html.producer_provenance` (per page, with `--page <page_id>`). `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
|
+
| `sdk repin` | Rewrites the version segment of semver-pinned Campaign Cart loader.js / campaign-cart.css URLs in a static repo (no `_data/campaigns.json`) to a target version, default the SDK support policy's `preferred_minimum`. It previews by default. `--apply` writes the files and the change record `.campaign-runtime/sdk-repin.json` (`campaigns-os-sdk-repin/v0`). `@latest`, `@main`, commit and prerelease refs, and pins at or above the target, are reported and never rewritten. A page-kit repo is refused with exit 2. Usage is in `docs/sdk-storage-compatibility.md`. | Additive supported subcommand under the listed `sdk` command. It never changes anything in a URL except the version segment. |
|
|
19
20
|
| `bin/campaigns-os.mjs` (`campaigns-os`) | The CLI entry itself. | Declared in `package.json` `bin`; the gate fails if it disappears. |
|
|
20
21
|
| 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. |
|
|
21
22
|
| Package exports `./commercial-journey` and `./commercial-parity` | Portable scenario planning, response normalization, contract-governed source extraction, Exact-only parity comparison, and deterministic QA assertion serialization. These modules own no network transport and do not calculate prices locally. | Consumers execute descriptors through a supported calculate transport, then pass captured envelopes into the pure normalizer. Existing export paths are gated and may not be renamed or removed without a breaking surface change. |
|
|
@@ -51,7 +51,8 @@ own schemas and evolve independently). Instead it carries:
|
|
|
51
51
|
|
|
52
52
|
- **Stable envelope** — `schema_version` (`campaigns-os-run-record/v0`),
|
|
53
53
|
`run_id`, package version, the command that ran, an `argv` *shape* (flag names
|
|
54
|
-
present, not raw values), `created_at`, consent state,
|
|
54
|
+
present, not raw values), `created_at`, consent state, remit status, and
|
|
55
|
+
optional `closed_by` (`run_end`, `qa_auto_end`, `stale_sweep`, or `manual`).
|
|
55
56
|
- **Run identity** — `map_id`, `campaign_slug`, `template_family`,
|
|
56
57
|
`entry_point_shape`. (Best-effort; missing identity never blocks capture.)
|
|
57
58
|
- **Source artifact refs** — for the Build Packet, Build Context, Assembly
|
|
@@ -64,6 +65,17 @@ own schemas and evolve independently). Instead it carries:
|
|
|
64
65
|
this run.
|
|
65
66
|
- **Findings snapshot** — this run's Workflow Findings (see channel below).
|
|
66
67
|
|
|
68
|
+
When a QA verdict is present, `observations.qa.verdict_run_id` names the same
|
|
69
|
+
verdict that supplies `disposition`. `build_fingerprint` is the QA stage's
|
|
70
|
+
recorded build fingerprint only when the Assembly Report binds that stage to
|
|
71
|
+
the same verdict; otherwise it is `null`. `stale` compares that fingerprint
|
|
72
|
+
with the Assembly Report's recorded build fingerprint using the same comparison
|
|
73
|
+
as `next`: `true` when they differ, `false` when they match, and `null` when
|
|
74
|
+
either fingerprint is unknown. A rebuild without `record build` therefore reads
|
|
75
|
+
`stale: false` when the recorded fingerprints still match; doctor's
|
|
76
|
+
`built_output.fingerprint_stale` checks the output on disk. All three fields
|
|
77
|
+
are optional for older records; without a verdict, `observations.qa` is absent.
|
|
78
|
+
|
|
67
79
|
### Run identity
|
|
68
80
|
|
|
69
81
|
A single canonical `campaigns_os_run_id` is minted at the run boundary and
|
|
@@ -78,6 +90,45 @@ Stage timings and repair-loop count are captured from the command lifecycle
|
|
|
78
90
|
journal when a run session or explicit lifecycle journal is active. They remain
|
|
79
91
|
best-effort signal: telemetry records the commands Campaigns OS can observe, not
|
|
80
92
|
every thought, browser click, or external editor action in an agent session.
|
|
93
|
+
Each new journal entry records `wait_ms` as non-negative whole milliseconds
|
|
94
|
+
blocked on terminal input; an invocation without a prompt records 0. Legacy
|
|
95
|
+
entries may omit it or hold null, and Run Record stages preserve unknown wait
|
|
96
|
+
as absent or null rather than inventing 0. `duration_ms` still includes prompt
|
|
97
|
+
wait, so observed command work is `duration_ms - wait_ms` when wait is known. Tier-2 phases carry their
|
|
98
|
+
own measured wait when the prompt occurs while that phase is active; the journal
|
|
99
|
+
also retains the invocation total. Nested prompt hooks count their outer wait
|
|
100
|
+
interval once. Authentication prompts are outside lifecycle capture by policy.
|
|
101
|
+
|
|
102
|
+
On a non-zero doctor or QA exit, optional `finding_codes` is an array of at most
|
|
103
|
+
five distinct string codes in first-seen order; null is invalid. Codes belong
|
|
104
|
+
to the phase active when they were recorded. Codes recorded outside any phase,
|
|
105
|
+
and codes in a legacy entry, are invocation-level only; aggregation assigns them
|
|
106
|
+
to the entry's last phase. A successful stage has no finding codes. The optional run-level
|
|
107
|
+
`needs_input_count` and `failure_count` are non-negative integer counts; null is
|
|
108
|
+
invalid and absence means a legacy record did not report the count.
|
|
109
|
+
`needs_input_count` counts journal entries with exit 2 and `failure_count`
|
|
110
|
+
counts entries with any other non-zero exit. Current command
|
|
111
|
+
paths use 0 for success, 1 for operational errors, 2 for missing or blocked
|
|
112
|
+
inputs, and 4 for blocked QA; the other-non-zero rule also covers a future
|
|
113
|
+
status without reclassifying exit 2. Both counts are per command invocation,
|
|
114
|
+
including a command that emits multiple Tier-2 stages. `repair_loop_count`
|
|
115
|
+
continues to count repeated commands plus explicit repair-loop hooks.
|
|
116
|
+
|
|
117
|
+
| Terminal input site | Wait hook | Capture context |
|
|
118
|
+
|---|---|---|
|
|
119
|
+
| Consent question (`src/consent.mjs`) | Around the injectable `ask` call | Active command, including `run-record` |
|
|
120
|
+
| Store question (`src/login.mjs`) | Around readline `question` | Authentication runs outside lifecycle capture |
|
|
121
|
+
| Finding stage, kind, summary, details (`src/cli.mjs`) | Around each readline `question` | Active `findings add` command; omitted fields do not prompt |
|
|
122
|
+
|
|
123
|
+
| Non-zero finding source | Codes recorded |
|
|
124
|
+
|---|---|
|
|
125
|
+
| `doctor` | `result.errors[].code` before rendering and exit 2 |
|
|
126
|
+
| `start` and `build` | Their embedded doctor `errors[].code` before the prepare result sets exit 2 |
|
|
127
|
+
| `qa run` and `qa parity` | Blocked verdict assertions: `evidence.code`, or assertion `id` when no code is present, before returning from QA dispatch with exit 4 |
|
|
128
|
+
|
|
129
|
+
Spec resolution exceptions and prepare-build without a doctor result do not
|
|
130
|
+
expose doctor or QA codes. They keep their existing exit and timing evidence,
|
|
131
|
+
with no invented finding code.
|
|
81
132
|
|
|
82
133
|
### Validation
|
|
83
134
|
|
|
@@ -246,7 +297,11 @@ remit(path, payload, proxyBase) // mirrors qa-node.mjs postVerdict
|
|
|
246
297
|
for a later post of the stored verdict), `attempted` / `ok` / `error` /
|
|
247
298
|
`endpoint` (`/api/qa/verdicts`), a `state` (`skipped` when the run's
|
|
248
299
|
publish was off, `ok`, `failed`), the `result` in the same vocabulary as
|
|
249
|
-
`remit_result`, the `base_kind`,
|
|
300
|
+
`remit_result`, the `base_kind`, `published_at`, and optional `reason`.
|
|
301
|
+
The reason records the actual QA publish decision: `loopback_base_url`,
|
|
302
|
+
`portal_managed_default`, `consent_off`, `flag_opt_out`, `flag_opt_in`,
|
|
303
|
+
`default`, or `local_spec`. A later `qa publish` has no QA run decision and
|
|
304
|
+
records a null reason. `qa run` hands the
|
|
250
305
|
block to the session through its QA attempt, so `run end` and the auto-end
|
|
251
306
|
stamp it; `qa publish` stamps the record whose `qa_verdict` artifact
|
|
252
307
|
references the verdict, reads `state: "ok"` as already published, and
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextcommerce/campaigns-os",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.55.0",
|
|
4
4
|
"description": "Toolkit for agent-assisted NEXT campaign builds.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -66,6 +66,8 @@
|
|
|
66
66
|
"check:spec": "node --test \"campaign-spec/test/**/*.test.ts\"",
|
|
67
67
|
"check": "npm run check:provenance && npm run check:workflows && npm run check:changelog-structure && npm run build:spec && npm run check:tests && npm run check:spec && npm run check:fixtures && npm run check:legacy-migration && npm run check:spec-conformance && npm run check:private-strings && npm run check:template-doctrine && npm run check:slot-manifest && npm run check:skill-versions && npm run check:cart-readiness && npm run check:sidecar-bundle && npm run check:supported-surface && npm run check:effects && npm run check:release-ledger && npm run check:runtime-recipe && npm run check:orientation-docs && npm run check:runtime-docs && npm run check:pack -- --skip-prepare",
|
|
68
68
|
"check:tests": "node ./scripts/check-tests.mjs",
|
|
69
|
+
"check:fast": "node ./scripts/check-fast.mjs",
|
|
70
|
+
"hooks:install": "node ./scripts/install-git-hooks.mjs",
|
|
69
71
|
"check:legacy-migration": "node ./scripts/check-legacy-migration.mjs",
|
|
70
72
|
"check:fixtures": "node ./scripts/check-fixtures.mjs",
|
|
71
73
|
"check:spec-conformance": "node ./scripts/check-campaign-spec-conformance.mjs",
|
|
@@ -329,7 +329,11 @@
|
|
|
329
329
|
"items": { "type": "string", "minLength": 1 }
|
|
330
330
|
},
|
|
331
331
|
"performed_by": { "type": "string", "minLength": 1 },
|
|
332
|
-
"source_build_fingerprint": {
|
|
332
|
+
"source_build_fingerprint": {
|
|
333
|
+
"description": "The build output fingerprint (stages.assembly.build_fingerprint) this stage was recorded against. stages.polish and stages.deploy carry it; record build makes a completed stage that names other output required again (a demoted stages.deploy keeps its prior record, with that record's outputs and evidence, in its history). A stages.deploy without it was recorded before deploy stamped its build and is kept as recorded.",
|
|
334
|
+
"type": "string",
|
|
335
|
+
"minLength": 1
|
|
336
|
+
},
|
|
333
337
|
"source_package_material_fingerprint": { "type": "string", "minLength": 1 },
|
|
334
338
|
"build_fingerprint": { "type": "string", "minLength": 1 },
|
|
335
339
|
"artifact_fingerprint": { "type": "string", "minLength": 1 },
|
|
@@ -134,6 +134,11 @@
|
|
|
134
134
|
"enum": ["skipped", "ok", "failed"],
|
|
135
135
|
"description": "skipped: publish was off for the run (no send). ok: the receiver's answer counts as stored. failed: refused or never answered."
|
|
136
136
|
},
|
|
137
|
+
"reason": {
|
|
138
|
+
"type": ["string", "null"],
|
|
139
|
+
"enum": ["loopback_base_url", "portal_managed_default", "consent_off", "flag_opt_out", "flag_opt_in", "default", "local_spec", null],
|
|
140
|
+
"description": "The QA publish decision's reason. null when no decision was recorded, such as a later qa publish of a stored verdict."
|
|
141
|
+
},
|
|
137
142
|
"result": {
|
|
138
143
|
"type": ["string", "null"],
|
|
139
144
|
"enum": ["stored", "already_stored", "ok_unparsed_ack", "refused", "transport_error", null],
|
|
@@ -226,6 +231,9 @@
|
|
|
226
231
|
"additionalProperties": false,
|
|
227
232
|
"properties": {
|
|
228
233
|
"disposition": { "type": ["string", "null"] },
|
|
234
|
+
"verdict_run_id": { "type": ["string", "null"], "minLength": 1, "description": "Run ID of the verdict supplying disposition." },
|
|
235
|
+
"build_fingerprint": { "type": ["string", "null"], "minLength": 1, "description": "QA build fingerprint from the Assembly Report stage bound to that verdict." },
|
|
236
|
+
"stale": { "type": ["boolean", "null"], "description": "Whether that QA fingerprint differs from the current recorded build; null when either fingerprint is unknown." },
|
|
229
237
|
"gap_classes": {
|
|
230
238
|
"type": "array",
|
|
231
239
|
"items": { "type": "string" },
|
|
@@ -286,19 +294,10 @@
|
|
|
286
294
|
"type": ["string", "null"],
|
|
287
295
|
"description": "Optional free-form confidence hint for primary_surface, e.g. \"low\"."
|
|
288
296
|
},
|
|
289
|
-
"
|
|
290
|
-
"type": "
|
|
291
|
-
"
|
|
292
|
-
"description": "
|
|
293
|
-
"properties": {
|
|
294
|
-
"input_tokens": { "type": "integer", "minimum": 0 },
|
|
295
|
-
"output_tokens": { "type": "integer", "minimum": 0 },
|
|
296
|
-
"tool_output_tokens": { "type": "integer", "minimum": 0 },
|
|
297
|
-
"total_tokens": { "type": "integer", "minimum": 0 },
|
|
298
|
-
"elapsed_ms": { "type": "integer", "minimum": 0 },
|
|
299
|
-
"model": { "type": "string" },
|
|
300
|
-
"source": { "type": "string" }
|
|
301
|
-
}
|
|
297
|
+
"closed_by": {
|
|
298
|
+
"type": "string",
|
|
299
|
+
"enum": ["run_end", "qa_auto_end", "stale_sweep", "manual"],
|
|
300
|
+
"description": "The command path that closed this Run Record. Absent on records written before this field existed."
|
|
302
301
|
},
|
|
303
302
|
"lifecycle": {
|
|
304
303
|
"type": ["object", "null"],
|
|
@@ -327,17 +326,23 @@
|
|
|
327
326
|
"type": "object",
|
|
328
327
|
"additionalProperties": false,
|
|
329
328
|
"required": ["name"],
|
|
329
|
+
"if": { "required": ["finding_codes"], "properties": { "finding_codes": {} } },
|
|
330
|
+
"then": { "required": ["exit_status"], "properties": { "exit_status": { "type": "integer", "not": { "const": 0 } } } },
|
|
330
331
|
"properties": {
|
|
331
332
|
"name": { "type": "string" },
|
|
332
333
|
"duration_ms": { "type": ["number", "null"] },
|
|
333
|
-
"exit_status": { "type": ["integer", "null"] }
|
|
334
|
+
"exit_status": { "type": ["integer", "null"] },
|
|
335
|
+
"wait_ms": { "type": ["integer", "null"], "minimum": 0, "description": "Whole milliseconds blocked on operator input. Absent or null means unknown for legacy entries; duration_ms includes it." },
|
|
336
|
+
"finding_codes": { "type": "array", "maxItems": 5, "uniqueItems": true, "items": { "type": "string" }, "description": "First five distinct doctor or QA finding codes, only on a non-zero exit." }
|
|
334
337
|
}
|
|
335
338
|
}
|
|
336
339
|
},
|
|
337
340
|
"repair_loop_count": {
|
|
338
341
|
"type": ["integer", "null"],
|
|
339
342
|
"description": "Re-runs of any command within the run (a re-run is a repair loop: doctor -> fix -> doctor). 0 when each command ran once."
|
|
340
|
-
}
|
|
343
|
+
},
|
|
344
|
+
"needs_input_count": { "type": "integer", "minimum": 0, "description": "Number of command invocations with exit_status 2." },
|
|
345
|
+
"failure_count": { "type": "integer", "minimum": 0, "description": "Number of command invocations with a non-zero exit_status other than 2." }
|
|
341
346
|
}
|
|
342
347
|
}
|
|
343
348
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: campaign-lifecycle-orientation
|
|
3
|
-
version: 1.0.
|
|
3
|
+
version: 1.0.32
|
|
4
4
|
description: Orient a reader to the Campaigns OS lifecycle artifacts a run has already emitted, without advancing any stage or changing any state.
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
Bundle revision: 1.
|
|
8
|
-
Run `npx --no-install campaigns-os tooling status --skills-revision 1.
|
|
7
|
+
Bundle revision: 1.55.0+skills.1
|
|
8
|
+
Run `npx --no-install campaigns-os tooling status --skills-revision 1.55.0+skills.1`
|
|
9
9
|
from the campaign's Page Kit folder, where it runs the project's pinned copy and
|
|
10
10
|
never installs one, at the start of each task. Start a fresh session if it
|
|
11
11
|
reports `mismatch`: this text is already in your context and is never re-read
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: campaign-readback-classification
|
|
3
|
-
version: 1.0.
|
|
3
|
+
version: 1.0.32
|
|
4
4
|
description: Classify a selected campaign from the readback projection's v2 fields and write a read-only handoff without turning diagnosis into permission.
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
Bundle revision: 1.
|
|
8
|
-
Run `npx --no-install campaigns-os tooling status --skills-revision 1.
|
|
7
|
+
Bundle revision: 1.55.0+skills.1
|
|
8
|
+
Run `npx --no-install campaigns-os tooling status --skills-revision 1.55.0+skills.1`
|
|
9
9
|
from the campaign's Page Kit folder, where it runs the project's pinned copy and
|
|
10
10
|
never installs one, at the start of each task. Start a fresh session if it
|
|
11
11
|
reports `mismatch`: this text is already in your context and is never re-read
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: campaign-run-evidence
|
|
3
|
-
version: 1.0.
|
|
3
|
+
version: 1.0.32
|
|
4
4
|
description: Interpret existing Campaigns OS doctor, QA and proof-depth evidence without claiming more proof than the artifacts contain.
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
Bundle revision: 1.
|
|
8
|
-
Run `npx --no-install campaigns-os tooling status --skills-revision 1.
|
|
7
|
+
Bundle revision: 1.55.0+skills.1
|
|
8
|
+
Run `npx --no-install campaigns-os tooling status --skills-revision 1.55.0+skills.1`
|
|
9
9
|
from the campaign's Page Kit folder, where it runs the project's pinned copy and
|
|
10
10
|
never installs one, at the start of each task. Start a fresh session if it
|
|
11
11
|
reports `mismatch`: this text is already in your context and is never re-read
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: contribution-intake
|
|
3
|
-
version: 1.0.
|
|
3
|
+
version: 1.0.32
|
|
4
4
|
description: Turn a suggestion about the agent surface into a classified, evidence-checked proposal and, only with attended approval, one issue on this repository's tracker.
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
Bundle revision: 1.
|
|
8
|
-
Run `npx --no-install campaigns-os tooling status --skills-revision 1.
|
|
7
|
+
Bundle revision: 1.55.0+skills.1
|
|
8
|
+
Run `npx --no-install campaigns-os tooling status --skills-revision 1.55.0+skills.1`
|
|
9
9
|
from the campaign's Page Kit folder, where it runs the project's pinned copy and
|
|
10
10
|
never installs one, at the start of each task. Start a fresh session if it
|
|
11
11
|
reports `mismatch`: this text is already in your context and is never re-read
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: next-campaigns-build
|
|
3
|
-
version: 1.0.
|
|
3
|
+
version: 1.0.37
|
|
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
|
-
Bundle revision: 1.
|
|
8
|
-
Run `npx --no-install campaigns-os tooling status --skills-revision 1.
|
|
7
|
+
Bundle revision: 1.55.0+skills.1
|
|
8
|
+
Run `npx --no-install campaigns-os tooling status --skills-revision 1.55.0+skills.1`
|
|
9
9
|
from the campaign's Page Kit folder, where it runs the project's pinned copy and
|
|
10
10
|
never installs one, at the start of each task. Start a fresh session if it
|
|
11
11
|
reports `mismatch`: this text is already in your context and is never re-read
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: next-campaigns-os
|
|
3
|
-
version: 1.0.
|
|
3
|
+
version: 1.0.52
|
|
4
4
|
description: Coordinate Campaigns OS lifecycle workflows from CampaignSpec, Build Packet, starter-template contracts, stage reports, deploy evidence, and QA proof depth.
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
Bundle revision: 1.
|
|
8
|
-
Run `npx --no-install campaigns-os tooling status --skills-revision 1.
|
|
7
|
+
Bundle revision: 1.55.0+skills.1
|
|
8
|
+
Run `npx --no-install campaigns-os tooling status --skills-revision 1.55.0+skills.1`
|
|
9
9
|
from the campaign's Page Kit folder, where it runs the project's pinned copy and
|
|
10
10
|
never installs one, at the start of each task. Start a fresh session if it
|
|
11
11
|
reports `mismatch`: this text is already in your context and is never re-read
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: next-campaigns-os-setup
|
|
3
|
-
version: 2.0.
|
|
3
|
+
version: 2.0.35
|
|
4
4
|
description: Bootstrap or prepare a target page-kit campaign repo from a doctor-cleared Campaigns OS Build Packet before full build wiring. Formerly installed as next-campaigns-setup; renamed 2026-08 to stop colliding with the published NextCommerceCo/skills scaffolder of that name.
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
Bundle revision: 1.
|
|
8
|
-
Run `npx --no-install campaigns-os tooling status --skills-revision 1.
|
|
7
|
+
Bundle revision: 1.55.0+skills.1
|
|
8
|
+
Run `npx --no-install campaigns-os tooling status --skills-revision 1.55.0+skills.1`
|
|
9
9
|
from the campaign's Page Kit folder, where it runs the project's pinned copy and
|
|
10
10
|
never installs one, at the start of each task. Start a fresh session if it
|
|
11
11
|
reports `mismatch`: this text is already in your context and is never re-read
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: next-campaigns-polish
|
|
3
|
-
version: 1.1.
|
|
3
|
+
version: 1.1.36
|
|
4
4
|
description: Run the visual/runtime polish pass after build and before QA for a Campaigns OS campaign.
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
Bundle revision: 1.
|
|
8
|
-
Run `npx --no-install campaigns-os tooling status --skills-revision 1.
|
|
7
|
+
Bundle revision: 1.55.0+skills.1
|
|
8
|
+
Run `npx --no-install campaigns-os tooling status --skills-revision 1.55.0+skills.1`
|
|
9
9
|
from the campaign's Page Kit folder, where it runs the project's pinned copy and
|
|
10
10
|
never installs one, at the start of each task. Start a fresh session if it
|
|
11
11
|
reports `mismatch`: this text is already in your context and is never re-read
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: next-campaigns-qa
|
|
3
|
-
version: 1.3.
|
|
3
|
+
version: 1.3.36
|
|
4
4
|
description: Run spec-aware QA from a saved Map or local-spec Build Packet and tested campaign URL after build, polish, and deploy/local evidence exist, including Playwright typed-card test-order proof.
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
Bundle revision: 1.
|
|
8
|
-
Run `npx --no-install campaigns-os tooling status --skills-revision 1.
|
|
7
|
+
Bundle revision: 1.55.0+skills.1
|
|
8
|
+
Run `npx --no-install campaigns-os tooling status --skills-revision 1.55.0+skills.1`
|
|
9
9
|
from the campaign's Page Kit folder, where it runs the project's pinned copy and
|
|
10
10
|
never installs one, at the start of each task. Start a fresh session if it
|
|
11
11
|
reports `mismatch`: this text is already in your context and is never re-read
|
|
@@ -80,7 +80,7 @@ Rules:
|
|
|
80
80
|
- Parity capture blocking proof is the voucher-adjusted persisted line from typed-card order readback. Browser totals and client state do not replace the persisted-line voucher guard.
|
|
81
81
|
- Read client purchase values per event. A whole-cart `dl_purchase` must not mask or supply an offer-level upsell purchase expectation.
|
|
82
82
|
- Live `qa parity` runs publish to the QA portal by default like other QA runs. Pass `--no-post-verdict` for dev, replay, negative-control, and other local proof runs.
|
|
83
|
-
- Theme gate: `qa run` refuses to run when a generatable brand theme is not applied to commerce pages and no waiver exists. Apply the brand layer or
|
|
83
|
+
- Theme gate: `qa run` refuses to run when a generatable brand theme is not applied to commerce pages and no waiver exists. Apply the brand layer or use the recorded waiver `campaigns-os theme waive --packet <p> --reason "<why>" --waived-by "<named human>"` (tier `C`: it overwrites the assembly report and doctor output). `qa run --theme-waive "<reason>"` is the one-run ephemeral form. Do not bypass the gate another way. A waived run still reports template-residue findings at warn severity.
|
|
84
84
|
- Template residue is a QA dimension, not advice: promoted starter families must have a brand/residue/pricing contract (`contracts/template-brand-contract.<family>.v0.json`). Browser QA inspects computed styles on commerce surfaces and fails pages that still render starter defaults (`#3c7dff`/`#0a265c`, starter `next-logo.png`, paypal/klarna chrome absent from the spec).
|
|
85
85
|
- Pricing visibility is a blocker: an upsell/downsell offer with zero visible price rows fails QA. Pricing surfaces render via template pricing modes (`full_price`, `compare_at_current`, `unit_price_plus_total`, `savings_badge_amount`, `code_discounted_post_checkout`), never via campaign CSS `display:none` on price wrappers.
|
|
86
86
|
- The upsell and checkout bundle price checks count the SDK's `data-next-bundle-display` price as a price row when it is visible and not empty.
|
package/skills.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "campaigns-os-skills",
|
|
3
3
|
"description": "Skills bundled with Campaigns OS. `skills.sh` installs these into the shared agent skill directories (~/.claude/skills, ~/.codex/skills), so each one is a versioned package: bump the version whenever a package changes. `bundle_revision` identifies the bundle as a whole — `<package version>+skills.<n>`, where the prefix is this package's version and `<n>` counts the skill-text revisions published against it. It advances whenever ANY bundled skill changes, every SKILL.md states it on its first body line, and `campaigns-os tooling status --skills-revision <value>` compares the value an agent read from a skill against the bundle on disk. See docs/skills-revision.md.",
|
|
4
|
-
"bundle_revision": "1.
|
|
4
|
+
"bundle_revision": "1.55.0+skills.1",
|
|
5
5
|
"homepage": "https://github.com/NextCommerceCo/campaigns-os",
|
|
6
6
|
"retired_skills": [
|
|
7
7
|
{
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
{
|
|
17
17
|
"id": "next-campaigns-os",
|
|
18
18
|
"name": "Campaigns OS Lifecycle",
|
|
19
|
-
"version": "1.0.
|
|
19
|
+
"version": "1.0.52",
|
|
20
20
|
"path": "skills/next-campaigns-os/SKILL.md",
|
|
21
21
|
"domain": "campaigns",
|
|
22
22
|
"description": "Coordinate Campaigns OS lifecycle workflows from CampaignSpec, Build Packet, starter-template contracts, stage reports, deploy evidence, and QA proof depth."
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
{
|
|
25
25
|
"id": "next-campaigns-os-setup",
|
|
26
26
|
"name": "Campaigns OS Setup",
|
|
27
|
-
"version": "2.0.
|
|
27
|
+
"version": "2.0.35",
|
|
28
28
|
"path": "skills/next-campaigns-os-setup/SKILL.md",
|
|
29
29
|
"domain": "campaigns",
|
|
30
30
|
"description": "Bootstrap or prepare a target page-kit campaign repo from a doctor-cleared Campaigns OS Build Packet before full build wiring. Formerly next-campaigns-setup; renamed to release that name to the published NextCommerceCo/skills scaffolder."
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
{
|
|
33
33
|
"id": "next-campaigns-build",
|
|
34
34
|
"name": "Campaign Build",
|
|
35
|
-
"version": "1.0.
|
|
35
|
+
"version": "1.0.37",
|
|
36
36
|
"path": "skills/next-campaigns-build/SKILL.md",
|
|
37
37
|
"domain": "campaigns",
|
|
38
38
|
"description": "Assemble a NEXT campaign from a doctor-cleared Build Packet, CampaignSpec/API values, prepared HTML/assets, page-kit, and starter-template contracts."
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
{
|
|
41
41
|
"id": "next-campaigns-polish",
|
|
42
42
|
"name": "Campaign Polish",
|
|
43
|
-
"version": "1.1.
|
|
43
|
+
"version": "1.1.36",
|
|
44
44
|
"path": "skills/next-campaigns-polish/SKILL.md",
|
|
45
45
|
"domain": "campaigns",
|
|
46
46
|
"description": "Run the visual/runtime polish pass after build and before QA for a Campaigns OS campaign."
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
{
|
|
49
49
|
"id": "next-campaigns-qa",
|
|
50
50
|
"name": "Campaign QA",
|
|
51
|
-
"version": "1.3.
|
|
51
|
+
"version": "1.3.36",
|
|
52
52
|
"path": "skills/next-campaigns-qa/SKILL.md",
|
|
53
53
|
"domain": "campaigns",
|
|
54
54
|
"description": "Run spec-aware QA from a saved Map or local-spec Build Packet and tested campaign URL after build, polish, and deploy/local evidence exist, including Playwright typed-card test-order proof."
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
{
|
|
57
57
|
"id": "campaign-lifecycle-orientation",
|
|
58
58
|
"name": "Campaign Lifecycle Orientation",
|
|
59
|
-
"version": "1.0.
|
|
59
|
+
"version": "1.0.32",
|
|
60
60
|
"path": "skills/campaign-lifecycle-orientation/SKILL.md",
|
|
61
61
|
"domain": "campaigns",
|
|
62
62
|
"description": "Orient a reader to the Campaigns OS lifecycle artifacts a run has already emitted, without advancing their state: the shared vocabulary, doctor as a gate, the stage record, and the store-theme/Page Kit two-worlds trap."
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
{
|
|
65
65
|
"id": "campaign-run-evidence",
|
|
66
66
|
"name": "Campaign Run Evidence",
|
|
67
|
-
"version": "1.0.
|
|
67
|
+
"version": "1.0.32",
|
|
68
68
|
"path": "skills/campaign-run-evidence/SKILL.md",
|
|
69
69
|
"domain": "campaigns",
|
|
70
70
|
"description": "Interpret existing doctor, QA verdict and proof-depth evidence without claiming more proof than the artifacts contain, and keep funnel proof apart from merchant launch readiness."
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
{
|
|
73
73
|
"id": "campaign-readback-classification",
|
|
74
74
|
"name": "Campaign Readback Classification",
|
|
75
|
-
"version": "1.0.
|
|
75
|
+
"version": "1.0.32",
|
|
76
76
|
"path": "skills/campaign-readback-classification/SKILL.md",
|
|
77
77
|
"domain": "campaigns",
|
|
78
78
|
"description": "Classify a selected campaign from the campaigns-os-readback/v2 fields (artifacts, staleness.stale_keys, clean, doctor, divergences, skip_cascades) and write a read-only handoff without turning diagnosis into permission."
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
{
|
|
81
81
|
"id": "contribution-intake",
|
|
82
82
|
"name": "Contribution Intake",
|
|
83
|
-
"version": "1.0.
|
|
83
|
+
"version": "1.0.32",
|
|
84
84
|
"path": "skills/contribution-intake/SKILL.md",
|
|
85
85
|
"domain": "campaigns",
|
|
86
86
|
"description": "Turn a suggestion about the agent surface into a classified, evidence-checked and redacted proposal, filed on this repository tracker only with attended approval."
|
|
@@ -66,6 +66,20 @@ const SCRIPT_STYLE_REFERENCE_POLICIES = new Set(["frontmatter_or_campaign_asset"
|
|
|
66
66
|
const CTA_REWRITE_POLICIES = ROUTE_REWRITE_POLICIES;
|
|
67
67
|
const LAYOUT_CHOICES = new Set(["campaign_layout", "page_layout", "raw_passthrough", "not_applicable", "unknown"]);
|
|
68
68
|
|
|
69
|
+
// The scalar choices record build can set; the object-valued template slice
|
|
70
|
+
// stays with its existing proof fields and doctor checks.
|
|
71
|
+
export const ADAPTER_DECISION_SCALAR_VALUES = Object.freeze(Object.assign(Object.create(null), {
|
|
72
|
+
raw_html_conversion_status: [...RAW_HTML_CONVERSION_STATUSES],
|
|
73
|
+
source_asset_strategy: [...SOURCE_ASSET_STRATEGIES],
|
|
74
|
+
commerce_shell_adoption: [...COMMERCE_SHELL_ADOPTIONS],
|
|
75
|
+
route_rewrite_policy: [...ROUTE_REWRITE_POLICIES],
|
|
76
|
+
config_script_strategy: [...CONFIG_SCRIPT_STRATEGIES],
|
|
77
|
+
frontmatter_policy: [...FRONTMATTER_POLICIES],
|
|
78
|
+
script_style_reference_policy: [...SCRIPT_STYLE_REFERENCE_POLICIES],
|
|
79
|
+
cta_rewrite_policy: [...CTA_REWRITE_POLICIES],
|
|
80
|
+
layout_choice: [...LAYOUT_CHOICES],
|
|
81
|
+
}));
|
|
82
|
+
|
|
69
83
|
/**
|
|
70
84
|
* Seeds the adapter decision record written onto a new Build Packet.
|
|
71
85
|
*
|
|
@@ -170,7 +184,7 @@ export function validateAdapterSourceFiles({ decisions, sourceRoot, pages = [],
|
|
|
170
184
|
addIssue(
|
|
171
185
|
warnings,
|
|
172
186
|
"source_html.raw_html_wrappers",
|
|
173
|
-
`
|
|
187
|
+
`Effective raw_html_conversion_status is "${status}", but mapped source HTML still contains document wrapper tags: ${sample}${more}. Strip <!doctype>, <html>, <head>, and <body> before treating the page as page-kit-ready source.`
|
|
174
188
|
);
|
|
175
189
|
}
|
|
176
190
|
|
|
@@ -184,32 +198,32 @@ export function validateAdapterDecisionGates({ decisions, location, specPages =
|
|
|
184
198
|
addIssue(
|
|
185
199
|
warnings,
|
|
186
200
|
"adapter.raw_html_conversion_status",
|
|
187
|
-
`Assembly is recorded complete, but ${location}.raw_html_conversion_status is "${decisions.raw_html_conversion_status}".
|
|
201
|
+
`Assembly is recorded complete, but ${location}.raw_html_conversion_status is "${decisions.raw_html_conversion_status}". Use record build --adapter-decision raw_html_conversion_status=<value> to record completed/not_required after wrapper stripping, frontmatter, asset moves, script/style refs, CTA rewrites, route policy, and layout choice are settled.`
|
|
188
202
|
);
|
|
189
203
|
}
|
|
190
204
|
if (["raw_passthrough", "unknown"].includes(decisions.source_asset_strategy)) {
|
|
191
|
-
addIssue(warnings, "adapter.source_asset_strategy", `Assembly is recorded complete with ${location}.source_asset_strategy="${decisions.source_asset_strategy}".
|
|
205
|
+
addIssue(warnings, "adapter.source_asset_strategy", `Assembly is recorded complete with ${location}.source_asset_strategy="${decisions.source_asset_strategy}". Use record build --adapter-decision source_asset_strategy=<value> to record pagekit_campaign_asset_root when src/<slug>/assets/* publishes at /<slug>/*.`);
|
|
192
206
|
}
|
|
193
207
|
if (["raw_passthrough", "unknown"].includes(decisions.route_rewrite_policy)) {
|
|
194
|
-
addIssue(warnings, "adapter.route_rewrite_policy", `Assembly is recorded complete with ${location}.route_rewrite_policy="${decisions.route_rewrite_policy}".
|
|
208
|
+
addIssue(warnings, "adapter.route_rewrite_policy", `Assembly is recorded complete with ${location}.route_rewrite_policy="${decisions.route_rewrite_policy}". Use record build --adapter-decision route_rewrite_policy=<value> to record how CampaignSpec routes and CTA destinations were rewritten before QA.`);
|
|
195
209
|
}
|
|
196
210
|
if (decisions.config_script_strategy === "unknown") {
|
|
197
|
-
addIssue(warnings, "adapter.config_script_strategy", `Assembly is recorded complete but ${location}.config_script_strategy is unknown.
|
|
211
|
+
addIssue(warnings, "adapter.config_script_strategy", `Assembly is recorded complete but ${location}.config_script_strategy is unknown. Use record build --adapter-decision config_script_strategy=<value> to record whether config scripts load via campaign assets, frontmatter scripts, inline config, or not_required.`);
|
|
198
212
|
}
|
|
199
213
|
if (["preserve_document_wrappers", "unknown"].includes(decisions.wrapper_policy)) {
|
|
200
|
-
addIssue(warnings, "adapter.wrapper_policy", `Assembly is recorded complete with ${location}.wrapper_policy="${decisions.wrapper_policy}".
|
|
214
|
+
addIssue(warnings, "adapter.wrapper_policy", `Assembly is recorded complete with ${location}.wrapper_policy="${decisions.wrapper_policy}". Select wrapper_policy at intake with prepare-build --wrapper-policy or the source-html manifest's wrapper_policy option; page-kit source should normally strip document wrappers unless preserving them is explicitly not_required.`);
|
|
201
215
|
}
|
|
202
216
|
if (["raw_passthrough", "unknown"].includes(decisions.frontmatter_policy)) {
|
|
203
|
-
addIssue(warnings, "adapter.frontmatter_policy", `Assembly is recorded complete with ${location}.frontmatter_policy="${decisions.frontmatter_policy}".
|
|
217
|
+
addIssue(warnings, "adapter.frontmatter_policy", `Assembly is recorded complete with ${location}.frontmatter_policy="${decisions.frontmatter_policy}". Use record build --adapter-decision frontmatter_policy=<value> to record how Page Kit YAML frontmatter was created or why it is not_required.`);
|
|
204
218
|
}
|
|
205
219
|
if (["raw_passthrough", "unknown"].includes(decisions.script_style_reference_policy)) {
|
|
206
|
-
addIssue(warnings, "adapter.script_style_reference_policy", `Assembly is recorded complete with ${location}.script_style_reference_policy="${decisions.script_style_reference_policy}".
|
|
220
|
+
addIssue(warnings, "adapter.script_style_reference_policy", `Assembly is recorded complete with ${location}.script_style_reference_policy="${decisions.script_style_reference_policy}". Use record build --adapter-decision script_style_reference_policy=<value> to record how scripts/styles load via frontmatter, campaign assets, inline blocks, or not_required.`);
|
|
207
221
|
}
|
|
208
222
|
if (["raw_passthrough", "unknown"].includes(decisions.cta_rewrite_policy)) {
|
|
209
|
-
addIssue(warnings, "adapter.cta_rewrite_policy", `Assembly is recorded complete with ${location}.cta_rewrite_policy="${decisions.cta_rewrite_policy}".
|
|
223
|
+
addIssue(warnings, "adapter.cta_rewrite_policy", `Assembly is recorded complete with ${location}.cta_rewrite_policy="${decisions.cta_rewrite_policy}". Use record build --adapter-decision cta_rewrite_policy=<value> to record how CTA destinations were rewritten from CampaignSpec routes before QA.`);
|
|
210
224
|
}
|
|
211
225
|
if (["raw_passthrough", "unknown"].includes(decisions.layout_choice)) {
|
|
212
|
-
addIssue(warnings, "adapter.layout_choice", `Assembly is recorded complete with ${location}.layout_choice="${decisions.layout_choice}".
|
|
226
|
+
addIssue(warnings, "adapter.layout_choice", `Assembly is recorded complete with ${location}.layout_choice="${decisions.layout_choice}". Use record build --adapter-decision layout_choice=<value> to record the Page Kit layout strategy before handoff.`);
|
|
213
227
|
}
|
|
214
228
|
}
|
|
215
229
|
|
|
@@ -219,13 +233,13 @@ export function validateAdapterDecisionGates({ decisions, location, specPages =
|
|
|
219
233
|
addIssue(
|
|
220
234
|
errors,
|
|
221
235
|
"adapter.commerce_shell_adoption",
|
|
222
|
-
`Runtime commerce pages (${runtimePages.map((page) => page.id).join(", ")}) are marked custom_html_experimental for template family "${family}". Use template_clone_first_verified or sdk_surfaces_preserved before treating checkout/upsell/downsell/receipt as build-ready.`
|
|
236
|
+
`Runtime commerce pages (${runtimePages.map((page) => page.id).join(", ")}) are marked custom_html_experimental for template family "${family}". Use record build --adapter-decision commerce_shell_adoption=<value> to record template_clone_first_verified or sdk_surfaces_preserved before treating checkout/upsell/downsell/receipt as build-ready.`
|
|
223
237
|
);
|
|
224
238
|
} else if (assemblyComplete && !["template_clone_first_verified", "sdk_surfaces_preserved"].includes(adoption)) {
|
|
225
239
|
addIssue(
|
|
226
240
|
warnings,
|
|
227
241
|
"adapter.commerce_shell_adoption",
|
|
228
|
-
`Assembly is recorded complete, but ${location}.commerce_shell_adoption is "${adoption || "missing"}" for runtime commerce pages (${runtimePages.map((page) => page.id).join(", ")}).
|
|
242
|
+
`Assembly is recorded complete, but ${location}.commerce_shell_adoption is "${adoption || "missing"}" for runtime commerce pages (${runtimePages.map((page) => page.id).join(", ")}). Use record build --adapter-decision commerce_shell_adoption=<value> after commerce pages are template-clone-first, then styled, with SDK-owned surfaces preserved.`
|
|
229
243
|
);
|
|
230
244
|
}
|
|
231
245
|
}
|