@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,58 @@
|
|
|
1
|
+
# Legacy migration contract
|
|
2
|
+
|
|
3
|
+
`@nextcommerce/campaigns-os/legacy-migration` is the portable contract for
|
|
4
|
+
planning a bounded Campaign Cart SDK 0.3.x to 0.4.x shadow-campaign migration.
|
|
5
|
+
It does not connect to a store or authorize a write.
|
|
6
|
+
|
|
7
|
+
The v0 contract includes three schemas:
|
|
8
|
+
|
|
9
|
+
- `campaigns-os-legacy-migration-inventory/v0` captures an exact source
|
|
10
|
+
campaign, unit-product package identities, shipping methods, wire-ready
|
|
11
|
+
Offer intents, and authorized-domain intents.
|
|
12
|
+
- `campaigns-os-legacy-provisioning-plan/v0` records the stable preview and its
|
|
13
|
+
campaign/package/shipping operations. Offer rows remain keyed intents until
|
|
14
|
+
package IDs exist at apply time.
|
|
15
|
+
- `campaigns-os-legacy-provisioning-receipt/v0` records resource IDs and
|
|
16
|
+
readback evidence, including one `offer.create` row per applied intent.
|
|
17
|
+
|
|
18
|
+
## Safety boundary
|
|
19
|
+
|
|
20
|
+
The contract contains no Admin API token, authenticated transport, session,
|
|
21
|
+
write executor, audit-store implementation, receipt store, rollback, or delete
|
|
22
|
+
operation. Inventory and plan inputs reject credential-like field names
|
|
23
|
+
recursively. Receipts may retain the public campaign `api_key` returned by the
|
|
24
|
+
Admin API, but reject private credential fields; their build-evidence projection
|
|
25
|
+
removes raw readback entirely. Execution is owned by the connector and must
|
|
26
|
+
retain read-before-write, explicit preview and apply, read-after-write, audit,
|
|
27
|
+
durable receipt, and stop-on-ambiguity rules.
|
|
28
|
+
|
|
29
|
+
Package rows identify exactly one product variant. Quantity tiers, vouchers,
|
|
30
|
+
and post-purchase pricing are Offers, never duplicate or quantity-shaped
|
|
31
|
+
packages. The upstream Offers API supports `all_packages`, but this migration
|
|
32
|
+
contract deliberately refuses it: a migration Offer must list stable package
|
|
33
|
+
keys and resolve those keys to IDs immediately before apply.
|
|
34
|
+
|
|
35
|
+
## Offer application
|
|
36
|
+
|
|
37
|
+
`buildLegacyOfferRequest(intent, packageIdByKey)` produces the documented
|
|
38
|
+
Offers create body. It refuses unresolved keys and emits `package_ids`; it does
|
|
39
|
+
not leak local `intent_key` or `package_keys` into the request.
|
|
40
|
+
|
|
41
|
+
The API read shape is not the write shape. Offer `package_ids` read back under
|
|
42
|
+
`condition.packages[]`, while package `price` reads back under `prices[]`.
|
|
43
|
+
`compareLegacyOfferReadback` and `compareLegacyPackageReadback` project those
|
|
44
|
+
known differences. If a field cannot be projected, they return
|
|
45
|
+
`unprojectable`; they never infer or guess a value. Package price comparison
|
|
46
|
+
therefore requires the campaign currency.
|
|
47
|
+
|
|
48
|
+
## Determinism and evidence
|
|
49
|
+
|
|
50
|
+
`normalizeLegacyMigrationInventory` sorts packages, shipping methods, Offers,
|
|
51
|
+
Offer package keys, and domains by their logical keys. Combined with
|
|
52
|
+
`stableCanonicalStringify` and `hashLegacyMigrationArtifact`, equivalent input
|
|
53
|
+
ordering yields the same digest.
|
|
54
|
+
|
|
55
|
+
`projectLegacyProvisioningReceipt` emits token-free build evidence: campaign,
|
|
56
|
+
package, shipping, and Offer IDs keyed by their stable identities, applied
|
|
57
|
+
Offer intent keys, plan hash, receipt hash, and applied timestamp. It omits
|
|
58
|
+
audit keys and raw readback payloads.
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Migration sidecar bundle v0
|
|
2
|
+
|
|
3
|
+
The migration sidecar bundle is the strict JSON boundary between a campaign
|
|
4
|
+
repository, its CI producer, and Campaigns Agent readback. It does not replace
|
|
5
|
+
the underlying artifacts and it does not create another manifest file. The
|
|
6
|
+
machine contract is
|
|
7
|
+
[`contracts/migration-sidecar-bundle.v0.json`](../contracts/migration-sidecar-bundle.v0.json),
|
|
8
|
+
and the conformance command is:
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
campaigns-os bundle check --packet campaign-runtime.build.json --json
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Add `--require-qa` when the migration or campaign claims QA is complete.
|
|
15
|
+
|
|
16
|
+
## Conformance is not readiness
|
|
17
|
+
|
|
18
|
+
`status: conformant` (and `ok: true`) means the sidecars agree with each other
|
|
19
|
+
and with the contract: every required artifact is present, valid JSON, on its
|
|
20
|
+
declared schema version, freshly timestamped, and carrying the same campaign
|
|
21
|
+
identity. It says nothing about whether doctor or QA passed. A doctor sidecar
|
|
22
|
+
that records a blocked run is a well-formed artifact whose content says the
|
|
23
|
+
campaign cannot proceed, and a blocked QA verdict is schema-valid.
|
|
24
|
+
|
|
25
|
+
Read readiness from two places instead:
|
|
26
|
+
|
|
27
|
+
- The findings. A doctor sidecar recording a blocked run (`status: blocked`
|
|
28
|
+
or `ok: false`) emits `bundle.doctor_output.blocked`; a QA verdict whose
|
|
29
|
+
`disposition` is `blocked` emits `bundle.qa_verdict.blocked`. Both are
|
|
30
|
+
warnings by default (the bundle is still conformant) and errors under
|
|
31
|
+
`--require-qa` (a QA-complete handoff cannot ride either block, so the bundle
|
|
32
|
+
is nonconformant and the command exits 2).
|
|
33
|
+
- `stage_blocked` keeps its published meaning: `true` only when a required
|
|
34
|
+
QA verdict (`--require-qa`) is blocked. The doctor case is carried by the
|
|
35
|
+
finding alone until a schema bump widens the field.
|
|
36
|
+
|
|
37
|
+
The text report prints a `Readiness:` line directly under `Status:` that reads
|
|
38
|
+
those fields for you. The remedy for a blocked doctor is to resolve its errors
|
|
39
|
+
and re-run `campaigns-os doctor --packet campaign-runtime.build.json
|
|
40
|
+
--write --strip-paths` so the retained sidecar records a ready run.
|
|
41
|
+
|
|
42
|
+
## Canonical bundle
|
|
43
|
+
|
|
44
|
+
| Kind | Canonical path | Requirement | Schema/version | Freshness |
|
|
45
|
+
| --- | --- | --- | --- | --- |
|
|
46
|
+
| Build Packet | `campaign-runtime.build.json` | Required | `campaign-runtime-build-packet/v0` | Its `generated_at` is the bundle-selection authority. Never select a packet by mtime. |
|
|
47
|
+
| Build Context | `.campaign-runtime/build-context.json` | Required | `campaign-runtime-build-context/v0` | Producer-stamped `generated_at`; `packet_path` must point to the root packet. |
|
|
48
|
+
| Assembly Report | `.campaign-runtime/assembly-report.json` | Required | `campaign-runtime-assembly-report/v0` | Producer-stamped `generated_at`; authored stage evidence is preserved. |
|
|
49
|
+
| Doctor Output | `.campaign-runtime/doctor-output.json` | Required | `campaigns-os-doctor-output/v0` | Refresh after any doctor-input change; an explicit `stale: true` fails conformance. `generated_by` names the command that persisted it (`doctor`, `next`, `start`, `build`, `qa run`); a sidecar without it predates the stamp. |
|
|
50
|
+
| QA Verdict projection | `.campaign-runtime/qa-verdict.json` | Required after QA | QA schema `1.0`, constrained by the sidecar projection schema | `generated_at` is the projection/promotion instant. |
|
|
51
|
+
|
|
52
|
+
The packet stays at repository root because that is the default discovery
|
|
53
|
+
contract. A packet found only at
|
|
54
|
+
`.campaign-runtime/campaign-runtime.build.json` is reported with a root-path
|
|
55
|
+
remedy; conformance does not silently widen discovery.
|
|
56
|
+
|
|
57
|
+
The checker validates canonical paths, declared schema versions, strict UTC
|
|
58
|
+
timestamps, cross-artifact Map ID, public slug, campaign directory, live URL
|
|
59
|
+
path, template family, and spec identity, doctor freshness, and the URL/order-
|
|
60
|
+
free QA projection. Safe repository-relative spellings such as
|
|
61
|
+
`campaign-runtime.build.json` and `./campaign-runtime.build.json` are
|
|
62
|
+
equivalent; absolute paths, URIs, backslashes, and parent traversal are not.
|
|
63
|
+
|
|
64
|
+
Spec identity has two deliberately separate meanings. Build Context
|
|
65
|
+
`spec.hash` and Assembly Report `identity.spec_hash` retain exact raw-byte
|
|
66
|
+
integrity. Build Context `spec.material_hash`, Assembly Report
|
|
67
|
+
`identity.spec_material_hash`, and QA Verdict `spec_hash` carry the canonical
|
|
68
|
+
semantic identity used for cross-producer correlation. Harmless JSON formatting
|
|
69
|
+
and the declared volatile top-level metadata do not change the material hash;
|
|
70
|
+
commerce or funnel changes do. A partially regenerated material-identity set
|
|
71
|
+
fails closed. For stored bundles produced before the material fields existed,
|
|
72
|
+
the checker uses the contract's explicit strict-legacy mode and requires the
|
|
73
|
+
three historical hash values to match exactly.
|
|
74
|
+
|
|
75
|
+
A blocked doctor remains readable evidence. Under `--require-qa`, a schema-
|
|
76
|
+
valid QA Verdict whose disposition is `blocked` is nonconformant for handoff and
|
|
77
|
+
the result carries `stage_blocked: true`; shape-valid does not mean ready.
|
|
78
|
+
|
|
79
|
+
The Build Packet schema keeps `campaign_directory` and `live_url_path`
|
|
80
|
+
nullable for older or partial packet compatibility. Bundle conformance is
|
|
81
|
+
deliberately stricter: both identities must be non-empty so equality with the
|
|
82
|
+
Assembly Report can be proved. Regenerate the packet with `start` or
|
|
83
|
+
`prepare-build` before checking a bundle whose packet carries either value as
|
|
84
|
+
`null`.
|
|
85
|
+
|
|
86
|
+
## Headless CI producer
|
|
87
|
+
|
|
88
|
+
Resolve and check out one commit before producing anything. The initial
|
|
89
|
+
`campaigns-os start` run writes the packet, context, report, and doctor output
|
|
90
|
+
from explicit CampaignSpec/source/template inputs. `prepare-build` writes the
|
|
91
|
+
packet, context, and report; refresh Doctor output with the command below.
|
|
92
|
+
Later CI runs must preserve the authored packet, context, and Assembly Report
|
|
93
|
+
rather than recreating them with `--force` and erasing stage decisions.
|
|
94
|
+
|
|
95
|
+
Refresh generated evidence at that commit:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
campaigns-os doctor \
|
|
99
|
+
--packet campaign-runtime.build.json \
|
|
100
|
+
--write \
|
|
101
|
+
--strip-paths \
|
|
102
|
+
--json
|
|
103
|
+
|
|
104
|
+
# Only when carrying forward a named historical full verdict:
|
|
105
|
+
campaigns-os qa promote \
|
|
106
|
+
--packet campaign-runtime.build.json \
|
|
107
|
+
--verdict "$EXPLICIT_FULL_VERDICT" \
|
|
108
|
+
--json
|
|
109
|
+
|
|
110
|
+
campaigns-os bundle check \
|
|
111
|
+
--packet campaign-runtime.build.json \
|
|
112
|
+
--require-qa \
|
|
113
|
+
--json
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
`qa promote` requires one explicit full-verdict path. CI must not pick a verdict
|
|
117
|
+
by mtime, filename sort, or a directory's apparent “latest” entry. If there is
|
|
118
|
+
no historical verdict to promote, run QA and let `qa run` write the committed
|
|
119
|
+
projection.
|
|
120
|
+
|
|
121
|
+
The checker emits both exact per-file SHA-256 digests and one
|
|
122
|
+
`material_digest`. The material digest canonicalizes object-key order and
|
|
123
|
+
removes only the volatile fields declared in the machine contract (generation
|
|
124
|
+
timestamps and run IDs). Repeating the producer over the same substantive
|
|
125
|
+
evidence therefore keeps the material digest stable; changing a disposition,
|
|
126
|
+
identity, stage state, or assertion changes it.
|
|
127
|
+
|
|
128
|
+
## Consumer and compatibility fixture
|
|
129
|
+
|
|
130
|
+
The supported production-shaped fixture lives at
|
|
131
|
+
`contracts/fixtures/sidecar-bundle/production-shaped/`. It contains the root
|
|
132
|
+
packet and all four canonical sidecars, including a URL/order-free QA verdict.
|
|
133
|
+
Campaigns Agent can copy or read that tree in both its deterministic and
|
|
134
|
+
real-Campaigns-OS lanes without this public repository importing private Agent
|
|
135
|
+
code.
|
|
136
|
+
|
|
137
|
+
Markdown reports, equivalence ledgers, and migration-specific scripts may live
|
|
138
|
+
beside the bundle as supporting evidence. They never satisfy a missing JSON
|
|
139
|
+
artifact and are never substituted for current readback truth.
|