@nextcommerce/campaigns-os 1.33.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/AGENTS.md +204 -0
- package/CHANGELOG.md +5002 -0
- package/CONTEXT.md +685 -0
- package/LICENSE +202 -0
- package/NOTICE +4 -0
- package/README.md +368 -0
- package/agents/claude/CLAUDE.md +32 -0
- package/agents/codex/AGENTS.md +27 -0
- package/agents/copilot/copilot-instructions.md +14 -0
- package/agents/cursor/campaigns-os.mdc +13 -0
- package/bin/campaigns-os.mjs +38 -0
- package/campaign-spec/README.md +138 -0
- package/campaign-spec/dist/analytics-vocabulary.d.ts +47 -0
- package/campaign-spec/dist/analytics-vocabulary.js +74 -0
- package/campaign-spec/dist/index.d.ts +40 -0
- package/campaign-spec/dist/index.js +77 -0
- package/campaign-spec/dist/normalize.d.ts +22 -0
- package/campaign-spec/dist/normalize.js +41 -0
- package/campaign-spec/dist/routing.d.ts +190 -0
- package/campaign-spec/dist/routing.js +263 -0
- package/campaign-spec/dist/rules/analytics-contract-shape.d.ts +42 -0
- package/campaign-spec/dist/rules/analytics-contract-shape.js +303 -0
- package/campaign-spec/dist/rules/assembly-hints-shape.d.ts +42 -0
- package/campaign-spec/dist/rules/assembly-hints-shape.js +191 -0
- package/campaign-spec/dist/rules/campaign-metadata.d.ts +14 -0
- package/campaign-spec/dist/rules/campaign-metadata.js +40 -0
- package/campaign-spec/dist/rules/checkout-has-success-url.d.ts +31 -0
- package/campaign-spec/dist/rules/checkout-has-success-url.js +66 -0
- package/campaign-spec/dist/rules/cycle-detection.d.ts +12 -0
- package/campaign-spec/dist/rules/cycle-detection.js +141 -0
- package/campaign-spec/dist/rules/design-source-shape.d.ts +29 -0
- package/campaign-spec/dist/rules/design-source-shape.js +142 -0
- package/campaign-spec/dist/rules/downsell-without-upsell.d.ts +11 -0
- package/campaign-spec/dist/rules/downsell-without-upsell.js +40 -0
- package/campaign-spec/dist/rules/exit-intent-validation.d.ts +23 -0
- package/campaign-spec/dist/rules/exit-intent-validation.js +147 -0
- package/campaign-spec/dist/rules/funnel-count.d.ts +9 -0
- package/campaign-spec/dist/rules/funnel-count.js +37 -0
- package/campaign-spec/dist/rules/funnel-hypothesis-length.d.ts +22 -0
- package/campaign-spec/dist/rules/funnel-hypothesis-length.js +60 -0
- package/campaign-spec/dist/rules/funnel-identity.d.ts +15 -0
- package/campaign-spec/dist/rules/funnel-identity.js +57 -0
- package/campaign-spec/dist/rules/funnel-weight-sum.d.ts +20 -0
- package/campaign-spec/dist/rules/funnel-weight-sum.js +66 -0
- package/campaign-spec/dist/rules/index.d.ts +69 -0
- package/campaign-spec/dist/rules/index.js +131 -0
- package/campaign-spec/dist/rules/offer-ref-integrity.d.ts +13 -0
- package/campaign-spec/dist/rules/offer-ref-integrity.js +59 -0
- package/campaign-spec/dist/rules/package-pricing-sanity.d.ts +12 -0
- package/campaign-spec/dist/rules/package-pricing-sanity.js +42 -0
- package/campaign-spec/dist/rules/page-count.d.ts +11 -0
- package/campaign-spec/dist/rules/page-count.js +31 -0
- package/campaign-spec/dist/rules/page-id-uniqueness.d.ts +14 -0
- package/campaign-spec/dist/rules/page-id-uniqueness.js +47 -0
- package/campaign-spec/dist/rules/promo-code-input-validation.d.ts +8 -0
- package/campaign-spec/dist/rules/promo-code-input-validation.js +126 -0
- package/campaign-spec/dist/rules/promo-codes-shape.d.ts +30 -0
- package/campaign-spec/dist/rules/promo-codes-shape.js +187 -0
- package/campaign-spec/dist/rules/route-field-ignored-for-page-type.d.ts +33 -0
- package/campaign-spec/dist/rules/route-field-ignored-for-page-type.js +81 -0
- package/campaign-spec/dist/rules/route-target-resolves.d.ts +32 -0
- package/campaign-spec/dist/rules/route-target-resolves.js +112 -0
- package/campaign-spec/dist/rules/schema-version.d.ts +21 -0
- package/campaign-spec/dist/rules/schema-version.js +53 -0
- package/campaign-spec/dist/rules/sdk-version.d.ts +26 -0
- package/campaign-spec/dist/rules/sdk-version.js +96 -0
- package/campaign-spec/dist/rules/shipping-countries-shape.d.ts +10 -0
- package/campaign-spec/dist/rules/shipping-countries-shape.js +30 -0
- package/campaign-spec/dist/rules/shipping-methods-present.d.ts +10 -0
- package/campaign-spec/dist/rules/shipping-methods-present.js +26 -0
- package/campaign-spec/dist/rules/store-profile-shape.d.ts +30 -0
- package/campaign-spec/dist/rules/store-profile-shape.js +127 -0
- package/campaign-spec/dist/rules/thank-you-requirement.d.ts +16 -0
- package/campaign-spec/dist/rules/thank-you-requirement.js +50 -0
- package/campaign-spec/dist/rules/unknown-top-level-fields.d.ts +28 -0
- package/campaign-spec/dist/rules/unknown-top-level-fields.js +114 -0
- package/campaign-spec/dist/rules/upsell-has-packages.d.ts +9 -0
- package/campaign-spec/dist/rules/upsell-has-packages.js +35 -0
- package/campaign-spec/dist/rules/upsell-routing-complete.d.ts +10 -0
- package/campaign-spec/dist/rules/upsell-routing-complete.js +45 -0
- package/campaign-spec/dist/rules/upsell-without-checkout.d.ts +11 -0
- package/campaign-spec/dist/rules/upsell-without-checkout.js +44 -0
- package/campaign-spec/dist/rules/variant-labels-shape.d.ts +28 -0
- package/campaign-spec/dist/rules/variant-labels-shape.js +86 -0
- package/campaign-spec/dist/sdk-version-parse.d.ts +43 -0
- package/campaign-spec/dist/sdk-version-parse.js +62 -0
- package/campaign-spec/dist/types.d.ts +674 -0
- package/campaign-spec/dist/types.js +40 -0
- package/campaign-spec/package.json +12 -0
- package/compatibility.json +25 -0
- package/contracts/agent-relevant-change-policy.v1.json +111 -0
- package/contracts/brand-theme-source-defaults.figma-sections-export.v0.json +32 -0
- package/contracts/brand-theme-target-tokens.next-core.v0.json +65 -0
- package/contracts/campaign-cart-checkout-field-contract.v0.json +45 -0
- package/contracts/campaign-cart-sdk-support-policy.v0.json +11 -0
- package/contracts/commerce-surface-catalog.json +2452 -0
- package/contracts/fixtures/orientation/canonicalization/v1.json +34 -0
- package/contracts/fixtures/orientation/envelope/current.json +95 -0
- package/contracts/fixtures/orientation/envelope/freshness_unknown.json +97 -0
- package/contracts/fixtures/orientation/envelope/legacy_baseline.json +95 -0
- package/contracts/fixtures/orientation/envelope/orientation_available.json +136 -0
- package/contracts/fixtures/orientation/envelope/recovered_interrupted_update.json +136 -0
- package/contracts/fixtures/orientation/envelope/refused.json +100 -0
- package/contracts/fixtures/orientation/envelope/restart_required.json +137 -0
- package/contracts/fixtures/orientation/envelope/updated.json +135 -0
- package/contracts/fixtures/orientation/hostile-target/README.md +61 -0
- package/contracts/fixtures/orientation/hostile-target/manifest.json +82 -0
- package/contracts/fixtures/orientation/hostile-target/repo/CHANGELOG.md +18 -0
- package/contracts/fixtures/orientation/hostile-target/repo/bin/intended.mjs +12 -0
- package/contracts/fixtures/orientation/hostile-target/repo/bin/tripwire.mjs +15 -0
- package/contracts/fixtures/orientation/hostile-target/repo/contracts/release-ledger.json +48 -0
- package/contracts/fixtures/orientation/hostile-target/repo/contracts/supported-surface.json +17 -0
- package/contracts/fixtures/orientation/hostile-target/repo/docs/example-contract.md +13 -0
- package/contracts/fixtures/orientation/hostile-target/repo/hooks/post-checkout +5 -0
- package/contracts/fixtures/orientation/hostile-target/repo/hooks/post-merge +5 -0
- package/contracts/fixtures/orientation/hostile-target/repo/hooks/pre-commit +5 -0
- package/contracts/fixtures/orientation/hostile-target/repo/hostile-dependency-tripwire/package.json +15 -0
- package/contracts/fixtures/orientation/hostile-target/repo/hostile-dependency-tripwire/tripwire.mjs +9 -0
- package/contracts/fixtures/orientation/hostile-target/repo/package.json +20 -0
- package/contracts/fixtures/orientation/hostile-target/repo/schemas/example.v0.schema.json +15 -0
- package/contracts/fixtures/orientation/release-gate/cases.json +1073 -0
- package/contracts/fixtures/runtime-recipe/accept/current.json +299 -0
- package/contracts/fixtures/runtime-recipe/accept/minimal.json +294 -0
- package/contracts/fixtures/runtime-recipe/dist-states.json +51 -0
- package/contracts/fixtures/runtime-recipe/manifest.json +85 -0
- package/contracts/fixtures/runtime-recipe/reject/advisory-enforcement.json +299 -0
- package/contracts/fixtures/runtime-recipe/reject/allowlist-without-hosts.json +297 -0
- package/contracts/fixtures/runtime-recipe/reject/committed-output-claim.json +299 -0
- package/contracts/fixtures/runtime-recipe/reject/engines-disagreement-warns.json +299 -0
- package/contracts/fixtures/runtime-recipe/reject/lifecycle-scripts-enabled.json +299 -0
- package/contracts/fixtures/runtime-recipe/reject/missing-required-field.json +251 -0
- package/contracts/fixtures/runtime-recipe/reject/unknown-kind.json +299 -0
- package/contracts/fixtures/runtime-recipe/reject/unknown-network-policy.json +299 -0
- package/contracts/fixtures/runtime-recipe/reject/unknown-output-check.json +310 -0
- package/contracts/fixtures/runtime-recipe/reject/unknown-revision.json +299 -0
- package/contracts/fixtures/runtime-recipe/reject/unknown-step-id.json +299 -0
- package/contracts/fixtures/runtime-recipe/reject/unperformable-check-skipped.json +299 -0
- package/contracts/fixtures/runtime-recipe/reject/unpinned-lockfile.json +299 -0
- package/contracts/fixtures/sidecar-bundle/production-shaped/.campaign-runtime/assembly-report.json +180 -0
- package/contracts/fixtures/sidecar-bundle/production-shaped/.campaign-runtime/build-context.json +115 -0
- package/contracts/fixtures/sidecar-bundle/production-shaped/.campaign-runtime/doctor-output.json +29 -0
- package/contracts/fixtures/sidecar-bundle/production-shaped/.campaign-runtime/qa-verdict.json +27 -0
- package/contracts/fixtures/sidecar-bundle/production-shaped/campaign-runtime.build.json +141 -0
- package/contracts/migration-sidecar-bundle.v0.json +149 -0
- package/contracts/orientation-limits.v1.json +41 -0
- package/contracts/orientation-reason-codes.v1.json +196 -0
- package/contracts/private-template-sources.json +8 -0
- package/contracts/release-ledger.json +4598 -0
- package/contracts/reserved-skill-names.json +13 -0
- package/contracts/runtime-recipe.campaigns-os-node-v1.json +299 -0
- package/contracts/supported-surface.json +180 -0
- package/contracts/template-brand-contract.apollo-mv-single-step.v0.json +27 -0
- package/contracts/template-brand-contract.apollo.v0.json +27 -0
- package/contracts/template-brand-contract.demeter.v0.json +27 -0
- package/contracts/template-brand-contract.olympus-mv-single-step.v0.json +27 -0
- package/contracts/template-brand-contract.olympus-mv-two-step.v0.json +28 -0
- package/contracts/template-brand-contract.olympus.v0.json +27 -0
- package/contracts/template-brand-contract.shared-commerce.v0.json +190 -0
- package/contracts/template-brand-contract.shop-single-step.v0.json +27 -0
- package/contracts/template-brand-contract.shop-three-step.v0.json +29 -0
- package/contracts/template-slot-manifest.apollo-mv-single-step.v0.json +14 -0
- package/contracts/template-slot-manifest.apollo.v0.json +12 -0
- package/contracts/template-slot-manifest.demeter.v0.json +30 -0
- package/contracts/template-slot-manifest.olympus-mv-single-step.v0.json +14 -0
- package/contracts/template-slot-manifest.olympus-mv-two-step.v0.json +15 -0
- package/contracts/template-slot-manifest.olympus.v0.json +12 -0
- package/contracts/template-slot-manifest.shared-content-core.v0.json +4254 -0
- package/contracts/template-slot-manifest.shop-single-step.v0.json +47 -0
- package/contracts/template-slot-manifest.shop-three-step.v0.json +33 -0
- package/docs/brand-theme-bridge.md +159 -0
- package/docs/build-packet.md +1300 -0
- package/docs/campaign-build-brief.md +145 -0
- package/docs/campaign-standardization-report.md +329 -0
- package/docs/campaigns-os-build-flow.md +117 -0
- package/docs/design-source-package.md +784 -0
- package/docs/legacy-migration.md +58 -0
- package/docs/migration-sidecar-bundle.md +139 -0
- package/docs/orientation-contract-reference.md +1220 -0
- package/docs/polish-evidence.md +502 -0
- package/docs/qa-and-test-orders.md +1691 -0
- package/docs/release-ledger-authoring-guide.md +274 -0
- package/docs/runtime-readiness.md +211 -0
- package/docs/supported-surface.md +83 -0
- package/docs/versioning.md +55 -0
- package/docs/workflow-findings-sidecar.md +588 -0
- package/package.json +135 -0
- package/prompts/first-build.md +27 -0
- package/prompts/friction-log.md +30 -0
- package/schemas/campaign-build-brief.v1.schema.json +149 -0
- package/schemas/campaign-design-source-package.v0.schema.json +697 -0
- package/schemas/campaign-runtime-assembly-report.v0.schema.json +390 -0
- package/schemas/campaign-runtime-build-context.v0.schema.json +339 -0
- package/schemas/campaign-runtime-build-packet.v0.schema.json +452 -0
- package/schemas/campaign-spec.v4.schema.json +582 -0
- package/schemas/campaigns-os-doctor-output.v0.schema.json +43 -0
- package/schemas/campaigns-os-legacy-migration-inventory.v0.schema.json +112 -0
- package/schemas/campaigns-os-legacy-provisioning-plan.v0.schema.json +38 -0
- package/schemas/campaigns-os-legacy-provisioning-receipt.v0.schema.json +57 -0
- package/schemas/campaigns-os-qa-verdict-sidecar.v0.schema.json +150 -0
- package/schemas/campaigns-os-qa-verdict.v0.schema.json +438 -0
- package/schemas/campaigns-os-release-ledger.v1.schema.json +162 -0
- package/schemas/campaigns-os-run-record.v0.schema.json +343 -0
- package/schemas/campaigns-os-runtime-recipe.v1.schema.json +313 -0
- package/schemas/campaigns-os-sidecar-bundle-conformance.v0.schema.json +78 -0
- package/schemas/campaigns-os-tooling-orientation.v1.schema.json +381 -0
- package/schemas/campaigns-os-workflow-finding.v0.schema.json +134 -0
- package/schemas/source-html-manifest.v0.schema.json +252 -0
- package/skills/next-campaigns-build/SKILL.md +73 -0
- package/skills/next-campaigns-os/SKILL.md +101 -0
- package/skills/next-campaigns-os/references/session-intake.md +160 -0
- package/skills/next-campaigns-os-setup/SKILL.md +22 -0
- package/skills/next-campaigns-polish/SKILL.md +145 -0
- package/skills/next-campaigns-qa/SKILL.md +92 -0
- package/skills.json +56 -0
- package/skills.sh +64 -0
- package/src/adapter-decision-contract.mjs +333 -0
- package/src/brand-theme.mjs +1151 -0
- package/src/browser-launch.mjs +79 -0
- package/src/build-brief.mjs +781 -0
- package/src/built-site-scope.mjs +312 -0
- package/src/campaign-ecosystem.mjs +734 -0
- package/src/campaign-identity.mjs +405 -0
- package/src/campaign-workspace.mjs +127 -0
- package/src/checkpoint-waiver.mjs +302 -0
- package/src/cli.mjs +13442 -0
- package/src/commercial-journey.mjs +1119 -0
- package/src/commercial-parity.mjs +965 -0
- package/src/consent.mjs +347 -0
- package/src/content-residue.mjs +322 -0
- package/src/deadline.mjs +81 -0
- package/src/design-source-package.mjs +2604 -0
- package/src/deviation.mjs +107 -0
- package/src/doctor-check-registry.mjs +49 -0
- package/src/doctor-sidecar.mjs +106 -0
- package/src/finding-cause.mjs +557 -0
- package/src/findings.mjs +326 -0
- package/src/fs-identity.mjs +68 -0
- package/src/gate-actions.mjs +105 -0
- package/src/html-scan.mjs +53 -0
- package/src/install-mode.mjs +272 -0
- package/src/legacy-migration.d.ts +128 -0
- package/src/legacy-migration.mjs +510 -0
- package/src/lifecycle.mjs +338 -0
- package/src/local-proof.mjs +401 -0
- package/src/map-pin-writeback.mjs +210 -0
- package/src/orchestration-stage-contract.mjs +81 -0
- package/src/package-install-fixture.mjs +33 -0
- package/src/page-kit-build-summary.mjs +175 -0
- package/src/page-kit-campaign-config.mjs +57 -0
- package/src/page-kit-sdk-version.mjs +392 -0
- package/src/page-kit-store-profile.mjs +369 -0
- package/src/page-kit-sync.mjs +162 -0
- package/src/polish-browser.mjs +867 -0
- package/src/polish-capture.mjs +1094 -0
- package/src/polish-deadline.mjs +51 -0
- package/src/polish-gate.mjs +739 -0
- package/src/polish-node.mjs +639 -0
- package/src/polish-page-load.mjs +1100 -0
- package/src/private-template-source.mjs +237 -0
- package/src/proof-policy.mjs +82 -0
- package/src/qa-analytics-correctness.mjs +307 -0
- package/src/qa-analytics-errors.mjs +38 -0
- package/src/qa-analytics-parity.mjs +699 -0
- package/src/qa-binding-evidence.mjs +140 -0
- package/src/qa-browser.mjs +6608 -0
- package/src/qa-cart-entry.mjs +406 -0
- package/src/qa-commercial-parity.mjs +641 -0
- package/src/qa-node.mjs +3620 -0
- package/src/qa-order-bump.mjs +381 -0
- package/src/qa-parity-capture.mjs +428 -0
- package/src/qa-parity-fixture.mjs +359 -0
- package/src/qa-publish.mjs +362 -0
- package/src/qa-purchase-data-layer.mjs +263 -0
- package/src/qa-route-probe.mjs +272 -0
- package/src/qa-sidecar.mjs +188 -0
- package/src/qa-test-order-topology.mjs +207 -0
- package/src/qa-url-privacy.mjs +13 -0
- package/src/qa-verdict-discovery.mjs +192 -0
- package/src/qa-verdict-publish.mjs +105 -0
- package/src/qa-verdict.mjs +287 -0
- package/src/remit.mjs +388 -0
- package/src/repo-scan.mjs +83 -0
- package/src/route-identity.mjs +133 -0
- package/src/run-record-closeout.mjs +229 -0
- package/src/run-record.mjs +839 -0
- package/src/run-session.mjs +226 -0
- package/src/runtime-state-ignore.mjs +113 -0
- package/src/sdk-attribute-index.mjs +212 -0
- package/src/sdk-markup.mjs +358 -0
- package/src/sdk-meta-tags.mjs +52 -0
- package/src/shell-token.mjs +7 -0
- package/src/sidecar-bundle.mjs +399 -0
- package/src/source-asset-crawl.mjs +469 -0
- package/src/source-html-intake.mjs +627 -0
- package/src/source-html-manifest.mjs +276 -0
- package/src/source-prep.mjs +284 -0
- package/src/spec-derive-store.mjs +431 -0
- package/src/spec-derive.mjs +514 -0
- package/src/spec-fetch.mjs +66 -0
- package/src/spec-hash.mjs +48 -0
- package/src/spec-identity.mjs +27 -0
- package/src/stage-ledger.mjs +509 -0
- package/src/standardization-report.mjs +1297 -0
- package/src/template-brand-contract.mjs +473 -0
- package/src/template-freshness.mjs +196 -0
- package/src/template-reference.mjs +81 -0
- package/src/template-slot-manifest.mjs +150 -0
- package/src/text-safety.mjs +62 -0
- package/src/theme-gate.mjs +185 -0
- package/src/upsell-selector-scope.mjs +299 -0
|
@@ -0,0 +1,582 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://nextcommerce.com/schemas/campaign-spec.v4.schema.json",
|
|
4
|
+
"title": "CampaignSpec v4 (4.2–4.3)",
|
|
5
|
+
"description": "The CampaignSpec authoring/export contract, described from the real export surface: a field-union inventory of 33 real CampaignSpec documents (195 pages), including 13 genuine Campaign Map Builder exports. This schema is deliberately PERMISSIVE on unknown fields (additionalProperties stays open everywhere): it names and types the known surface, while rejection of unknown fields is deferred to validation profiles in a later change. Rules in campaign-spec/rules/ own semantic validation (routing completeness, weights, cycles); this schema owns shape. NOTE: some raw API responses wrap the spec in an { ok, data } envelope — this schema describes the spec itself (the .data member), not the envelope.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": true,
|
|
8
|
+
"required": ["schema_version", "funnels"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"schema_version": {
|
|
11
|
+
"enum": ["4.2", "4.3"],
|
|
12
|
+
"description": "Supported CampaignSpec lineage versions. Real corpus: 4.3×18, 4.2×15; no other values observed. v4.1 funnel_pages-only topology is rejected by normalize() (ADR-002)."
|
|
13
|
+
},
|
|
14
|
+
"builder_version": { "type": "string", "description": "Campaign Map Builder version that produced the export (31/33 real specs)." },
|
|
15
|
+
"generated_at": { "type": "string", "description": "ISO timestamp of export generation." },
|
|
16
|
+
"campaign": { "$ref": "#/$defs/campaign" },
|
|
17
|
+
"global_config": {
|
|
18
|
+
"type": "object",
|
|
19
|
+
"additionalProperties": true,
|
|
20
|
+
"properties": {
|
|
21
|
+
"sdk_version": { "type": "string", "description": "CANONICAL home of the campaign-cart SDK pin for the 4.x lineage (present in 33/33 real specs)." }
|
|
22
|
+
},
|
|
23
|
+
"description": "Global build configuration. global_config.sdk_version is the canonical SDK version declaration."
|
|
24
|
+
},
|
|
25
|
+
"runtime": {
|
|
26
|
+
"type": "object",
|
|
27
|
+
"additionalProperties": true,
|
|
28
|
+
"properties": {
|
|
29
|
+
"sdk_version": { "type": "string", "description": "Accepted ALIAS of global_config.sdk_version (seen only in 2 local drafts, always redundant). Prefer global_config.sdk_version." }
|
|
30
|
+
},
|
|
31
|
+
"description": "Accepted alias location for sdk_version. Not part of the Map Builder export surface."
|
|
32
|
+
},
|
|
33
|
+
"funnels": {
|
|
34
|
+
"type": "array",
|
|
35
|
+
"items": { "$ref": "#/$defs/funnel" },
|
|
36
|
+
"description": "Canonical v4.2+ funnel topology. Required — the one structural precondition normalize() enforces (the key must exist as an array). An EMPTY array is structurally valid here by design: mid-edit Map Builder drafts validate structurally, and the FunnelCount rule rejects zero funnels at error severity. Schema owns shape; rules own cardinality."
|
|
37
|
+
},
|
|
38
|
+
"funnel_pages": {
|
|
39
|
+
"type": "array",
|
|
40
|
+
"items": { "$ref": "#/$defs/funnelPageMirror" },
|
|
41
|
+
"description": "Flattened legacy mirror of funnels[].pages[] with per-page _funnel_id/_funnel_name annotations (27/33 real specs; declared 'legacy' by _provenance). funnels[] is authoritative."
|
|
42
|
+
},
|
|
43
|
+
"shipping_methods": {
|
|
44
|
+
"type": "array",
|
|
45
|
+
"items": { "$ref": "#/$defs/shippingMethod" },
|
|
46
|
+
"description": "Campaign-level shipping method catalog (32/33 real specs)."
|
|
47
|
+
},
|
|
48
|
+
"offers": {
|
|
49
|
+
"type": "array",
|
|
50
|
+
"items": { "$ref": "#/$defs/offer" },
|
|
51
|
+
"description": "Root offer catalog. ref_id is the sole offer identity (all 236 real occurrences); package_ref_id does not exist in real exports and is not part of the contract."
|
|
52
|
+
},
|
|
53
|
+
"spec_identity": { "$ref": "#/$defs/specIdentity" },
|
|
54
|
+
"build_scope": { "$ref": "#/$defs/buildScope" },
|
|
55
|
+
"analytics": { "$ref": "#/$defs/analyticsContract" },
|
|
56
|
+
"_provenance": { "$ref": "#/$defs/provenance" },
|
|
57
|
+
"slug": { "type": "string", "description": "Flat mirror of the saved map slug (7/33 real specs carry flat slug/map_id/saved_at mirrors)." },
|
|
58
|
+
"map_id": { "type": "string", "description": "Flat mirror of spec_identity.map_id." },
|
|
59
|
+
"saved_at": { "type": "string", "description": "Flat mirror of spec_identity.saved_at." },
|
|
60
|
+
"deployment": { "type": "object", "additionalProperties": true, "description": "Local-draft-only extension (2 specs); not a Map Builder export field." },
|
|
61
|
+
"draft": { "type": ["boolean", "object"], "description": "Local-draft-only extension (2 specs)." },
|
|
62
|
+
"draft_notes": { "type": ["string", "array", "object"], "description": "Local-draft-only extension (2 specs)." },
|
|
63
|
+
"figma_url": { "type": ["string", "null"], "description": "Ops-authored design pointer (declared ops-owned by _provenance)." }
|
|
64
|
+
},
|
|
65
|
+
"$defs": {
|
|
66
|
+
"campaign": {
|
|
67
|
+
"type": "object",
|
|
68
|
+
"additionalProperties": true,
|
|
69
|
+
"properties": {
|
|
70
|
+
"ref_id": { "type": ["number", "string"], "description": "Numeric platform campaign id (33/33 real specs)." },
|
|
71
|
+
"id": { "type": "string", "description": "Campaign slug-style identifier (28/33 real specs)." },
|
|
72
|
+
"name": { "type": "string" },
|
|
73
|
+
"slug": { "type": "string" },
|
|
74
|
+
"currency": { "type": "string" },
|
|
75
|
+
"language": { "type": "string" },
|
|
76
|
+
"payment_env_key": { "type": "string" },
|
|
77
|
+
"campaigns_api_key": { "type": ["string", "null"], "description": "Public-by-design, domain-allowlisted Campaigns API key (32/33 real specs)." },
|
|
78
|
+
"available_payment_methods": { "type": "array" },
|
|
79
|
+
"available_express_payment_methods": { "type": "array" },
|
|
80
|
+
"available_currencies": { "type": "array", "items": { "type": "string" } },
|
|
81
|
+
"available_shipping_countries": {
|
|
82
|
+
"description": "Arrives in THREE incompatible shapes in real exports: bare string \"all\" (5 specs), an array of country-code strings incl. [] (22+), and an array of { code, label } objects (5). All three are accepted here; normalization to one canonical shape is deliberately deferred to a later change.",
|
|
83
|
+
"anyOf": [
|
|
84
|
+
{ "const": "all" },
|
|
85
|
+
{
|
|
86
|
+
"type": "array",
|
|
87
|
+
"items": { "type": "string" },
|
|
88
|
+
"not": { "contains": { "const": "all" } }
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"type": "array",
|
|
92
|
+
"items": {
|
|
93
|
+
"type": "object",
|
|
94
|
+
"additionalProperties": true,
|
|
95
|
+
"required": ["code"],
|
|
96
|
+
"properties": {
|
|
97
|
+
"code": { "type": "string" },
|
|
98
|
+
"label": { "type": "string" }
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
]
|
|
103
|
+
},
|
|
104
|
+
"tracking": {
|
|
105
|
+
"type": "object",
|
|
106
|
+
"additionalProperties": true,
|
|
107
|
+
"properties": {
|
|
108
|
+
"status": { "type": "string" },
|
|
109
|
+
"providers": { "type": "object" }
|
|
110
|
+
},
|
|
111
|
+
"description": "Tracking readback block (23/33 real specs): { status, providers }."
|
|
112
|
+
},
|
|
113
|
+
"preferred_template_family": { "type": ["string", "null"], "description": "HINT naming the starter template family; build-time template lock still decides (10/33 real specs, null-valued in others)." },
|
|
114
|
+
"allowed_domains": { "type": "array", "items": { "type": "string" }, "description": "Domain allowlist for the Campaigns API key (2/33 real specs; ops-authored)." },
|
|
115
|
+
"route_root": { "type": ["string", "null"], "description": "Public route root; '/' declares a root-served campaign. Authoring extension — see campaign-spec/types.ts." },
|
|
116
|
+
"store_url": { "type": ["string", "null"] },
|
|
117
|
+
"store_name": { "type": ["string", "null"] },
|
|
118
|
+
"store_contact": { "type": ["string", "null"] },
|
|
119
|
+
"store_terms": { "type": ["string", "null"] },
|
|
120
|
+
"store_shipping": { "type": ["string", "null"] },
|
|
121
|
+
"store_privacy": { "type": ["string", "null"] },
|
|
122
|
+
"store_returns": { "type": ["string", "null"] },
|
|
123
|
+
"store_phone": { "type": ["string", "null"], "description": "Human-readable display phone. See store_phone_tel for the tel: URI." },
|
|
124
|
+
"store_phone_tel": { "type": ["string", "null"], "description": "tel:-prefixed phone URI for Call-us CTAs; distinct from the display string store_phone." },
|
|
125
|
+
"footer_links": {
|
|
126
|
+
"type": "array",
|
|
127
|
+
"items": {
|
|
128
|
+
"type": "object",
|
|
129
|
+
"additionalProperties": true,
|
|
130
|
+
"properties": {
|
|
131
|
+
"label": { "type": "string" },
|
|
132
|
+
"url": { "type": "string" },
|
|
133
|
+
"required": { "type": "boolean" }
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
"description": "Ops-authored footer link roster (declared ops-owned by _provenance)."
|
|
137
|
+
},
|
|
138
|
+
"seo": { "type": "object", "additionalProperties": true, "description": "Ops-authored SEO block (declared ops-owned by _provenance)." }
|
|
139
|
+
},
|
|
140
|
+
"description": "Campaign identity + store profile. The store_* block (store_url/name/contact/terms/shipping/privacy/returns/phone/phone_tel) appears on 15–22 of 33 real specs, null-valued when unset."
|
|
141
|
+
},
|
|
142
|
+
"funnel": {
|
|
143
|
+
"type": "object",
|
|
144
|
+
"additionalProperties": true,
|
|
145
|
+
"required": ["id"],
|
|
146
|
+
"properties": {
|
|
147
|
+
"id": { "type": "string" },
|
|
148
|
+
"name": { "type": "string" },
|
|
149
|
+
"hypothesis": { "type": "string" },
|
|
150
|
+
"weight": { "type": "number" },
|
|
151
|
+
"pages": { "type": "array", "items": { "$ref": "#/$defs/page" } },
|
|
152
|
+
"promo_codes": { "type": "array", "items": { "$ref": "#/$defs/promoCode" } }
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
"page": {
|
|
156
|
+
"type": "object",
|
|
157
|
+
"additionalProperties": true,
|
|
158
|
+
"required": ["id", "type"],
|
|
159
|
+
"properties": {
|
|
160
|
+
"id": { "type": "string" },
|
|
161
|
+
"type": {
|
|
162
|
+
"enum": ["presell", "landing", "select", "checkout", "upsell", "downsell", "thankyou"],
|
|
163
|
+
"description": "Authoring page type. 'thankyou' is the canonical terminal page type (33/33 real specs); 'receipt' is the SDK-layer projection, expressed via sdk_hints.sdk_page_type and sdk_hints.meta_tags['next-page-type'], never as page.type. 'select' is the bundle-selection step of a two-step family — a template-owned commerce page that routes forward like a landing page but carries SDK cart selection, so commerce gates apply to it and not to 'landing'. Distinct from the page ID \"select\", which is a separate namespace."
|
|
164
|
+
},
|
|
165
|
+
"order": { "type": "number" },
|
|
166
|
+
"label": { "type": "string" },
|
|
167
|
+
"is_entry": { "type": "boolean", "description": "True on funnel entry pages (178/195 real pages carry the flag)." },
|
|
168
|
+
"page_url": { "type": "string", "description": "Authored route field: usually a route path like 'checkout/' (137 of 170 occurrences), sometimes empty, a bare token, or a legacy .html filename." },
|
|
169
|
+
"next_page": { "type": "string", "description": "PAGE ID of the next page — 100% of real occurrences hold page ids, never routes. Route paths live in resolved_routing." },
|
|
170
|
+
"on_accept": { "type": "string", "description": "PAGE ID routed to on upsell accept. Meaningful only on a page that presents an accept/decline offer (type 'upsell' or 'downsell'); on any other page type there is no offer to accept, so it is ignored for routing." },
|
|
171
|
+
"on_decline": { "type": "string", "description": "PAGE ID routed to on upsell decline." },
|
|
172
|
+
"success_url": { "type": "string", "description": "PAGE ID routed to on checkout success. Despite the name, this never holds a URL in real exports (33/33 occurrences are page ids). Meaningful only on a page that takes payment (type 'checkout'); on any other page type there is no payment success to route from, so it is ignored for routing and next_page wins."},
|
|
173
|
+
"_next_label": { "type": ["string", "null"], "description": "Builder-side label shadow of next_page (underscore-prefixed keys are builder annotations)." },
|
|
174
|
+
"_accept_label": { "type": ["string", "null"] },
|
|
175
|
+
"_decline_label": { "type": ["string", "null"] },
|
|
176
|
+
"_success_label": { "type": ["string", "null"] },
|
|
177
|
+
"resolved_routing": { "$ref": "#/$defs/resolvedRouting" },
|
|
178
|
+
"sdk_hints": { "$ref": "#/$defs/sdkHints" },
|
|
179
|
+
"packages": { "type": "array", "items": { "$ref": "#/$defs/pagePackage" } },
|
|
180
|
+
"offers": { "type": "array", "items": { "$ref": "#/$defs/pageOffer" } },
|
|
181
|
+
"design_hooks": { "$ref": "#/$defs/designHooks" },
|
|
182
|
+
"design_source": { "$ref": "#/$defs/designSource" },
|
|
183
|
+
"exit_intent": { "$ref": "#/$defs/exitIntent" },
|
|
184
|
+
"promo_code_input": { "$ref": "#/$defs/promoCodeInput" },
|
|
185
|
+
"upsell_template_pattern": { "type": "string", "description": "Per-page UI variant hint (authoring extension; see campaign-spec/types.ts)." },
|
|
186
|
+
"upsell_mv_tiers": { "$ref": "#/$defs/upsellMvTiers" },
|
|
187
|
+
"variant_labels": { "$ref": "#/$defs/variantLabels" },
|
|
188
|
+
"template": { "type": "string", "description": "Source template path. Hand-authored-spec field only (3 specs) — not a Map Builder export field." },
|
|
189
|
+
"notes": { "type": ["string", "null"] },
|
|
190
|
+
"custom_fields": { "type": "object", "additionalProperties": true }
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
"funnelPageMirror": {
|
|
194
|
+
"type": "object",
|
|
195
|
+
"allOf": [{ "$ref": "#/$defs/page" }],
|
|
196
|
+
"properties": {
|
|
197
|
+
"_funnel_id": { "type": "string" },
|
|
198
|
+
"_funnel_name": { "type": "string" }
|
|
199
|
+
},
|
|
200
|
+
"description": "funnel_pages[] mirror entry: a page plus the _funnel_id/_funnel_name annotations linking it back to its funnel."
|
|
201
|
+
},
|
|
202
|
+
"resolvedRouting": {
|
|
203
|
+
"type": "object",
|
|
204
|
+
"additionalProperties": true,
|
|
205
|
+
"properties": {
|
|
206
|
+
"accept": { "type": "string", "description": "Resolved PAGE ID for on_accept." },
|
|
207
|
+
"decline": { "type": "string", "description": "Resolved PAGE ID for on_decline." },
|
|
208
|
+
"success": { "type": "string", "description": "Resolved PAGE ID for success_url. Like the declared field, meaningful only on a page that takes payment (type 'checkout'); the exporter may still emit it elsewhere, where routing ignores it." },
|
|
209
|
+
"next_page": { "type": "string", "description": "Resolved PAGE ID for next_page." },
|
|
210
|
+
"accept_route": { "type": "string", "description": "Trailing-slash route path for accept." },
|
|
211
|
+
"decline_route": { "type": "string" },
|
|
212
|
+
"success_route": { "type": "string" },
|
|
213
|
+
"next_page_route": { "type": "string" },
|
|
214
|
+
"accept_filename": { "type": "string", "description": "Route path or legacy .html filename for accept." },
|
|
215
|
+
"decline_filename": { "type": "string" },
|
|
216
|
+
"success_filename": { "type": "string" },
|
|
217
|
+
"next_page_filename": { "type": "string" }
|
|
218
|
+
},
|
|
219
|
+
"description": "DERIVED routing projection (135/195 real pages): page-id fields resolved to route paths (*_route) and filenames (*_filename). The declared routing fields (next_page/on_accept/on_decline/success_url) stay page-ids; this object is where route paths live."
|
|
220
|
+
},
|
|
221
|
+
"sdkHints": {
|
|
222
|
+
"type": "object",
|
|
223
|
+
"additionalProperties": true,
|
|
224
|
+
"properties": {
|
|
225
|
+
"sdk_page_type": {
|
|
226
|
+
"enum": ["product", "checkout", "upsell", "receipt"],
|
|
227
|
+
"description": "SDK-layer page type projection. Observed values across the real corpus. A page.type of 'thankyou' projects to 'receipt' here."
|
|
228
|
+
},
|
|
229
|
+
"meta_tags": {
|
|
230
|
+
"type": "object",
|
|
231
|
+
"additionalProperties": { "type": "string" },
|
|
232
|
+
"description": "SDK meta tags for the page. Observed keys: next-page-type, next-currency, next-upsell-accept-url, next-upsell-decline-url, next-success-url, next-prevent-back-navigation, next-predictive-address, next-funnel, next-api-key, next-spreedly-key, next-analytics-view-item."
|
|
233
|
+
},
|
|
234
|
+
"frontmatter": {
|
|
235
|
+
"type": "object",
|
|
236
|
+
"additionalProperties": true,
|
|
237
|
+
"description": "TEMPLATE-HANDOFF EXTENSION (not a Map Builder export field): starter-template frontmatter mapping used by the contracts/fixtures/campaign-specs agent-contract fixtures to document how spec refs land in template frontmatter."
|
|
238
|
+
},
|
|
239
|
+
"template_family": {
|
|
240
|
+
"type": "string",
|
|
241
|
+
"description": "TEMPLATE-HANDOFF EXTENSION (not a Map Builder export field): starter-template family the fixture page maps to; must match the commerce-surface-catalog family that references the fixture."
|
|
242
|
+
}
|
|
243
|
+
},
|
|
244
|
+
"description": "Real export subkeys are sdk_page_type + meta_tags ONLY; frontmatter and template_family are blessed template-handoff extensions carried by the agent-contract fixtures."
|
|
245
|
+
},
|
|
246
|
+
"pagePackage": {
|
|
247
|
+
"type": "object",
|
|
248
|
+
"additionalProperties": true,
|
|
249
|
+
"properties": {
|
|
250
|
+
"ref_id": { "type": ["string", "number"] },
|
|
251
|
+
"qty": { "type": "number", "description": "Package quantity. The real export key is qty (206/211 real package entries) — NOT quantity." },
|
|
252
|
+
"name": { "type": ["string", "null"] },
|
|
253
|
+
"price": { "type": ["string", "number", "null"] },
|
|
254
|
+
"price_retail": { "type": ["string", "number", "null"] },
|
|
255
|
+
"product_name": { "type": ["string", "null"] },
|
|
256
|
+
"product_sku": { "type": ["string", "null"] },
|
|
257
|
+
"product_variant_name": { "type": ["string", "null"] },
|
|
258
|
+
"product_purchase_availability": { "type": ["string", "null"] },
|
|
259
|
+
"product_inventory_availability": { "type": ["string", "null"] },
|
|
260
|
+
"image": { "type": ["string", "null"] },
|
|
261
|
+
"is_upsell": { "type": "boolean", "description": "Boolean role flag. There is no 'role' field in real exports — role is expressed by the is_upsell/is_order_bump/default_selected boolean trio." },
|
|
262
|
+
"is_order_bump": { "type": "boolean" },
|
|
263
|
+
"default_selected": { "type": "boolean" },
|
|
264
|
+
"configurable": { "type": "boolean", "description": "Fixture/authoring extension marking quantity-configurable package rows." },
|
|
265
|
+
"variant_attributes": {
|
|
266
|
+
"type": "array",
|
|
267
|
+
"items": {
|
|
268
|
+
"type": "object",
|
|
269
|
+
"additionalProperties": true,
|
|
270
|
+
"properties": {
|
|
271
|
+
"code": { "type": "string" },
|
|
272
|
+
"name": { "type": "string" },
|
|
273
|
+
"value": { "type": "string" }
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
},
|
|
277
|
+
"is_recurring": { "type": "boolean" },
|
|
278
|
+
"price_recurring": { "type": ["string", "number", "null"] },
|
|
279
|
+
"interval": { "type": ["string", "null"] },
|
|
280
|
+
"interval_count": { "type": ["number", "null"] }
|
|
281
|
+
}
|
|
282
|
+
},
|
|
283
|
+
"pageOffer": {
|
|
284
|
+
"type": "object",
|
|
285
|
+
"additionalProperties": true,
|
|
286
|
+
"required": ["ref_id"],
|
|
287
|
+
"properties": {
|
|
288
|
+
"ref_id": { "type": ["string", "number"], "description": "Sole offer identity, referencing the root offers[] catalog (all 236 real offer occurrences use ref_id)." },
|
|
289
|
+
"name": { "type": ["string", "null"] },
|
|
290
|
+
"type": { "type": "string" },
|
|
291
|
+
"code": { "type": ["string", "null"], "description": "Voucher code; often null in real exports." },
|
|
292
|
+
"condition": { "$ref": "#/$defs/offerCondition" },
|
|
293
|
+
"benefit": { "$ref": "#/$defs/offerBenefit" }
|
|
294
|
+
}
|
|
295
|
+
},
|
|
296
|
+
"offer": {
|
|
297
|
+
"type": "object",
|
|
298
|
+
"additionalProperties": true,
|
|
299
|
+
"required": ["ref_id"],
|
|
300
|
+
"properties": {
|
|
301
|
+
"ref_id": { "type": ["string", "number"], "description": "Sole offer identity (all 236 real occurrences: ref_id + code (often null) + name). package_ref_id never appears in real exports and is dropped from the contract." },
|
|
302
|
+
"name": { "type": ["string", "null"] },
|
|
303
|
+
"type": { "type": "string" },
|
|
304
|
+
"code": { "type": ["string", "null"] },
|
|
305
|
+
"condition": { "$ref": "#/$defs/offerCondition" },
|
|
306
|
+
"benefit": { "$ref": "#/$defs/offerBenefit" },
|
|
307
|
+
"packages": {
|
|
308
|
+
"type": "array",
|
|
309
|
+
"items": {
|
|
310
|
+
"type": "object",
|
|
311
|
+
"additionalProperties": true,
|
|
312
|
+
"properties": {
|
|
313
|
+
"package_id": { "type": ["number", "string"] },
|
|
314
|
+
"package_name": { "type": ["string", "null"] },
|
|
315
|
+
"package_image": { "type": ["string", "null"] },
|
|
316
|
+
"product_name": { "type": ["string", "null"] },
|
|
317
|
+
"product_variant_name": { "type": ["string", "null"] },
|
|
318
|
+
"unit_price": { "type": ["string", "number", "null"] },
|
|
319
|
+
"unit_price_before_discount": { "type": ["string", "number", "null"] },
|
|
320
|
+
"package_price": { "type": ["string", "number", "null"] },
|
|
321
|
+
"package_price_before_discount": { "type": ["string", "number", "null"] },
|
|
322
|
+
"package_unit_qty": { "type": ["number", "null"] }
|
|
323
|
+
}
|
|
324
|
+
},
|
|
325
|
+
"description": "Packages the offer applies to, nested with package_id identity."
|
|
326
|
+
},
|
|
327
|
+
"shipping_methods": {
|
|
328
|
+
"type": "array",
|
|
329
|
+
"items": { "$ref": "#/$defs/shippingMethod" },
|
|
330
|
+
"description": "Offer-scoped shipping method pricing."
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
},
|
|
334
|
+
"offerCondition": {
|
|
335
|
+
"type": "object",
|
|
336
|
+
"additionalProperties": true,
|
|
337
|
+
"properties": {
|
|
338
|
+
"type": { "type": "string" },
|
|
339
|
+
"value": { "type": ["number", "string", "null"] },
|
|
340
|
+
"description": { "type": ["string", "null"] }
|
|
341
|
+
}
|
|
342
|
+
},
|
|
343
|
+
"offerBenefit": {
|
|
344
|
+
"type": "object",
|
|
345
|
+
"additionalProperties": true,
|
|
346
|
+
"properties": {
|
|
347
|
+
"type": { "type": "string" },
|
|
348
|
+
"value": { "type": ["number", "string", "null"] },
|
|
349
|
+
"description": { "type": ["string", "null"] }
|
|
350
|
+
}
|
|
351
|
+
},
|
|
352
|
+
"shippingMethod": {
|
|
353
|
+
"type": "object",
|
|
354
|
+
"additionalProperties": true,
|
|
355
|
+
"properties": {
|
|
356
|
+
"ref_id": { "type": ["string", "number"] },
|
|
357
|
+
"code": { "type": ["string", "null"] },
|
|
358
|
+
"key": { "type": ["string", "null"] },
|
|
359
|
+
"name": { "type": ["string", "null"] },
|
|
360
|
+
"price": { "type": ["string", "number", "null"] },
|
|
361
|
+
"price_before_discount": { "type": ["string", "number", "null"] }
|
|
362
|
+
}
|
|
363
|
+
},
|
|
364
|
+
"specIdentity": {
|
|
365
|
+
"type": "object",
|
|
366
|
+
"additionalProperties": true,
|
|
367
|
+
"properties": {
|
|
368
|
+
"source": { "type": "string", "description": "Observed values: campaign-map-builder, hand-authored-simulation, local-experimental." },
|
|
369
|
+
"map_id": { "type": "string" },
|
|
370
|
+
"id": { "type": "string" },
|
|
371
|
+
"map_url": { "type": "string" },
|
|
372
|
+
"edit_url": { "type": "string" },
|
|
373
|
+
"spec_url": { "type": "string" },
|
|
374
|
+
"spec_hash": { "type": "string" },
|
|
375
|
+
"saved_at": { "type": "string" },
|
|
376
|
+
"public_route_slug": { "type": "string" },
|
|
377
|
+
"variant_slug": { "type": "string" },
|
|
378
|
+
"template_family": { "type": "string" },
|
|
379
|
+
"derived_from": { "type": "string" },
|
|
380
|
+
"authority": { "type": "string" }
|
|
381
|
+
},
|
|
382
|
+
"description": "Saved Map Builder identity block (26/33 real specs)."
|
|
383
|
+
},
|
|
384
|
+
"buildScope": {
|
|
385
|
+
"type": "object",
|
|
386
|
+
"additionalProperties": true,
|
|
387
|
+
"properties": {
|
|
388
|
+
"mode": { "enum": ["partial", "full"] },
|
|
389
|
+
"reasons": { "type": "array", "items": { "type": "string" } }
|
|
390
|
+
},
|
|
391
|
+
"description": "Ops-authored build scope declaration (16/33 real specs)."
|
|
392
|
+
},
|
|
393
|
+
"provenance": {
|
|
394
|
+
"type": "object",
|
|
395
|
+
"additionalProperties": true,
|
|
396
|
+
"properties": {
|
|
397
|
+
"ops": { "type": "array", "items": { "type": "string" } },
|
|
398
|
+
"api": { "type": "array", "items": { "type": "string" } },
|
|
399
|
+
"derived": { "type": "array", "items": { "type": "string" } },
|
|
400
|
+
"legacy": { "type": "array", "items": { "type": "string" } }
|
|
401
|
+
},
|
|
402
|
+
"description": "Declares which JSON paths are ops-owned vs api-owned vs derived vs legacy (27/33 real specs)."
|
|
403
|
+
},
|
|
404
|
+
"analyticsContract": {
|
|
405
|
+
"type": "object",
|
|
406
|
+
"additionalProperties": true,
|
|
407
|
+
"properties": {
|
|
408
|
+
"mode": { "enum": ["auto", "manual", "disabled"] },
|
|
409
|
+
"enabled": { "type": "boolean" },
|
|
410
|
+
"providers": {
|
|
411
|
+
"type": "object",
|
|
412
|
+
"additionalProperties": {
|
|
413
|
+
"type": "object",
|
|
414
|
+
"additionalProperties": true,
|
|
415
|
+
"properties": {
|
|
416
|
+
"enabled": { "type": "boolean" },
|
|
417
|
+
"containerId": { "type": "string" },
|
|
418
|
+
"pixelId": { "type": "string" },
|
|
419
|
+
"endpoint": { "type": "string" },
|
|
420
|
+
"transform": { "type": "string" },
|
|
421
|
+
"blockedEvents": { "type": "array", "items": { "type": "string" } }
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
},
|
|
425
|
+
"out_of_band_pixels": {
|
|
426
|
+
"type": "array",
|
|
427
|
+
"items": {
|
|
428
|
+
"type": "object",
|
|
429
|
+
"additionalProperties": true,
|
|
430
|
+
"properties": {
|
|
431
|
+
"vendor": { "type": "string" },
|
|
432
|
+
"loaded_via": { "type": "string" },
|
|
433
|
+
"id": { "type": "string" }
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
},
|
|
437
|
+
"manual_events": {
|
|
438
|
+
"type": "array",
|
|
439
|
+
"items": {
|
|
440
|
+
"type": "object",
|
|
441
|
+
"additionalProperties": true,
|
|
442
|
+
"properties": {
|
|
443
|
+
"event": { "type": "string" },
|
|
444
|
+
"page": { "type": "string" },
|
|
445
|
+
"trigger": { "type": "string" }
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
},
|
|
449
|
+
"utmTransfer": {
|
|
450
|
+
"type": "object",
|
|
451
|
+
"additionalProperties": true,
|
|
452
|
+
"properties": {
|
|
453
|
+
"enabled": { "type": "boolean" },
|
|
454
|
+
"applyToExternalLinks": { "type": "boolean" },
|
|
455
|
+
"paramsToCopy": { "type": "array", "items": { "type": "string" } },
|
|
456
|
+
"excludedDomains": { "type": "array", "items": { "type": "string" } }
|
|
457
|
+
}
|
|
458
|
+
},
|
|
459
|
+
"params": {
|
|
460
|
+
"type": "object",
|
|
461
|
+
"additionalProperties": true,
|
|
462
|
+
"properties": {
|
|
463
|
+
"content": {
|
|
464
|
+
"type": "array",
|
|
465
|
+
"items": {
|
|
466
|
+
"type": "object",
|
|
467
|
+
"additionalProperties": true,
|
|
468
|
+
"properties": {
|
|
469
|
+
"name": { "type": "string" },
|
|
470
|
+
"hides": { "type": "string" },
|
|
471
|
+
"pages": { "type": "array", "items": { "type": "string" } }
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
},
|
|
475
|
+
"tracking": {
|
|
476
|
+
"type": "object",
|
|
477
|
+
"additionalProperties": true,
|
|
478
|
+
"properties": {
|
|
479
|
+
"preserve": { "type": "array", "items": { "type": "string" } },
|
|
480
|
+
"across": { "type": "array", "items": { "type": "string" } },
|
|
481
|
+
"click_id": {
|
|
482
|
+
"type": "object",
|
|
483
|
+
"additionalProperties": true,
|
|
484
|
+
"properties": {
|
|
485
|
+
"inbound": { "type": "string" },
|
|
486
|
+
"maps_to": { "type": "string" }
|
|
487
|
+
}
|
|
488
|
+
},
|
|
489
|
+
"external_trackers": { "type": "array", "items": { "type": "string" } }
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
},
|
|
495
|
+
"description": "Analytics & attribution contract (3/33 real specs; optional). Mirrors the AnalyticsContract type in campaign-spec/types.ts."
|
|
496
|
+
},
|
|
497
|
+
"designHooks": {
|
|
498
|
+
"type": "object",
|
|
499
|
+
"additionalProperties": true,
|
|
500
|
+
"properties": {
|
|
501
|
+
"figma_frame_url": { "type": ["string", "null"] },
|
|
502
|
+
"component_slots": { "type": ["object", "array", "null"] }
|
|
503
|
+
},
|
|
504
|
+
"description": "Per-page design pointers (93/195 real pages): { figma_frame_url, component_slots }."
|
|
505
|
+
},
|
|
506
|
+
"designSource": {
|
|
507
|
+
"type": "object",
|
|
508
|
+
"additionalProperties": true,
|
|
509
|
+
"properties": {
|
|
510
|
+
"type": { "type": "string" },
|
|
511
|
+
"file_url": { "type": "string" },
|
|
512
|
+
"breakpoints": {
|
|
513
|
+
"type": "object",
|
|
514
|
+
"additionalProperties": true,
|
|
515
|
+
"properties": {
|
|
516
|
+
"desktop": { "type": "string" },
|
|
517
|
+
"tablet": { "type": "string" },
|
|
518
|
+
"mobile": { "type": "string" }
|
|
519
|
+
}
|
|
520
|
+
},
|
|
521
|
+
"notes": { "type": "string" }
|
|
522
|
+
},
|
|
523
|
+
"description": "Pointer to the design artifact supplying prepared HTML (authoring extension; see campaign-spec/types.ts)."
|
|
524
|
+
},
|
|
525
|
+
"exitIntent": {
|
|
526
|
+
"type": "object",
|
|
527
|
+
"additionalProperties": true,
|
|
528
|
+
"properties": {
|
|
529
|
+
"enabled": { "type": "boolean" },
|
|
530
|
+
"offer_ref_id": { "type": ["string", "number"] },
|
|
531
|
+
"offer_code": { "type": "string" }
|
|
532
|
+
}
|
|
533
|
+
},
|
|
534
|
+
"promoCodeInput": {
|
|
535
|
+
"type": "object",
|
|
536
|
+
"additionalProperties": true,
|
|
537
|
+
"properties": {
|
|
538
|
+
"enabled": { "type": "boolean" },
|
|
539
|
+
"mode": { "type": "string" },
|
|
540
|
+
"offer_ref_id": { "type": ["string", "number"] },
|
|
541
|
+
"offer_code": { "type": "string" }
|
|
542
|
+
}
|
|
543
|
+
},
|
|
544
|
+
"promoCode": {
|
|
545
|
+
"type": "object",
|
|
546
|
+
"additionalProperties": true,
|
|
547
|
+
"required": ["id", "code"],
|
|
548
|
+
"description": "Authored per-funnel promo roster (campaigns-os Slice 4c) — NOT a Map Builder export field, so corpus evidence does not apply. id + code are the contract's required identity pair, enforced at rule level by PromoCodesShape (empty/duplicate checks); the schema mirrors that contract.",
|
|
549
|
+
"properties": {
|
|
550
|
+
"id": { "type": "string" },
|
|
551
|
+
"code": { "type": "string" },
|
|
552
|
+
"starts_at": { "type": "string" },
|
|
553
|
+
"ends_at": { "type": "string" },
|
|
554
|
+
"title": { "type": "string" },
|
|
555
|
+
"emoji": { "type": "string" },
|
|
556
|
+
"offer1": { "type": "string" },
|
|
557
|
+
"offer2": { "type": "string" },
|
|
558
|
+
"top_bar_bg": { "type": "string" },
|
|
559
|
+
"highlight_color": { "type": "string" },
|
|
560
|
+
"banner_text": { "type": "string" },
|
|
561
|
+
"banner_text_sec": { "type": "string" },
|
|
562
|
+
"limited_time": { "type": "string" }
|
|
563
|
+
}
|
|
564
|
+
},
|
|
565
|
+
"upsellMvTiers": {
|
|
566
|
+
"type": "object",
|
|
567
|
+
"additionalProperties": true,
|
|
568
|
+
"properties": {
|
|
569
|
+
"min": { "type": "number" },
|
|
570
|
+
"max": { "type": "number" }
|
|
571
|
+
}
|
|
572
|
+
},
|
|
573
|
+
"variantLabels": {
|
|
574
|
+
"type": "object",
|
|
575
|
+
"additionalProperties": true,
|
|
576
|
+
"properties": {
|
|
577
|
+
"primary": { "type": "string" },
|
|
578
|
+
"secondary": { "type": "string" }
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://nextcommerce.com/schemas/campaigns-os-doctor-output.v0.schema.json",
|
|
4
|
+
"title": "Campaigns OS Doctor Output v0",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": true,
|
|
7
|
+
"required": [
|
|
8
|
+
"schema_version",
|
|
9
|
+
"generated_at",
|
|
10
|
+
"ok",
|
|
11
|
+
"status",
|
|
12
|
+
"errors",
|
|
13
|
+
"warnings",
|
|
14
|
+
"ready",
|
|
15
|
+
"derived",
|
|
16
|
+
"next"
|
|
17
|
+
],
|
|
18
|
+
"properties": {
|
|
19
|
+
"schema_version": { "const": "campaigns-os-doctor-output/v0" },
|
|
20
|
+
"generated_at": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$"
|
|
23
|
+
},
|
|
24
|
+
"generated_by": {
|
|
25
|
+
"type": "string",
|
|
26
|
+
"minLength": 1,
|
|
27
|
+
"description": "The campaigns-os command that persisted this sidecar (doctor, next, start, build, qa run). Optional: sidecars written before the stamp existed carry no producer."
|
|
28
|
+
},
|
|
29
|
+
"ok": { "type": "boolean" },
|
|
30
|
+
"status": {
|
|
31
|
+
"enum": ["ready", "ready_with_warnings", "ready_with_waivers", "blocked"]
|
|
32
|
+
},
|
|
33
|
+
"errors": { "type": "array" },
|
|
34
|
+
"warnings": { "type": "array" },
|
|
35
|
+
"ready": { "type": "array" },
|
|
36
|
+
"derived": { "type": "object" },
|
|
37
|
+
"next": { "type": ["object", "null"] },
|
|
38
|
+
"stale": { "type": "boolean" },
|
|
39
|
+
"stale_marked_by": { "type": ["string", "null"] },
|
|
40
|
+
"stale_marked_at": { "type": "string" },
|
|
41
|
+
"stale_reason": { "type": "string" }
|
|
42
|
+
}
|
|
43
|
+
}
|