@nextcommerce/campaigns-os 1.48.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 +539 -0
- package/agents/claude/CLAUDE.md +6 -5
- package/agents/codex/AGENTS.md +6 -5
- package/agents/copilot/copilot-instructions.md +3 -3
- package/agents/cursor/campaigns-os.mdc +3 -3
- 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 +254 -2
- package/contracts/release-ledger.json +1239 -0
- package/contracts/supported-surface.json +4 -4
- 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/brand-theme-bridge.md +12 -6
- package/docs/build-packet.md +101 -12
- 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 +66 -11
- 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/schemas/campaign-runtime-build-packet.v0.schema.json +4 -0
- package/schemas/campaigns-os-qa-verdict.v0.schema.json +8 -3
- 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 +4 -4
- 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 +5 -4
- 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 +25 -2
- 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 +320 -42
- 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/install-mode.mjs +0 -8
- package/src/invocation.mjs +5 -2
- 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-binding-evidence.mjs +21 -0
- package/src/qa-browser.mjs +338 -97
- package/src/qa-content-params.mjs +889 -0
- package/src/qa-node.mjs +114 -14
- 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 +356 -36
- package/src/theme-gate.mjs +3 -3
|
@@ -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",
|
|
@@ -5816,6 +5895,179 @@
|
|
|
5816
5895
|
"test_scope": "full",
|
|
5817
5896
|
"notes": "record polish --dry-run runs every check the real invocation runs and prints what it would write; 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."
|
|
5818
5897
|
},
|
|
5898
|
+
{
|
|
5899
|
+
"command": "record",
|
|
5900
|
+
"subcommand": "theme",
|
|
5901
|
+
"flags": [],
|
|
5902
|
+
"annotations": {
|
|
5903
|
+
"readOnlyHint": false,
|
|
5904
|
+
"destructiveHint": true,
|
|
5905
|
+
"openWorldHint": false,
|
|
5906
|
+
"idempotentHint": false
|
|
5907
|
+
},
|
|
5908
|
+
"tier": "C",
|
|
5909
|
+
"writes": [
|
|
5910
|
+
{
|
|
5911
|
+
"path": "{target}/.campaign-runtime/assembly-report.json",
|
|
5912
|
+
"when": "the record passes every check — theme.status becomes applied with load_order after-next-core, css_path, commerce_pages and per-page evidence read from the built pages; any earlier theme waiver is cleared",
|
|
5913
|
+
"observed_in": [
|
|
5914
|
+
"no_session",
|
|
5915
|
+
"ambient_session",
|
|
5916
|
+
"stale_session",
|
|
5917
|
+
"lifecycle_log",
|
|
5918
|
+
"persisted_consent"
|
|
5919
|
+
]
|
|
5920
|
+
},
|
|
5921
|
+
{
|
|
5922
|
+
"path": "{target}/.campaign-runtime/doctor-output.json",
|
|
5923
|
+
"when": "a retained doctor sidecar exists — the record postdates the doctor snapshot, so it is stamped stale",
|
|
5924
|
+
"observed_in": [
|
|
5925
|
+
"no_session",
|
|
5926
|
+
"ambient_session",
|
|
5927
|
+
"stale_session",
|
|
5928
|
+
"lifecycle_log",
|
|
5929
|
+
"persisted_consent"
|
|
5930
|
+
]
|
|
5931
|
+
},
|
|
5932
|
+
{
|
|
5933
|
+
"path": "{lifecycle-journal}",
|
|
5934
|
+
"when": "a lifecycle journal is selected for the invocation — an active run session, --lifecycle-journal, or CAMPAIGNS_OS_LIFECYCLE_LOG",
|
|
5935
|
+
"observed_in": [
|
|
5936
|
+
"ambient_session",
|
|
5937
|
+
"lifecycle_log"
|
|
5938
|
+
]
|
|
5939
|
+
}
|
|
5940
|
+
],
|
|
5941
|
+
"sends": [],
|
|
5942
|
+
"effect_test": "effects: record theme",
|
|
5943
|
+
"test_scope": "full",
|
|
5944
|
+
"notes": "Destructive: it replaces report.theme's status, css_path, load_order, commerce_pages, evidence and waiver. Refused, writing nothing, when build is not recorded for the current output, when the campaign ships no commerce pages, when a built commerce page that loads next-core.css does not load brand-theme.css (or checkout-brand.css) after it, or links one that is not in the built output, or when no built commerce page loads next-core.css. The Build Context is read, not written."
|
|
5945
|
+
},
|
|
5946
|
+
{
|
|
5947
|
+
"command": "record",
|
|
5948
|
+
"subcommand": "theme",
|
|
5949
|
+
"flags": [
|
|
5950
|
+
"--dry-run"
|
|
5951
|
+
],
|
|
5952
|
+
"annotations": {
|
|
5953
|
+
"readOnlyHint": true,
|
|
5954
|
+
"destructiveHint": false,
|
|
5955
|
+
"openWorldHint": false,
|
|
5956
|
+
"idempotentHint": true
|
|
5957
|
+
},
|
|
5958
|
+
"tier": "none",
|
|
5959
|
+
"writes": [],
|
|
5960
|
+
"sends": [],
|
|
5961
|
+
"effect_test": "effects: record theme --dry-run",
|
|
5962
|
+
"test_scope": "full",
|
|
5963
|
+
"notes": "record theme --dry-run runs every check the real invocation runs and prints what it would write; 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."
|
|
5964
|
+
},
|
|
5965
|
+
{
|
|
5966
|
+
"command": "record",
|
|
5967
|
+
"subcommand": "deploy",
|
|
5968
|
+
"flags": [],
|
|
5969
|
+
"annotations": {
|
|
5970
|
+
"readOnlyHint": false,
|
|
5971
|
+
"destructiveHint": true,
|
|
5972
|
+
"openWorldHint": true,
|
|
5973
|
+
"idempotentHint": false
|
|
5974
|
+
},
|
|
5975
|
+
"tier": "C",
|
|
5976
|
+
"writes": [
|
|
5977
|
+
{
|
|
5978
|
+
"path": "{packet}",
|
|
5979
|
+
"when": "the record passes every check — deploy.preview_url becomes the served URL",
|
|
5980
|
+
"observed_in": [
|
|
5981
|
+
"no_session",
|
|
5982
|
+
"ambient_session",
|
|
5983
|
+
"stale_session",
|
|
5984
|
+
"lifecycle_log",
|
|
5985
|
+
"persisted_consent"
|
|
5986
|
+
]
|
|
5987
|
+
},
|
|
5988
|
+
{
|
|
5989
|
+
"path": "{target}/.campaign-runtime/assembly-report.json",
|
|
5990
|
+
"when": "the record passes every check — stages.deploy becomes completed with the served URL in outputs and one evidence line per page that answered",
|
|
5991
|
+
"observed_in": [
|
|
5992
|
+
"no_session",
|
|
5993
|
+
"ambient_session",
|
|
5994
|
+
"stale_session",
|
|
5995
|
+
"lifecycle_log",
|
|
5996
|
+
"persisted_consent"
|
|
5997
|
+
]
|
|
5998
|
+
},
|
|
5999
|
+
{
|
|
6000
|
+
"path": "{target}/.campaign-runtime/doctor-output.json",
|
|
6001
|
+
"when": "a retained doctor sidecar exists — the record postdates the doctor snapshot, so it is stamped stale",
|
|
6002
|
+
"observed_in": [
|
|
6003
|
+
"no_session",
|
|
6004
|
+
"ambient_session",
|
|
6005
|
+
"stale_session",
|
|
6006
|
+
"lifecycle_log",
|
|
6007
|
+
"persisted_consent"
|
|
6008
|
+
]
|
|
6009
|
+
},
|
|
6010
|
+
{
|
|
6011
|
+
"path": "{lifecycle-journal}",
|
|
6012
|
+
"when": "a lifecycle journal is selected for the invocation — an active run session, --lifecycle-journal, or CAMPAIGNS_OS_LIFECYCLE_LOG",
|
|
6013
|
+
"observed_in": [
|
|
6014
|
+
"ambient_session",
|
|
6015
|
+
"lifecycle_log"
|
|
6016
|
+
]
|
|
6017
|
+
}
|
|
6018
|
+
],
|
|
6019
|
+
"sends": [
|
|
6020
|
+
{
|
|
6021
|
+
"destination": "{base-url}",
|
|
6022
|
+
"what": "a GET for each built page under the served URL, to prove the local preview answers before it is recorded",
|
|
6023
|
+
"when": "the packet's deploy target is local-serve and --base-url is a loopback origin naming the campaign's route root",
|
|
6024
|
+
"requires_consent": false,
|
|
6025
|
+
"observed_in": [
|
|
6026
|
+
"no_session",
|
|
6027
|
+
"ambient_session",
|
|
6028
|
+
"stale_session",
|
|
6029
|
+
"lifecycle_log",
|
|
6030
|
+
"persisted_consent"
|
|
6031
|
+
]
|
|
6032
|
+
}
|
|
6033
|
+
],
|
|
6034
|
+
"effect_test": "effects: record deploy",
|
|
6035
|
+
"test_scope": "full",
|
|
6036
|
+
"notes": "Destructive: it replaces stages.deploy and the packet's deploy.preview_url. The requests stay on this machine: --base-url must be a loopback origin. Refused, writing nothing, when the packet is not local-serve, the URL is not loopback or not the campaign's route root, a built page does not answer 2xx, polish is not recorded, the built output changed since build was recorded, or the theme gate is blocked. The Build Context is read, not written."
|
|
6037
|
+
},
|
|
6038
|
+
{
|
|
6039
|
+
"command": "record",
|
|
6040
|
+
"subcommand": "deploy",
|
|
6041
|
+
"flags": [
|
|
6042
|
+
"--dry-run"
|
|
6043
|
+
],
|
|
6044
|
+
"annotations": {
|
|
6045
|
+
"readOnlyHint": false,
|
|
6046
|
+
"destructiveHint": false,
|
|
6047
|
+
"openWorldHint": true,
|
|
6048
|
+
"idempotentHint": true
|
|
6049
|
+
},
|
|
6050
|
+
"tier": "A",
|
|
6051
|
+
"writes": [],
|
|
6052
|
+
"sends": [
|
|
6053
|
+
{
|
|
6054
|
+
"destination": "{base-url}",
|
|
6055
|
+
"what": "a GET for each built page under the served URL, to prove the local preview answers before it is recorded",
|
|
6056
|
+
"when": "the packet's deploy target is local-serve and --base-url is a loopback origin naming the campaign's route root",
|
|
6057
|
+
"requires_consent": false,
|
|
6058
|
+
"observed_in": [
|
|
6059
|
+
"no_session",
|
|
6060
|
+
"ambient_session",
|
|
6061
|
+
"stale_session",
|
|
6062
|
+
"lifecycle_log",
|
|
6063
|
+
"persisted_consent"
|
|
6064
|
+
]
|
|
6065
|
+
}
|
|
6066
|
+
],
|
|
6067
|
+
"effect_test": "effects: record deploy --dry-run",
|
|
6068
|
+
"test_scope": "full",
|
|
6069
|
+
"notes": "record deploy --dry-run runs every check the real invocation runs, the page requests included, and prints what it would write; 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."
|
|
6070
|
+
},
|
|
5819
6071
|
{
|
|
5820
6072
|
"command": "login",
|
|
5821
6073
|
"subcommand": null,
|