@nextcommerce/campaigns-os 1.50.0 → 1.52.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 +426 -0
- package/agents/claude/CLAUDE.md +2 -2
- package/agents/codex/AGENTS.md +1 -1
- package/agents/copilot/copilot-instructions.md +1 -1
- package/agents/cursor/campaigns-os.mdc +1 -1
- package/campaign-spec/dist/rules/campaign-metadata.d.ts +5 -1
- package/campaign-spec/dist/rules/campaign-metadata.js +9 -2
- package/campaign-spec/dist/rules/design-source-shape.js +13 -3
- package/campaign-spec/dist/rules/sdk-version.js +2 -1
- package/compatibility.json +1 -1
- package/contracts/commerce-surface-catalog.json +26 -46
- package/contracts/effects.v1.json +81 -2
- package/contracts/release-ledger.json +906 -0
- package/contracts/supported-surface.json +2 -2
- package/contracts/template-brand-contract.shared-commerce.v0.json +2 -2
- package/contracts/template-slot-manifest.shared-content-core.v0.json +24 -0
- package/docs/build-packet.md +93 -9
- package/docs/campaign-build-brief.md +25 -1
- package/docs/effects.md +6 -0
- package/docs/local-setup.md +1 -1
- package/docs/orientation-contract-reference.md +1 -1
- package/docs/polish-evidence.md +10 -0
- package/docs/qa-and-test-orders.md +45 -4
- package/docs/runtime-readiness.md +1 -1
- package/docs/sdk-storage-compatibility.md +1 -1
- package/docs/skills-revision.md +10 -10
- package/package.json +1 -1
- 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 +4 -4
- package/skills/next-campaigns-os/references/session-intake.md +7 -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 +6 -5
- package/skills.json +10 -10
- package/src/adapter-decision-contract.mjs +1 -1
- package/src/brand-theme.mjs +12 -0
- package/src/build-brief.mjs +68 -21
- package/src/built-site-scope.mjs +39 -6
- package/src/built-smoke-qc.mjs +1117 -0
- package/src/campaign-identity.mjs +36 -2
- package/src/cart-placeholders.mjs +730 -0
- package/src/cli.mjs +310 -34
- package/src/commercial-journey.mjs +65 -4
- package/src/commercial-parity.mjs +6 -1
- package/src/doctor/checks.mjs +291 -24
- package/src/doctor/inspect.mjs +53 -2
- package/src/doctor/next-step.mjs +1 -1
- package/src/invocation.mjs +2 -1
- package/src/local-preview-policy.mjs +1 -1
- package/src/local-proof.mjs +4 -1
- package/src/polish-browser.mjs +218 -1
- package/src/polish-capture.mjs +1 -1
- package/src/polish-media-weight.mjs +492 -0
- package/src/polish-node.mjs +96 -4
- package/src/progress-node.mjs +5 -1
- package/src/qa-browser.mjs +308 -96
- package/src/qa-content-params.mjs +889 -0
- package/src/qa-node.mjs +104 -12
- package/src/qa-order-bump.mjs +22 -1
- package/src/qa-policy-links.mjs +1019 -0
- package/src/qa-tracking-params.mjs +1389 -0
- package/src/qa-url-privacy.mjs +168 -0
- package/src/qc-accept.mjs +446 -0
- package/src/qc-check-registry.mjs +83 -0
- package/src/qc-results.mjs +1049 -0
- package/src/sdk-attribute-index.mjs +71 -0
- package/src/sdk-markup.mjs +2 -2
- package/src/sdk-storage-compatibility.mjs +63 -3
- package/src/source-prep.mjs +37 -7
- package/src/stage-record.mjs +56 -17
|
@@ -849,8 +849,8 @@
|
|
|
849
849
|
},
|
|
850
850
|
"verification": {
|
|
851
851
|
"sdk_version": "0.4.40",
|
|
852
|
-
"verified_at": "2026-10-
|
|
853
|
-
"evidence": "sdk-0.4.40-2026-10-
|
|
852
|
+
"verified_at": "2026-10-04T02:15:52Z",
|
|
853
|
+
"evidence": "sdk-0.4.40-2026-10-04",
|
|
854
854
|
"status": "certified",
|
|
855
855
|
"source": "template-verification.json"
|
|
856
856
|
}
|
|
@@ -861,7 +861,7 @@
|
|
|
861
861
|
"id": "template-reference-apollo",
|
|
862
862
|
"family": "apollo",
|
|
863
863
|
"version": "sdk-0.4.38-composable-upsells-2026-09-25",
|
|
864
|
-
"source_commit": "
|
|
864
|
+
"source_commit": "80f0e30f873b5a13a5232ffd76b20da53480ae57",
|
|
865
865
|
"provenance_url": "https://raw.githubusercontent.com/NextCommerceCo/campaign-cart-starter-templates/main/docs/template-references/apollo/README.md",
|
|
866
866
|
"contract_path": "contracts/commerce-surface-catalog.json",
|
|
867
867
|
"standard_viewport_refs": [
|
|
@@ -1273,8 +1273,8 @@
|
|
|
1273
1273
|
},
|
|
1274
1274
|
"verification": {
|
|
1275
1275
|
"sdk_version": "0.4.40",
|
|
1276
|
-
"verified_at": "2026-10-
|
|
1277
|
-
"evidence": "sdk-0.4.40-2026-10-
|
|
1276
|
+
"verified_at": "2026-10-04T02:15:52Z",
|
|
1277
|
+
"evidence": "sdk-0.4.40-2026-10-04",
|
|
1278
1278
|
"status": "certified",
|
|
1279
1279
|
"source": "template-verification.json"
|
|
1280
1280
|
}
|
|
@@ -1584,8 +1584,8 @@
|
|
|
1584
1584
|
},
|
|
1585
1585
|
"verification": {
|
|
1586
1586
|
"sdk_version": "0.4.40",
|
|
1587
|
-
"verified_at": "2026-10-
|
|
1588
|
-
"evidence": "sdk-0.4.40-2026-10-
|
|
1587
|
+
"verified_at": "2026-10-04T02:15:52Z",
|
|
1588
|
+
"evidence": "sdk-0.4.40-2026-10-04",
|
|
1589
1589
|
"status": "certified",
|
|
1590
1590
|
"source": "template-verification.json"
|
|
1591
1591
|
}
|
|
@@ -1887,8 +1887,8 @@
|
|
|
1887
1887
|
},
|
|
1888
1888
|
"verification": {
|
|
1889
1889
|
"sdk_version": "0.4.40",
|
|
1890
|
-
"verified_at": "2026-10-
|
|
1891
|
-
"evidence": "sdk-0.4.40-2026-10-
|
|
1890
|
+
"verified_at": "2026-10-04T02:15:52Z",
|
|
1891
|
+
"evidence": "sdk-0.4.40-2026-10-04",
|
|
1892
1892
|
"status": "certified",
|
|
1893
1893
|
"source": "template-verification.json"
|
|
1894
1894
|
}
|
|
@@ -2228,8 +2228,8 @@
|
|
|
2228
2228
|
},
|
|
2229
2229
|
"verification": {
|
|
2230
2230
|
"sdk_version": "0.4.40",
|
|
2231
|
-
"verified_at": "2026-10-
|
|
2232
|
-
"evidence": "sdk-0.4.40-2026-10-
|
|
2231
|
+
"verified_at": "2026-10-04T02:15:52Z",
|
|
2232
|
+
"evidence": "sdk-0.4.40-2026-10-04",
|
|
2233
2233
|
"status": "certified",
|
|
2234
2234
|
"source": "template-verification.json"
|
|
2235
2235
|
}
|
|
@@ -2667,8 +2667,8 @@
|
|
|
2667
2667
|
},
|
|
2668
2668
|
"verification": {
|
|
2669
2669
|
"sdk_version": "0.4.40",
|
|
2670
|
-
"verified_at": "2026-10-
|
|
2671
|
-
"evidence": "sdk-0.4.40-2026-10-
|
|
2670
|
+
"verified_at": "2026-10-04T02:15:52Z",
|
|
2671
|
+
"evidence": "sdk-0.4.40-2026-10-04",
|
|
2672
2672
|
"status": "certified",
|
|
2673
2673
|
"source": "template-verification.json"
|
|
2674
2674
|
}
|
|
@@ -3024,8 +3024,8 @@
|
|
|
3024
3024
|
},
|
|
3025
3025
|
"verification": {
|
|
3026
3026
|
"sdk_version": "0.4.40",
|
|
3027
|
-
"verified_at": "2026-10-
|
|
3028
|
-
"evidence": "sdk-0.4.40-2026-10-
|
|
3027
|
+
"verified_at": "2026-10-04T02:15:52Z",
|
|
3028
|
+
"evidence": "sdk-0.4.40-2026-10-04",
|
|
3029
3029
|
"status": "certified",
|
|
3030
3030
|
"source": "template-verification.json"
|
|
3031
3031
|
}
|
|
@@ -3314,8 +3314,8 @@
|
|
|
3314
3314
|
},
|
|
3315
3315
|
"verification": {
|
|
3316
3316
|
"sdk_version": "0.4.40",
|
|
3317
|
-
"verified_at": "2026-10-
|
|
3318
|
-
"evidence": "sdk-0.4.40-2026-10-
|
|
3317
|
+
"verified_at": "2026-10-04T02:15:52Z",
|
|
3318
|
+
"evidence": "sdk-0.4.40-2026-10-04",
|
|
3319
3319
|
"status": "certified",
|
|
3320
3320
|
"source": "template-verification.json"
|
|
3321
3321
|
}
|
|
@@ -3334,30 +3334,15 @@
|
|
|
3334
3334
|
{
|
|
3335
3335
|
"families": [
|
|
3336
3336
|
"olympus",
|
|
3337
|
-
"apollo"
|
|
3338
|
-
|
|
3339
|
-
"note": "Single-package check-style bump."
|
|
3340
|
-
},
|
|
3341
|
-
{
|
|
3342
|
-
"families": [
|
|
3337
|
+
"apollo",
|
|
3338
|
+
"demeter",
|
|
3343
3339
|
"olympus-mv-single-step",
|
|
3344
3340
|
"apollo-mv-single-step",
|
|
3345
|
-
"olympus-mv-two-step"
|
|
3346
|
-
],
|
|
3347
|
-
"note": "MV/configurable bump: quantity sync via data-next-product-sync (product_id), so it sums across variant swaps (SDK 0.4.25+). See CLAUDE.md."
|
|
3348
|
-
},
|
|
3349
|
-
{
|
|
3350
|
-
"families": [
|
|
3341
|
+
"olympus-mv-two-step",
|
|
3351
3342
|
"shop-single-step",
|
|
3352
3343
|
"shop-three-step"
|
|
3353
3344
|
],
|
|
3354
|
-
"note": "
|
|
3355
|
-
},
|
|
3356
|
-
{
|
|
3357
|
-
"families": [
|
|
3358
|
-
"demeter"
|
|
3359
|
-
],
|
|
3360
|
-
"note": "Editorial bump styling."
|
|
3345
|
+
"note": "GENERATED from _shared/checkout/_includes/ (sync:shared, byte-identical by construction, lint:shared-enforced) since the #194 consolidation — edit the _shared source, never a family copy. Superset contract: pricing_mode + legacy show_* bools; package_sync/sync_quantity AND product_sync (product_id match for MV mains, wins when both set); per-family demo values live in page frontmatter (order_bump.check01)."
|
|
3361
3346
|
}
|
|
3362
3347
|
]
|
|
3363
3348
|
},
|
|
@@ -3375,30 +3360,25 @@
|
|
|
3375
3360
|
"shop-single-step",
|
|
3376
3361
|
"shop-three-step"
|
|
3377
3362
|
],
|
|
3378
|
-
"note": "
|
|
3363
|
+
"note": "GENERATED from _shared/checkout/_includes/ (sync:shared, byte-identical by construction, lint:shared-enforced) since the #194 consolidation — edit the _shared source, never a family copy. Unsynced product-card bump with optional PackageToggle line-item property field (SDK 0.4.27+)."
|
|
3379
3364
|
}
|
|
3380
3365
|
]
|
|
3381
3366
|
},
|
|
3382
3367
|
"bump-switch01.html": {
|
|
3383
3368
|
"surface": "orderBump",
|
|
3384
3369
|
"lineages": [
|
|
3385
|
-
{
|
|
3386
|
-
"families": [
|
|
3387
|
-
"demeter"
|
|
3388
|
-
],
|
|
3389
|
-
"note": "Switch-style bump with demeter styling."
|
|
3390
|
-
},
|
|
3391
3370
|
{
|
|
3392
3371
|
"families": [
|
|
3393
3372
|
"olympus",
|
|
3394
3373
|
"apollo",
|
|
3374
|
+
"demeter",
|
|
3395
3375
|
"olympus-mv-single-step",
|
|
3396
3376
|
"apollo-mv-single-step",
|
|
3397
3377
|
"olympus-mv-two-step",
|
|
3398
3378
|
"shop-single-step",
|
|
3399
3379
|
"shop-three-step"
|
|
3400
3380
|
],
|
|
3401
|
-
"note": "
|
|
3381
|
+
"note": "GENERATED from _shared/checkout/_includes/ (sync:shared, byte-identical by construction, lint:shared-enforced) since the #194 consolidation — edit the _shared source, never a family copy. Switch-style bump; intentionally never quantity-synced."
|
|
3402
3382
|
}
|
|
3403
3383
|
]
|
|
3404
3384
|
},
|
|
@@ -3524,6 +3504,6 @@
|
|
|
3524
3504
|
}
|
|
3525
3505
|
},
|
|
3526
3506
|
"_synced_from_repo": "NextCommerceCo/campaign-cart-starter-templates",
|
|
3527
|
-
"_synced_from_ref": "
|
|
3528
|
-
"_synced_from_sha": "
|
|
3507
|
+
"_synced_from_ref": "2c618942391ae398fb4812f36fc93e6632054874",
|
|
3508
|
+
"_synced_from_sha": "2c618942391ae398fb4812f36fc93e6632054874"
|
|
3529
3509
|
}
|
|
@@ -362,6 +362,29 @@
|
|
|
362
362
|
"test_scope": "full",
|
|
363
363
|
"notes": "qa publish --dry-run runs every check the real invocation runs and prints what it would do; it writes nothing under the target, appends no lifecycle entry (the command is declared `dryRun` in src/invocation.mjs) and runs no stale-session closeout. Local-spec packets are refused before publication because they have no saved Map destination."
|
|
364
364
|
},
|
|
365
|
+
{
|
|
366
|
+
"command": "checkpoint",
|
|
367
|
+
"subcommand": "accept",
|
|
368
|
+
"flags": [
|
|
369
|
+
"--dry-run"
|
|
370
|
+
],
|
|
371
|
+
"annotations": {
|
|
372
|
+
"readOnlyHint": true,
|
|
373
|
+
"destructiveHint": false,
|
|
374
|
+
"openWorldHint": false,
|
|
375
|
+
"idempotentHint": true
|
|
376
|
+
},
|
|
377
|
+
"tier": "none",
|
|
378
|
+
"writes": [],
|
|
379
|
+
"sends": [],
|
|
380
|
+
"effect_test": "effects: checkpoint accept --dry-run (preflight)",
|
|
381
|
+
"test_scope": "preflight",
|
|
382
|
+
"notes": "checkpoint accept --dry-run runs every check the real invocation runs and prints the accepts it would record; it writes nothing under the target, does not mark the doctor sidecar stale, appends no lifecycle entry (the command is declared `dryRun` in src/invocation.mjs) and runs no stale-session closeout. PREFLIGHT-PROVED: doctor, Polish and QA checks produce accept-eligible warnings, but the offline fixture names a synthetic result ref that matches no current result, so its dry run is refused (changed_since_handoff) before it reaches an accept that passes its checks; the case proves the refused dry run writes nothing and contacts nothing.",
|
|
383
|
+
"preflight": {
|
|
384
|
+
"may_write": [],
|
|
385
|
+
"may_contact": []
|
|
386
|
+
}
|
|
387
|
+
},
|
|
365
388
|
{
|
|
366
389
|
"command": "checkpoint",
|
|
367
390
|
"subcommand": "waive",
|
|
@@ -2731,11 +2754,19 @@
|
|
|
2731
2754
|
"requires_consent": false,
|
|
2732
2755
|
"observed_in": [],
|
|
2733
2756
|
"not_observed_reason": "the offline fixture is blocked at the theme/proof gate before a served page is read, so there is no page to compare and the live campaign is not read"
|
|
2757
|
+
},
|
|
2758
|
+
{
|
|
2759
|
+
"destination": "the http(s) store policy URLs the CampaignSpec configures (campaign.store_terms, campaign.store_privacy, campaign.store_returns, campaign.store_shipping, and campaign.store_contact when it is an http(s) URL), and the redirects they answer with; a mailto: campaign.store_contact is checked for presence only and is never requested",
|
|
2760
|
+
"what": "GET requests that read headers only: at most 5 configured URLs, at most 6 requests per URL (the URL and up to 5 redirects), at most 30 per run",
|
|
2761
|
+
"when": "--browser runs the page checks and the CampaignSpec configures at least one http(s) store policy URL",
|
|
2762
|
+
"requires_consent": false,
|
|
2763
|
+
"observed_in": [],
|
|
2764
|
+
"not_observed_reason": "the offline fixture's browser run is blocked at the gate before any page is checked, so no store policy URL is requested"
|
|
2734
2765
|
}
|
|
2735
2766
|
],
|
|
2736
2767
|
"effect_test": "effects: qa run --browser (preflight)",
|
|
2737
2768
|
"test_scope": "preflight",
|
|
2738
|
-
"notes": "PREFLIGHT-PROVED: --browser needs an installed Chromium and a reachable campaign, neither of which exists offline. The case proves the attempt is blocked at the same gate as the node run and writes exactly the blocked-attempt evidence. It SENDS on a blocked attempt too: the verdict is published to {proxy-base}/api/qa/verdicts and the QA stage progress observation to {proxy-base}/api/progress, both under persisted consent for the endpoint. Publishing rides the telemetry consent seam rather than a flag of its own, so the four consent-off conditions saw neither request. Local-spec packets retain verdicts in the repository and never send a QA verdict or progress to the Map portal, even with --post-verdict. When a served page was read and a public Campaigns API key resolves, it also makes one read-only GET of {proxy-base}/api/campaign under X-Campaign-Key to check the served pages' shipping and package refs against the live campaign (#533); without a key or a page, or on a failed read, the verdict records the check as not_run with its reason. --no-live-refs skips that read (its own row).",
|
|
2769
|
+
"notes": "PREFLIGHT-PROVED: --browser needs an installed Chromium and a reachable campaign, neither of which exists offline. The case proves the attempt is blocked at the same gate as the node run and writes exactly the blocked-attempt evidence. It SENDS on a blocked attempt too: the verdict is published to {proxy-base}/api/qa/verdicts and the QA stage progress observation to {proxy-base}/api/progress, both under persisted consent for the endpoint. Publishing rides the telemetry consent seam rather than a flag of its own, so the four consent-off conditions saw neither request. Local-spec packets retain verdicts in the repository and never send a QA verdict or progress to the Map portal, even with --post-verdict. When a served page was read and a public Campaigns API key resolves, it also makes one read-only GET of {proxy-base}/api/campaign under X-Campaign-Key to check the served pages' shipping and package refs against the live campaign (#533); without a key or a page, or on a failed read, the verdict records the check as not_run with its reason. --no-live-refs skips that read (its own row). Once the page checks run, it also sends the header-only GETs to the configured http(s) store policy URLs (their own row) to check the served pages' policy links; offline the run is blocked at the gate before any page is checked, so none is sent.",
|
|
2739
2770
|
"preflight": {
|
|
2740
2771
|
"may_write": [
|
|
2741
2772
|
"{target}/qa-output/**",
|
|
@@ -3357,11 +3388,19 @@
|
|
|
3357
3388
|
"observed_in": [
|
|
3358
3389
|
"persisted_consent"
|
|
3359
3390
|
]
|
|
3391
|
+
},
|
|
3392
|
+
{
|
|
3393
|
+
"destination": "the http(s) store policy URLs the CampaignSpec configures (campaign.store_terms, campaign.store_privacy, campaign.store_returns, campaign.store_shipping, and campaign.store_contact when it is an http(s) URL), and the redirects they answer with; a mailto: campaign.store_contact is checked for presence only and is never requested",
|
|
3394
|
+
"what": "GET requests that read headers only: at most 5 configured URLs, at most 6 requests per URL (the URL and up to 5 redirects), at most 30 per run",
|
|
3395
|
+
"when": "--browser runs the page checks and the CampaignSpec configures at least one http(s) store policy URL",
|
|
3396
|
+
"requires_consent": false,
|
|
3397
|
+
"observed_in": [],
|
|
3398
|
+
"not_observed_reason": "the offline fixture's browser run is blocked at the gate before any page is checked, so no store policy URL is requested"
|
|
3360
3399
|
}
|
|
3361
3400
|
],
|
|
3362
3401
|
"effect_test": "effects: qa run --browser --no-live-refs (preflight)",
|
|
3363
3402
|
"test_scope": "preflight",
|
|
3364
|
-
"notes": "PREFLIGHT-PROVED like `qa run --browser`: no installed Chromium or reachable campaign offline. The `qa run --browser` row's writes and sends, without the {proxy-base}/api/campaign read: the verdict records the live-campaign-refs check skipped with reason disabled, never a pass. The other sends keep their own conditions and opt-outs.",
|
|
3403
|
+
"notes": "PREFLIGHT-PROVED like `qa run --browser`: no installed Chromium or reachable campaign offline. The `qa run --browser` row's writes and sends, without the {proxy-base}/api/campaign read: the verdict records the live-campaign-refs check skipped with reason disabled, never a pass. The other sends keep their own conditions and opt-outs. The header-only GETs to the configured http(s) store policy URLs are sent as in the `qa run --browser` row, and offline none is sent.",
|
|
3365
3404
|
"preflight": {
|
|
3366
3405
|
"may_write": [
|
|
3367
3406
|
"{target}/qa-output/**",
|
|
@@ -4076,6 +4115,46 @@
|
|
|
4076
4115
|
]
|
|
4077
4116
|
}
|
|
4078
4117
|
},
|
|
4118
|
+
{
|
|
4119
|
+
"command": "checkpoint",
|
|
4120
|
+
"subcommand": "accept",
|
|
4121
|
+
"flags": [],
|
|
4122
|
+
"annotations": {
|
|
4123
|
+
"readOnlyHint": false,
|
|
4124
|
+
"destructiveHint": false,
|
|
4125
|
+
"openWorldHint": false,
|
|
4126
|
+
"idempotentHint": false
|
|
4127
|
+
},
|
|
4128
|
+
"tier": "B",
|
|
4129
|
+
"writes": [
|
|
4130
|
+
{
|
|
4131
|
+
"path": "{target}/.campaign-runtime/assembly-report.json",
|
|
4132
|
+
"when": "an accept is recorded — every listed result is a current accept-eligible warning that was on record before the command; the accepts are appended to qc_accepts[] and evidence[], and nothing already there is replaced",
|
|
4133
|
+
"observed_in": [],
|
|
4134
|
+
"not_observed_reason": "the offline fixture names a synthetic result ref that matches no current result, so its accept is refused (changed_since_handoff) before the one write; the case proves the refusal writes nothing"
|
|
4135
|
+
},
|
|
4136
|
+
{
|
|
4137
|
+
"path": "{target}/.campaign-runtime/doctor-output.json",
|
|
4138
|
+
"when": "an accept is recorded; it marks the retained doctor sidecar stale",
|
|
4139
|
+
"observed_in": [],
|
|
4140
|
+
"not_observed_reason": "the offline fixture names a synthetic result ref that matches no current result, so its accept is refused (changed_since_handoff) before the one write; the case proves the refusal writes nothing"
|
|
4141
|
+
},
|
|
4142
|
+
{
|
|
4143
|
+
"path": "{lifecycle-journal}",
|
|
4144
|
+
"when": "a lifecycle journal is selected for the invocation — an active run session, --lifecycle-journal, or CAMPAIGNS_OS_LIFECYCLE_LOG; the entry records the attempt and its exit status, whether the accept was recorded or the handler failed (such as on malformed packet JSON). A refused invocation journals nothing: a typed accept refusal (any refusal_code), or any other refusal the command raises — a missing, repeated or malformed flag, a missing assembly report, or a qc_accepts or evidence value that is not an array",
|
|
4145
|
+
"observed_in": [],
|
|
4146
|
+
"not_observed_reason": "the offline fixture reaches neither a recorded accept nor a handler failure: it names a synthetic result ref that matches no current result, so its accept is refused (changed_since_handoff), and the case proves that refusal journals nothing"
|
|
4147
|
+
}
|
|
4148
|
+
],
|
|
4149
|
+
"sends": [],
|
|
4150
|
+
"effect_test": "effects: checkpoint accept (preflight)",
|
|
4151
|
+
"test_scope": "preflight",
|
|
4152
|
+
"notes": "Tier B, not C: tier C means the invocation overwrites, clears or discards state that was already there, and `checkpoint waive` is tier C because a waiver overrides a blocking gate. An accept appends, overrides no gate and changes no readiness, and the doctor-sidecar stale stamp is the same write `theme generate` makes at tier B. Not idempotent: a repeat appends another record. It reads only what is already on disk and sends nothing. PREFLIGHT-PROVED: doctor, Polish and QA checks produce accept-eligible warnings, but the offline fixture names a synthetic result ref that matches no current result, so its accept is refused (changed_since_handoff) before the write; the case proves the refused accept writes nothing — no report, no stale stamp, no journal entry — and contacts nothing.",
|
|
4153
|
+
"preflight": {
|
|
4154
|
+
"may_write": [],
|
|
4155
|
+
"may_contact": []
|
|
4156
|
+
}
|
|
4157
|
+
},
|
|
4079
4158
|
{
|
|
4080
4159
|
"command": "checkpoint",
|
|
4081
4160
|
"subcommand": "waive",
|