@nextcommerce/campaigns-os 1.59.0 → 1.60.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.
Files changed (41) hide show
  1. package/CHANGELOG.md +116 -0
  2. package/README.md +6 -5
  3. package/compatibility.json +1 -1
  4. package/contracts/commerce-surface-catalog.json +18 -18
  5. package/contracts/release-ledger.json +543 -0
  6. package/contracts/supported-surface.json +1 -1
  7. package/contracts/template-brand-contract.shared-commerce.v0.json +1 -1
  8. package/docs/build-packet.md +14 -12
  9. package/docs/campaign-build-brief.md +1 -1
  10. package/docs/campaigns-os-build-flow.md +1 -1
  11. package/docs/local-setup.md +1 -1
  12. package/docs/orientation-contract-reference.md +1 -1
  13. package/docs/polish-evidence.md +1 -1
  14. package/docs/runtime-readiness.md +1 -1
  15. package/docs/skills-revision.md +10 -10
  16. package/package.json +1 -1
  17. package/skills/campaign-lifecycle-orientation/SKILL.md +3 -3
  18. package/skills/campaign-readback-classification/SKILL.md +3 -3
  19. package/skills/campaign-run-evidence/SKILL.md +3 -3
  20. package/skills/contribution-intake/SKILL.md +3 -3
  21. package/skills/next-campaigns-build/SKILL.md +4 -4
  22. package/skills/next-campaigns-os/SKILL.md +3 -3
  23. package/skills/next-campaigns-os-setup/SKILL.md +3 -3
  24. package/skills/next-campaigns-polish/SKILL.md +9 -10
  25. package/skills/next-campaigns-qa/SKILL.md +3 -3
  26. package/skills/next-campaigns-sdk-bump/SKILL.md +193 -0
  27. package/skills.json +18 -10
  28. package/src/built-site-scope.mjs +5 -12
  29. package/src/campaign-identity.mjs +6 -4
  30. package/src/cli.mjs +37 -60
  31. package/src/doctor/checks.mjs +6 -3
  32. package/src/doctor/inspect.mjs +2 -8
  33. package/src/doctor/next-step.mjs +6 -3
  34. package/src/orchestration-stage-contract.mjs +6 -3
  35. package/src/page-kit-build-summary.mjs +21 -1
  36. package/src/page-kit-campaign-config.mjs +19 -0
  37. package/src/polish-gate.mjs +1 -5
  38. package/src/progress-node.mjs +2 -1
  39. package/src/spec-derive.mjs +24 -9
  40. package/src/stage-ledger.mjs +27 -1
  41. package/src/stage-record.mjs +18 -2
@@ -52,7 +52,7 @@ import {
52
52
  import { evaluateRecordedHiddenEagerMediaCheckpoint } from "./polish-node.mjs";
53
53
  import { effectiveStageStatus, effectiveStatusIsTerminal, inputStamps, stageWriteInputs } from "./input-currency.mjs";
54
54
  import { demoteStages, recordBrief, recordSpec } from "./input-refresh.mjs";
55
- import { applyDerivedAssemblyReportSummary, archiveStageRecord, archiveSupersededRecord, assemblyReportMatchesPacket, commitAssemblyReport, inputChangeFor } from "./stage-ledger.mjs";
55
+ import { applyDerivedAssemblyReportSummary, archiveStageRecord, archiveSupersededRecord, assemblyReportMatchesPacket, commitAssemblyReport, inputChangeFor, restorePolishKeptWithOutput } from "./stage-ledger.mjs";
56
56
  import { withTargetLockSync } from "./target-lock.mjs";
57
57
  import { commerceScopeFromScope } from "./theme-gate.mjs";
58
58
 
@@ -382,9 +382,15 @@ function composeBuild(report, { now, recordedBy, fingerprint, manifest = null, b
382
382
  if (detected) {
383
383
  const cause = detected === "spec_material_changed" ? "spec" : "presentation";
384
384
  const demoted = demoteStages({ ...nextReport, stages: { ...nextReport.stages, assembly, ...deploy } }, { causes: [cause], now, by: "record build", only: ["polish", "qa"] });
385
- return { report: demoted.report, context: null };
385
+ const kept = keptPolishFor(demoted.report.stages.polish, { assembly, fingerprint, sourcePackageFingerprint, stamps });
386
+ return { report: kept ? { ...demoted.report, stages: { ...demoted.report.stages, polish: kept } } : demoted.report, context: null };
386
387
  }
387
388
  const previousPolish = stageObject(report, "polish");
389
+ // The usual #668 path: intake (prepare-build --force or record spec) already
390
+ // recorded the change on assembly, so nothing is detected here, but the
391
+ // carried input_change makes this build a replay the operator kept.
392
+ const keptPolish = keptPolishFor(previousPolish, { assembly, fingerprint, sourcePackageFingerprint, stamps });
393
+ if (keptPolish) return { report: { ...nextReport, stages: { ...nextReport.stages, assembly, polish: keptPolish, ...deploy } }, context: null };
388
394
  const polishStillCurrent = stageIsTerminal(String(previousPolish.status || ""))
389
395
  && optionalString(previousPolish.source_build_fingerprint) === fingerprint;
390
396
  const polish = polishStillCurrent
@@ -399,6 +405,16 @@ function composeBuild(report, { now, recordedBy, fingerprint, manifest = null, b
399
405
  return { report: { ...nextReport, stages: { ...nextReport.stages, assembly, polish, ...deploy } }, context: null };
400
406
  }
401
407
 
408
+ // #668: the Polish a CampaignSpec change superseded comes back when the
409
+ // operator's --deviation-reason kept the output it reviewed (stage-ledger's
410
+ // restorePolishKeptWithOutput decides from the archived record). A terminal
411
+ // Polish, or a build the operator did not keep, is left alone.
412
+ function keptPolishFor(polish, { assembly, fingerprint, sourcePackageFingerprint, stamps }) {
413
+ if (!isObject(assembly.unchanged_output_reason) || stageIsTerminal(String(polish?.status || ""))) return null;
414
+ const kept = restorePolishKeptWithOutput(polish, { fingerprint, sourcePackageFingerprint, stamps, completedStatuses: POLISH_COMPLETED_STATUSES });
415
+ return kept ? withoutKeys(kept, ["skip_reason"]) : null;
416
+ }
417
+
402
418
  // stages.deploy after a build of `fingerprint`, or null when it is kept: a
403
419
  // completed deploy whose source_build_fingerprint names other output goes
404
420
  // whole into history (archived_by "record build", reason_code