@sonordev/contracts 2.18.0 → 2.20.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 +34 -0
- package/README.md +454 -1
- package/dist/broadcast-layouts.d.ts +8 -0
- package/dist/broadcast-layouts.js +4 -0
- package/dist/broadcast-layouts.mjs +3 -1
- package/dist/funnels.d.ts +46 -0
- package/dist/funnels.js +35 -4
- package/dist/funnels.mjs +33 -5
- package/dist/resonance-constants.d.ts +4 -0
- package/dist/resonance-constants.js +10 -0
- package/dist/resonance-constants.mjs +6 -0
- package/dist/resonance.d.ts +6962 -0
- package/dist/resonance.js +1809 -0
- package/dist/resonance.mjs +1650 -0
- package/dist/signal-experiments.d.ts +219 -0
- package/dist/signal-experiments.js +270 -0
- package/dist/signal-experiments.mjs +260 -0
- package/dist/wire-schema.d.ts +36 -0
- package/docs.json +21 -0
- package/package.json +19 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,39 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.20.0
|
|
4
|
+
|
|
5
|
+
- Publish the `resonance`, `resonance-constants` and `signal-experiments` entries with matching CommonJS, ESM and TypeScript surfaces. Add the documentation manifest used by sonor.dev. These validation contracts grant no campaign approval or spending authority.
|
|
6
|
+
|
|
7
|
+
- Bind current Meta configuration review to the existing semantic definition digest plus a nondecreasing audit revision. Add required native `currentDefinitionDigest` metadata so metadata-only saves can preserve multiple unchanged channel configurations. Original snapshots stay immutable; exact prepared-plan, approval and native root fences remain unchanged.
|
|
8
|
+
|
|
9
|
+
- Add pure native measurement bootstrap save/current/snapshot/response contracts and one deterministic page projection using existing semantic digest bytes. Native page resources retain UTC millisecond revisions; rule revisions use full existing evidence digests. Project/site CAS, actual protected writer and one read-only native freshness resolver remain separate adoption requirements.
|
|
10
|
+
- Add pure Meta configuration save/snapshot/view/response contracts, exact existing-audience or admitted-setup mappings, immutable friendly review material, shared digest/projection helpers, minimal optional mandate feed selection and post-acceptance original feed review. Preserve the raw existing mandate-draft response and no-feed request bytes. Saved profile references require actual persisted operation IDs and integer configuration revisions; parsing grants no native capability or approval.
|
|
11
|
+
- Add closed explicit `provider_managed` Meta age intent alongside unchanged absent, omitted and bounded behavior. Actual first same-root PAUSED creator observation and unchanged activation comparison remain native owner work; existing consumers must explicitly support the new branch before adoption.
|
|
12
|
+
|
|
13
|
+
- Add an optional original Meta website-visit feed grant and a closed internal `deliver_website_visit` command through the existing Resonance parser and digests. Preserve omitted legacy fields and require explicit native feed authority; parsing doesn't authenticate a producer or permit manual origination.
|
|
14
|
+
- Add same-occurrence reported path and Meta cookie observation shapes, one fixed SDK observation policy and canonical semantic configuration/profile digest helpers. Add original-time checks with an inclusive five-minute local freshness bound and zero future allowance. These are Sonor rules, not Meta acceptance guarantees; native capture, consent, admission and delivery remain separate.
|
|
15
|
+
- Represent explicit omitted or bounded original Meta age selection. Absent fields retain legacy bytes and don't choose defaults. Actual policy, compiler and normalized readback support remain adapter responsibilities.
|
|
16
|
+
|
|
17
|
+
- Add a closed Google qualified-conversion delivery command and explicit original mandate operation. Reference one original Google channel and a persisted conversion ID. Optional plan, mandate and time context checks public grant consistency and the original prepared definition revision; private facts, native receipts, current consent and final admission remain server-owned. Existing launch grants never expand automatically.
|
|
18
|
+
|
|
19
|
+
- Add closed finite Meta candidate policy, lifecycle evidence and one-action decision variants through the existing Resonance entry. Reference original candidate channel IDs, preserve mature allocation, and bind later graph evidence without a digest cycle. Fixed exploration explicitly has no performance-decision policy. Optional actual evidence/plan arguments check cross-object scope and action consistency; native funding and admission remain server-owned.
|
|
20
|
+
|
|
21
|
+
- Add optional, closed `clickIdentifiers` to page-view measurement occurrences. Accept exactly one bounded `gclid`, `gbraid` or `wbraid`; other occurrence kinds reject it. Export its parser, type and JSON Schema. Identifiers describe observed lineage and grant no conversion or provider authority.
|
|
22
|
+
|
|
23
|
+
- Add strict Google configuration draft, snapshot, view and review contracts, one canonical projection and a digest-input helper. Prepared Google Search previews require either actual existing-goal evidence or bounded one-action setup intent for creation after the same mandate; other channels use explicit `null`. Require the explicit historical `qualified_at_observation_v1` provider signal profile, distinct from current Sonor outcome counts. Draft declarations stay bound to their campaign and creative scope; parsing grants no provider or approval authority.
|
|
24
|
+
|
|
25
|
+
- Add strict command-preparation request and response parsers. Preparation reports existing mandate or current owner approval requirements and never grants authority. Add `@sonordev/contracts/resonance-constants` for browser wire literals without campaign schemas.
|
|
26
|
+
|
|
27
|
+
- Add canonical Signal experiment create/update parsers and bounded Resonance audience/experiment management commands. Add reviewed public source-marker fields and the explicit first-party last-touch attribution model. These parsers validate wire data and grant no approval or provider authority.
|
|
28
|
+
|
|
29
|
+
- Add `@sonordev/contracts/resonance`: strict campaign, account capability, prepared-plan, mandate lookup, command, receipt, measurement and consent boundaries for connected campaign operations. Money uses exact decimal-string micros with checked provider-unit conversion. Parsing validates data and scope; it never grants advertising or spending authority.
|
|
30
|
+
- Retain the 2.19 review-photo presentation exports and all existing contracts.
|
|
31
|
+
|
|
32
|
+
## 2.19.0
|
|
33
|
+
|
|
34
|
+
- Add an optional per-review photo presentation to `@sonordev/contracts/broadcast-layouts`: `REVIEW_PHOTO_PRESENTATIONS`, `ReviewPhotoPresentation` and `isReviewPhotoPresentation` support the explicit `background` choice. Input consumers handle an omitted choice by preserving the saved value and `null` by clearing it to automatic. Existing automatic layouts, composition seeds and variation draws are unchanged.
|
|
35
|
+
- Keep the decision-role entry and all other published contracts behavior unchanged.
|
|
36
|
+
|
|
3
37
|
## 2.18.0
|
|
4
38
|
|
|
5
39
|
A minor release: one new entry, `@sonordev/contracts/decision-roles`. Every other entry is unchanged.
|
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ pnpm add @sonordev/contracts
|
|
|
19
19
|
| `@sonordev/contracts/seo-pages` | Which `seo_pages` row a path resolves to on a multi-site project | the Sonor API, Signal, site-kit's sitemap sync |
|
|
20
20
|
| `@sonordev/contracts/seo-meta` | Whether a title or description is fit to ship | site-kit, Signal's SEO gate |
|
|
21
21
|
| `@sonordev/contracts/llms` | llms.txt sanitizers, the word-safe cut they use (`clipAtWordBoundary`), what each page line says (`pickLlmsPageDescription`: summary, curated meta, served meta, schema description, then a cleaned scrape; `llmsPageTitle`, `isLlmsListablePage`, `groupLlmsPages`, `selectLlmsPages`) and the contract version | site-kit, the Sonor API, Signal's schema validation |
|
|
22
|
-
| `@sonordev/contracts/forms` |
|
|
22
|
+
| `@sonordev/contracts/forms` | Shared form validation helpers | site-kit forms, the Sonor API's form intake |
|
|
23
23
|
| `@sonordev/contracts/fleet` | The fleet heartbeat's wire shape | site-kit, the Sonor API |
|
|
24
24
|
| `@sonordev/contracts/slots` | Slot payload signing, contract v2 (HMAC; Node only). Signs and verifies v1 for older site-kit releases | the Sonor API, site-kit on the server |
|
|
25
25
|
| `@sonordev/contracts/slot-content` | What a slot of each kind may hold (`normalizeSlotValue`), safe links, the rich-text parser. No `crypto`, so browsers can import it | the Sonor API, site-kit, the dashboard editor |
|
|
@@ -42,6 +42,9 @@ pnpm add @sonordev/contracts
|
|
|
42
42
|
| `@sonordev/contracts/inbox` | Which inbox cards are decisions a bulk action leaves alone (`isDecisionCard`, `DECISION_INSIGHT_TYPES`) | Signal's inbox decides what "Mark all read" and "Dismiss all" may touch, the dashboard previews the same result before the write |
|
|
43
43
|
| `@sonordev/contracts/crm-disposition` | What a rep's call outcome (positive, negative or left voicemail) changes on a prospect: the call's outcome and sentiment, the contact's stage, the company's status, today's reminder and outreach (`dispositionTransitions`), and the reasons a negative outcome carries | the Sonor API applies an outcome, the dashboard's calling screen offers the same three buttons and reasons, the sales extension stops flipping a company on dial |
|
|
44
44
|
| `@sonordev/contracts/decision-roles` | The part a job title says a person plays in a buying decision (`DECISION_ROLES`: owner, decision maker, influencer, gatekeeper), read from the title alone by `decisionRoleForTitle` | the Sonor API's site-people scan and Signal's site-people scout read the same map |
|
|
45
|
+
| `@sonordev/contracts/resonance` | Campaign, consent, measurement, plan, mandate and command parsers, types and JSON schemas | Sites, APIs and the dashboard share the same wire rules |
|
|
46
|
+
| `@sonordev/contracts/resonance-constants` | Small browser-safe measurement wire constants | Browser readers that don't need campaign schemas |
|
|
47
|
+
| `@sonordev/contracts/signal-experiments` | Shared Signal experiment create and update validation | APIs and the dashboard use one experiment boundary |
|
|
45
48
|
|
|
46
49
|
## Focus closing artwork
|
|
47
50
|
|
|
@@ -853,6 +856,7 @@ import { createHash } from 'node:crypto'
|
|
|
853
856
|
import {
|
|
854
857
|
ARTICLE_COVER_LAYOUTS, CARD_LAYOUTS, isCardLayoutId, normalizeArticleCoverLayout,
|
|
855
858
|
normalizeReviewCardVariation, reviewCardVariationFromDigest, reviewCompositionSeed,
|
|
859
|
+
REVIEW_PHOTO_PRESENTATIONS, isReviewPhotoPresentation,
|
|
856
860
|
} from '@sonordev/contracts/broadcast-layouts'
|
|
857
861
|
|
|
858
862
|
CARD_LAYOUTS // ['stacked', 'headline', 'split', 'anchor']
|
|
@@ -861,6 +865,9 @@ isCardLayoutId('stacked') // true: an old post still reads
|
|
|
861
865
|
normalizeArticleCoverLayout('stacked') // 'anchor'
|
|
862
866
|
normalizeArticleCoverLayout('split') // 'headline'
|
|
863
867
|
normalizeReviewCardVariation('spotlight') // 'signature'
|
|
868
|
+
REVIEW_PHOTO_PRESENTATIONS // ['background']
|
|
869
|
+
isReviewPhotoPresentation('background') // true
|
|
870
|
+
isReviewPhotoPresentation(null) // false: a clear operation is handled by the caller
|
|
864
871
|
|
|
865
872
|
// On the server: a review's composition, stable for its identity.
|
|
866
873
|
const digest = createHash('sha256').update(reviewCompositionSeed(projectId, reviewId)).digest()
|
|
@@ -889,6 +896,13 @@ reviewCardVariationFromDigest(digest) // 'signature' or 'frame'
|
|
|
889
896
|
as Signature and anything unknown as the default, Signature.
|
|
890
897
|
**`isReviewCardVariation`** is the strict check for a request that must
|
|
891
898
|
name a drawn one.
|
|
899
|
+
- **`REVIEW_PHOTO_PRESENTATIONS`** lists explicit per-review photo choices:
|
|
900
|
+
`background` places the primary photo behind the review text. The
|
|
901
|
+
`ReviewPhotoPresentation` type and `isReviewPhotoPresentation` guard share
|
|
902
|
+
that supported set. The guard accepts explicit values only; input consumers
|
|
903
|
+
handle omission (preserve a saved choice) and `null` (clear it to automatic)
|
|
904
|
+
separately. Existing records without a choice keep their deterministic
|
|
905
|
+
composition; presentation doesn't change the seed or variation draw.
|
|
892
906
|
- **A review's composition never moves.** It's drawn from the SHA-256 of
|
|
893
907
|
`reviewCompositionSeed(projectId, reviewId)`, never from anything a person
|
|
894
908
|
can edit. `reviewCardVariationFromDigest` reads the first four bytes
|
|
@@ -1146,3 +1160,442 @@ Use `parseFunnelCreateArgs`, `parseFunnelUpdateArgs`, `parseFunnelRevisionArgs`,
|
|
|
1146
1160
|
`parsePublishedFunnelPage` refuses private definition fields and unsafe asset URLs. It supports bounded text paragraphs and bullet lists, with a managed form slug and canonical campaign identity. `managedFunnelPath` reserves `/f/:slug`; a consuming site must opt in and verify its actual routes.
|
|
1147
1161
|
|
|
1148
1162
|
`parseFunnelReadiness`, `parseFunnelOperationReceipt` and the detail/catalog/preview parsers validate bounded response envelopes. Operation receipts bind the exact command target and approved action, and always report zero messages sent by the configuration command. Preview and published-version detail parsers preserve the exact launch or rollback evidence.
|
|
1163
|
+
|
|
1164
|
+
|
|
1165
|
+
## Adopting 2.20.0
|
|
1166
|
+
|
|
1167
|
+
Use the same contracts version in every application that exchanges Resonance
|
|
1168
|
+
payloads. This release includes the 2.19 review-photo presentation exports and
|
|
1169
|
+
adds the Resonance and Signal experiment entries. Existing package subpaths stay
|
|
1170
|
+
available. Import a specific entry rather than the package root.
|
|
1171
|
+
|
|
1172
|
+
```ts
|
|
1173
|
+
import { parseMoney } from '@sonordev/contracts/resonance'
|
|
1174
|
+
|
|
1175
|
+
const budget = parseMoney({ currency: 'USD', amountMicros: '1250000' })
|
|
1176
|
+
```
|
|
1177
|
+
|
|
1178
|
+
The parsers validate wire data. They don't approve a campaign, authorize spending
|
|
1179
|
+
or confirm provider delivery. Keep those checks in the application that owns the
|
|
1180
|
+
action. Deploy accepting server parsers before enabling new browser fields.
|
|
1181
|
+
|
|
1182
|
+
## The resonance contract
|
|
1183
|
+
|
|
1184
|
+
Import pure parsers, types and JSON schemas from `@sonordev/contracts/resonance`.
|
|
1185
|
+
`parseResonanceCampaignDraft` accepts bounded incomplete setup; `parseResonanceCampaignDefinition`
|
|
1186
|
+
requires resolved goals, resources, destinations, channels and budget. Existing funnel,
|
|
1187
|
+
Broadcast, Outreach, Files, brand and experiment records retain ownership. Nested
|
|
1188
|
+
references must match the campaign's project and owned-site scope. Server lookups
|
|
1189
|
+
must still validate ownership, current revisions, policy and actual permission.
|
|
1190
|
+
|
|
1191
|
+
`Money` is `{ currency: 'USD', amountMicros: '1250000' }`, exactly 1.25 USD.
|
|
1192
|
+
`parseMoney`, `addMoney`, `moneyToProviderUnits` and `moneyFromProviderUnits` use
|
|
1193
|
+
integer arithmetic. Never pass amounts through `Number` or assume every currency
|
|
1194
|
+
uses cents. Conversion requires the verified provider/account exponent (0, 2, 3 or
|
|
1195
|
+
6) and native limit; fractional units, overflow and currency mismatch fail.
|
|
1196
|
+
Supported currency codes are exported as `RESONANCE_CURRENCIES`; actual advertiser
|
|
1197
|
+
eligibility, minimum budgets and delivery semantics remain provider checks.
|
|
1198
|
+
|
|
1199
|
+
The initial paid profiles are `google_search` and `meta_retargeting`, distinct
|
|
1200
|
+
from provider IDs `google_ads` and `meta_ads`. They are closed plans, not arbitrary
|
|
1201
|
+
provider JSON or a claim to support every campaign type. Prepared plans bind exact
|
|
1202
|
+
ordered creative copy/media/crop references, destinations, budgets, goal/policy
|
|
1203
|
+
revisions and server-owned compiled manifest references. `resonancePlanIssues`
|
|
1204
|
+
reports blocked, missing or stale capabilities without turning them into success.
|
|
1205
|
+
|
|
1206
|
+
`parseResonanceMandateApprovalPayload(value, target)` validates the exact business
|
|
1207
|
+
payload and project/campaign target. It doesn't approve anything. Resolve original
|
|
1208
|
+
principal and approval provenance through the existing Action Ledger; compute and
|
|
1209
|
+
verify the server digest over `resonanceMandateDigestInput` before admitting effects.
|
|
1210
|
+
The command digest input similarly canonicalizes only parsed command fields.
|
|
1211
|
+
Launch/update/resume and optimization require exact plan/mandate lookups. Safety
|
|
1212
|
+
pause/finish/reconcile commands require root revision and idempotency identity but
|
|
1213
|
+
no fresh creative approval, so stale creative evidence cannot prevent a stop.
|
|
1214
|
+
|
|
1215
|
+
An immutable `PreparedPlan` is stored as an existing campaign version; it is review
|
|
1216
|
+
evidence, not approval authority. Receipt state and unresolved exposure remain
|
|
1217
|
+
separate from approval. An uncertain provider admission requires reconciliation
|
|
1218
|
+
before retry; it must not release liability or repeat creation automatically.
|
|
1219
|
+
|
|
1220
|
+
Metric observations distinguish observed zero from unknown, insufficient, delayed
|
|
1221
|
+
and unavailable values, retain window/timezone and native-unit evidence, and use
|
|
1222
|
+
exact counts/money/ratios. Consent and conversion parsers validate scoped evidence;
|
|
1223
|
+
a browser cannot mint a trusted lead by passing validation. Accepted source rows,
|
|
1224
|
+
current consent/withdrawal and experiment exposure must be verified server-side.
|
|
1225
|
+
No scripts, credentials, cookies or customer personal data belong in these DTOs.
|
|
1226
|
+
|
|
1227
|
+
|
|
1228
|
+
The save/binding/accept command parsers use the same strict wire rules. Updates
|
|
1229
|
+
require an expected root revision; root creation can omit it. Account bindings
|
|
1230
|
+
select existing provider resources, never credentials. Optimizer evidence and
|
|
1231
|
+
immutable decisions have separate parsers: they retain unknown tracking/power
|
|
1232
|
+
checks, exact before/after allocations and remote snapshot identities. Resolve
|
|
1233
|
+
minimum evidence, lag, cooldown and mandate coverage from the referenced frozen
|
|
1234
|
+
policy on the server. Parsed metrics or an actionable decision alone never grant
|
|
1235
|
+
spending authority. A blocked or no-op decision cannot carry allocation effects.
|
|
1236
|
+
|
|
1237
|
+
|
|
1238
|
+
Public measurement configuration is a separate closed DTO. It carries only typed
|
|
1239
|
+
Google Ads tag/Meta pixel identifiers, permitted resource rules and basic consent
|
|
1240
|
+
policy. A measurement occurrence is a view, explicit interest or experiment
|
|
1241
|
+
exposure; it cannot declare an accepted conversion. Consent updates preserve
|
|
1242
|
+
unknown, denied and withdrawn states. These parsers don't load any tags, collect
|
|
1243
|
+
browser data or turn a reported grant into server-verified permission. The browser
|
|
1244
|
+
runtime and server evidence/withdrawal checks must implement those controls.
|
|
1245
|
+
|
|
1246
|
+
Page-view occurrences can include optional `clickIdentifiers`, with exactly one
|
|
1247
|
+
closed shape: `{ gclid: string }`, `{ gbraid: string }` or `{ wbraid: string }`.
|
|
1248
|
+
`parseResonanceClickIdentifiers`, `ResonanceClickIdentifiers` and
|
|
1249
|
+
`RESONANCE_CLICK_IDENTIFIERS_JSON_SCHEMA` share that boundary. Values contain
|
|
1250
|
+
1 to 1024 characters, with no whitespace or control characters. This is the
|
|
1251
|
+
application's transport bound. Other occurrence kinds reject the field.
|
|
1252
|
+
The browser reads the current URL only after the required advertising grants
|
|
1253
|
+
and scoped proof are available. An observed identifier doesn't authenticate a
|
|
1254
|
+
paid click. The server must verify the same subject, site, current consent and
|
|
1255
|
+
actual form occurrence before using it for conversion matching. Identifiers
|
|
1256
|
+
don't belong in public configuration, receipts, results or logs. Deploy the
|
|
1257
|
+
accepting server parser before enabling browser emission.
|
|
1258
|
+
|
|
1259
|
+
Initial acceptance uses only `{ expectedRevision, ledgerActionId }`. The server
|
|
1260
|
+
loads the approved native payload and current kill state and returns the canonical
|
|
1261
|
+
mandate reference. Clients must never guess a kill revision to construct authority.
|
|
1262
|
+
|
|
1263
|
+
|
|
1264
|
+
Managed definitions contain the closed `optimization.policy`; prepared plans freeze
|
|
1265
|
+
an identical `resolvedEvidencePolicy`. Initial inline policies have `sourceRef: null`.
|
|
1266
|
+
A genuine existing source can supply optional provenance, but a new campaign doesn't
|
|
1267
|
+
need a synthetic experiment, self-referencing plan or new policy table. The first
|
|
1268
|
+
algorithm is explicitly observational qualified-lead CPQL allocation with approved
|
|
1269
|
+
maturity, coverage, uncertainty, attribution, lag and cooldown values. Executable
|
|
1270
|
+
allocation and current source/mandate admission remain server-owned.
|
|
1271
|
+
|
|
1272
|
+
### Finite preapproved Meta candidates
|
|
1273
|
+
|
|
1274
|
+
The optimization policy also supports the closed `finite_meta_candidates_v1`
|
|
1275
|
+
branch with `decisionKind: 'preapproved_candidate_operation'`. One policy
|
|
1276
|
+
variant belongs to each original plan. The existing mature allocation branch
|
|
1277
|
+
keeps its meaning and shape.
|
|
1278
|
+
|
|
1279
|
+
The finite policy uses `candidateChannelIds` to reference original Meta channels
|
|
1280
|
+
in the same definition. Their existing creatives, account, site, independent
|
|
1281
|
+
adset lifetime cap and original budget flight remain authoritative. The policy
|
|
1282
|
+
doesn't copy those inputs or contain compiled graph hashes. It records an exact
|
|
1283
|
+
reviewed order and schedule, one activation per candidate, concurrency, allowed
|
|
1284
|
+
actions, a typed exploration ceiling, tracking requirements and hard stops.
|
|
1285
|
+
`performanceDecisionPolicy` is explicitly `null`: this profile supports fixed
|
|
1286
|
+
exploration and approved safety stops, with no measured winner, adaptive pruning,
|
|
1287
|
+
budget increase, promotion or causal A/B claim.
|
|
1288
|
+
|
|
1289
|
+
Preparation resolves the original graphs and binds them with the policy in the
|
|
1290
|
+
existing review digest. The existing mandate seals that review. Later evidence
|
|
1291
|
+
and decisions reference the resulting graph identities; their hashes never feed
|
|
1292
|
+
back into the definition policy. No new policy registry or mandate field is used.
|
|
1293
|
+
|
|
1294
|
+
`ResonanceFiniteMetaCandidatePolicy`, `ResonanceFiniteMetaCandidateEvidence` and
|
|
1295
|
+
`ResonancePreapprovedCandidateOperationDecision` narrow the existing generic
|
|
1296
|
+
types. Their parsers, JSON Schemas and digest helpers share the existing
|
|
1297
|
+
`resonance` entry. Cold lifecycle evidence records unobserved measurement as
|
|
1298
|
+
`null`, with no borrowed donor outcomes or invented mature zero. An actionable
|
|
1299
|
+
decision carries exactly one `materialize_and_activate`, `activate_held` or
|
|
1300
|
+
`pause_candidate` action. Blocked and no-op decisions carry none. These decisions
|
|
1301
|
+
don't carry mature adjustments or a fabricated zero-to-cap transfer.
|
|
1302
|
+
|
|
1303
|
+
Pass the actual prepared plan as the optional second argument to
|
|
1304
|
+
`parseResonanceOptimizationEvidence` to check original public scope, manifest,
|
|
1305
|
+
cap and flight. Pass actual evidence and, when available, that plan as the second
|
|
1306
|
+
and third arguments to `parseResonanceOptimizationDecision` to check policy,
|
|
1307
|
+
action, fixed order, freshness and commitment-reference consistency. Parsing a
|
|
1308
|
+
standalone object checks its closed shape; it can't authenticate referenced rows
|
|
1309
|
+
or establish approval. Servers must load and verify the actual accepted plan,
|
|
1310
|
+
native claim, current permission and protected evidence before admission.
|
|
1311
|
+
|
|
1312
|
+
The API and database reserve the full independent cap before the first create.
|
|
1313
|
+
Activating an already paused candidate adds no new exposure only when its exact
|
|
1314
|
+
original physical commitment is already fully held. Resource presence or a
|
|
1315
|
+
reference alone doesn't prove that condition. Pause and donor decreases don't
|
|
1316
|
+
release old holds; uncertain effects retain their original key and reconcile.
|
|
1317
|
+
The public optimize command and existing Ledger workflow are unchanged.
|
|
1318
|
+
|
|
1319
|
+
Provider spend, clicks and impressions retain their own `provider_aggregate`
|
|
1320
|
+
counting unit and `provider_reported` attribution. First-party qualified-cohort
|
|
1321
|
+
observations keep the original objective's counting unit and attribution model.
|
|
1322
|
+
They aren't interchangeable evidence, and neither enables a performance
|
|
1323
|
+
decision in this fixed profile.
|
|
1324
|
+
|
|
1325
|
+
Ordinary optimize actions, including an explicitly allowed candidate pause,
|
|
1326
|
+
remain inside the current policy and mandate expiry. At or after expiry,
|
|
1327
|
+
creation and activation stop; any needed pause uses the existing current-owner
|
|
1328
|
+
safety pause or escalation path. This contract doesn't create post-expiry
|
|
1329
|
+
permission or a second stop-validity clock.
|
|
1330
|
+
|
|
1331
|
+
Public measurement transport uses the dedicated `X-Sonor-Resonance-Subject`
|
|
1332
|
+
header. Config reads do not issue identity. Only an explicit preference action
|
|
1333
|
+
can receive `subjectProof`, `expiresAt`, `currentConsentRevision` and the four
|
|
1334
|
+
purpose receipts. This is an opaque scoped proof, kept in browser memory. Proof expiry isn't
|
|
1335
|
+
consent expiry and must not force recurring consent prompts. Valid current CMP
|
|
1336
|
+
state may support scoped proof renewal/resumption through the authoritative API;
|
|
1337
|
+
until a valid proof is available, exports stay off. Config itself never bootstraps identity.
|
|
1338
|
+
`expectedConsentRevision` atomically fences the complete subject preference batch.
|
|
1339
|
+
The browser must discard stale grant replies, stop immediately on withdrawal,
|
|
1340
|
+
and never replay pre-consent events or bootstrap identity on config/page load.
|
|
1341
|
+
These contracts describe evidence, not an implemented transport or real-person identity.
|
|
1342
|
+
|
|
1343
|
+
|
|
1344
|
+
Tracking-only legacy campaign views retain revision zero; managed campaigns require
|
|
1345
|
+
at least revision one. Creation can adopt a tracking root at zero, but updates need
|
|
1346
|
+
a managed revision. Unknown admission in any child forces reconciliation and cannot
|
|
1347
|
+
be hidden by a failed root label or retry advice. Known reconciled/rejected work
|
|
1348
|
+
may still retry the same original operation when the server authorizes it.
|
|
1349
|
+
|
|
1350
|
+
`parseResonanceSubjectRenewCommand` accepts only current consent/config/policy
|
|
1351
|
+
revisions. Renewal rotates a proof without granting or changing consent. It requires
|
|
1352
|
+
the scoped subject transport and current server/CMP checks; it isn't permission to
|
|
1353
|
+
bootstrap identity from a config read or recover someone else's receipt.
|
|
1354
|
+
|
|
1355
|
+
|
|
1356
|
+
Public renewal includes schema version and the asserted project/site envelope as
|
|
1357
|
+
well as current revisions; the server resolves and verifies that scope from proof
|
|
1358
|
+
and credential. Finite allocation horizons carry verified UTC start/end, timezone
|
|
1359
|
+
and source revision, so eligible total/lifetime budgets can be compared on the
|
|
1360
|
+
same actual period without relabeling daily averages as hard lifetime caps.
|
|
1361
|
+
|
|
1362
|
+
`cpqlMissingOutcomeBound` computes the named observational sensitivity method from
|
|
1363
|
+
trusted unique-contact totals: eligible `n`, fully resolved attribution/dedupe/final
|
|
1364
|
+
qualification intersection `c`, and qualified subset `k`. It returns the ceiling of
|
|
1365
|
+
`10000*(n-c)/(2*k+n-c)`, or unknown when no positive source universe exists. This
|
|
1366
|
+
isn't statistical confidence, causal lift or permission to inject counts from a
|
|
1367
|
+
browser. API source producers must verify the complete universe and spend period;
|
|
1368
|
+
without that witness, the evidence bound remains unknown. Coverage stays separate.
|
|
1369
|
+
|
|
1370
|
+
### Successor management and attribution fields
|
|
1371
|
+
|
|
1372
|
+
The local 2.20 candidate adds `@sonordev/contracts/signal-experiments` as the
|
|
1373
|
+
single parser for the existing Signal create/update payload. It exports
|
|
1374
|
+
`parseSignalExperimentCreate`, `parseSignalExperimentUpdate`, their types and
|
|
1375
|
+
JSON Schemas. Both operations check unique variant keys and the existing
|
|
1376
|
+
weight-sum tolerance of 0.01. Percentages must be finite and within 0 to 100.
|
|
1377
|
+
Optional allocation and targeting defaults remain the existing service's job.
|
|
1378
|
+
Parsing doesn't grant access or select a variant.
|
|
1379
|
+
|
|
1380
|
+
`/resonance` adds audience draft save and experiment create/update, lifecycle,
|
|
1381
|
+
complete and link command parsers. Each managed experiment command requires
|
|
1382
|
+
`expectedRevision` and `idempotencyKey`. Audience drafts reference the current
|
|
1383
|
+
measurement config's resource rule IDs. The server resolves their scope and
|
|
1384
|
+
provider retention limit. Saving a draft uploads no people or audiences.
|
|
1385
|
+
|
|
1386
|
+
Public source markers use the `sonor_source` parameter and bounded
|
|
1387
|
+
`rsm1.<claims>.<signature>` format. A prepared channel preview can carry an
|
|
1388
|
+
`attributionMarker`; its destination URL must contain exactly that reviewed
|
|
1389
|
+
marker. An occurrence can carry the bounded `sourceMarker` value. The pure
|
|
1390
|
+
parser checks format and URL coherence. The server verifies the signature,
|
|
1391
|
+
purpose, accepted immutable plan and actual resource scope.
|
|
1392
|
+
|
|
1393
|
+
`first_party_last_touch_marker_v1` describes server-recorded first-party source
|
|
1394
|
+
mapping under the reviewed attribution window. It doesn't establish a paid
|
|
1395
|
+
click, a human visit or a causal effect. Unresolved source linkage stays
|
|
1396
|
+
unallocated. The existing resource, audience-rule and experiment-reference
|
|
1397
|
+
readers are also exported so owner projections can use the same validators.
|
|
1398
|
+
|
|
1399
|
+
Qualified-lead prepared plans require a non-null `resolvedQualificationRule`.
|
|
1400
|
+
Other objectives carry an explicit null. The objective keeps the selected
|
|
1401
|
+
`qualificationRule`; the prepared projection shows its actual CRM project ref,
|
|
1402
|
+
`crmVariant`, native `ladderSnapshot`, eligible form and cohort boundaries.
|
|
1403
|
+
`semantic_key` and native preset stage IDs can be null. The parser preserves
|
|
1404
|
+
those native values and never manufactures a stage UUID or infers qualification
|
|
1405
|
+
from a stage's position or won/lost flag.
|
|
1406
|
+
|
|
1407
|
+
The three selected stage partitions must be disjoint and exhaust the resolved
|
|
1408
|
+
native ladder. The public projection must match the selected partitions, native
|
|
1409
|
+
ref, source form, counting unit and maturity delay. API persistence resolves one
|
|
1410
|
+
canonical witness and uses that same object for internal resource evidence and
|
|
1411
|
+
public review. The server must verify its actual source and digest. These shape
|
|
1412
|
+
checks don't establish that a caller supplied genuine database rows.
|
|
1413
|
+
|
|
1414
|
+
`PreparedPlan.expiresAt` is an initial acceptance freshness deadline. Continuing
|
|
1415
|
+
an already accepted campaign uses its current native mandate and budget limits,
|
|
1416
|
+
with current resource and capability checks. The pure initial-readiness helper
|
|
1417
|
+
doesn't replace those authority checks.
|
|
1418
|
+
|
|
1419
|
+
### Preparing a campaign command
|
|
1420
|
+
|
|
1421
|
+
`parseResonanceCommandPrepareRequest` reads only `expectedRevision` and `idempotencyKey`. The API resolves the accepted plan, current resources and authority for launch, update or resume. `parseResonanceCommandPrepareResponse` reads `{ command, covered, approvalRequirement, reasonCodes }`, where `command` may be `null` and `approvalRequirement` is `existing_mandate`, `current_owner` or `null`. A covered command still needs its required native approval and claim. Resume after a pause requires the current owner's approval through the existing action ledger.
|
|
1422
|
+
|
|
1423
|
+
`@sonordev/contracts/resonance-constants` exports `RESONANCE_SUBJECT_HEADER`, `RESONANCE_SOURCE_MARKER_PARAMETER` and `RESONANCE_ATTRIBUTION_MODEL` without loading campaign schemas. The main Resonance entry re-exports these same literals. Browser adapters can use the constants entry when they don't need a parser.
|
|
1424
|
+
|
|
1425
|
+
### Delivering a qualified Google conversion
|
|
1426
|
+
|
|
1427
|
+
The existing `ResonanceCommand` union adds `operation: 'deliver_conversion'`. It requires the usual schema version, campaign, prepared plan, review digest, expected revision, idempotency key and mandate reference, plus `channelIds` with exactly one original Google channel and `conversionId` for the persisted canonical qualified fact. The command carries no click identifiers, personal data, provider payload, values, timestamps, native destination or approval flags.
|
|
1428
|
+
|
|
1429
|
+
The original mandate must explicitly include `deliver_conversion` in `allowedOperations`. A launch-only grant doesn't gain delivery permission. The existing original review binds the goal, source, qualification witness and Google configuration; there's no second delivery policy object. The initial profile is `qualified_at_observation_v1` for one managed-form qualified source and one destination. Existing goals with multiple actions are rejected for delivery. Cross-account action ownership remains unsupported.
|
|
1430
|
+
|
|
1431
|
+
`parseResonanceCommand(value, { preparedPlan, mandate, now })` optionally checks those actual parsed objects for original scope and prepared definition revision, goal, budget, account, site, single-action Google profile and the original dispatch window. The one-argument call remains shape validation. An accepted plan's initial freshness deadline doesn't create a reporting tail: new dispatch must remain within its original mandate and budget window. Ordinary delivery stops after expiry; read-only receipt reconciliation doesn't resend it.
|
|
1432
|
+
|
|
1433
|
+
These checks don't authenticate a persisted fact, current principal, kill or finish state, qualification, consent continuity, native claim or export deduplication. The server must verify the protected same-root goal-installation receipt and current native ownership. Setup intent only binds the reviewed local action and strategy; actual destination resolution requires its original successful native setup receipts. Missing or stale provenance blocks delivery. Parsing neither proves that setup ran nor authorizes a provider request. Accepted provider ingestion doesn't establish attribution or bidding success.
|
|
1434
|
+
|
|
1435
|
+
### Google campaign configuration
|
|
1436
|
+
|
|
1437
|
+
`parseResonanceGoogleConfigurationSaveCommand` reads a strict draft request
|
|
1438
|
+
with `schemaVersion: 1`, `expectedCampaignRevision`, `expectedRevision`,
|
|
1439
|
+
`idempotencyKey`, the required `signalSemantics`,
|
|
1440
|
+
`declaration: { statement, category }` and one top-level mode:
|
|
1441
|
+
|
|
1442
|
+
- `existing`: `nativeGoal: { externalId, actionIds }`, using full native Google
|
|
1443
|
+
resource names. The unique action set is sorted by the parser.
|
|
1444
|
+
- `admitted_setup`: `setupIntent: { requestedGoalName, requestedActionName }`.
|
|
1445
|
+
These are intended display names, bounded to 160 characters, not purported
|
|
1446
|
+
native resources. The server
|
|
1447
|
+
derives the complete setup specification.
|
|
1448
|
+
|
|
1449
|
+
Revision `0` expects no saved configuration. The server checks the campaign
|
|
1450
|
+
and configuration revisions and recovers the original operation by its key.
|
|
1451
|
+
Parsing doesn't save, approve or spend anything. Save the campaign and channel
|
|
1452
|
+
first, retain their IDs, then save their configuration. The configuration
|
|
1453
|
+
response supplies the resulting `campaignRevision`, configuration `revision`,
|
|
1454
|
+
`operationId` and `replayed`. Retry an uncertain save with its original key and
|
|
1455
|
+
body before starting another operation. Re-read the actual campaign after an
|
|
1456
|
+
uncertain initial draft save; its stable ID may now have a later revision.
|
|
1457
|
+
|
|
1458
|
+
The required `signalSemantics` is `qualified_at_observation_v1` for both
|
|
1459
|
+
modes and the setup specification. It describes an explicitly reviewed
|
|
1460
|
+
**historical provider bid signal**, distinct from Sonor's unchanged
|
|
1461
|
+
`current_at_observation` qualified counts. It doesn't promise equal counts or
|
|
1462
|
+
provider count retraction. Existing and new setup profiles currently support
|
|
1463
|
+
only `qualified_lead` with `unique_qualified_contact` and a 1–90 day window.
|
|
1464
|
+
Actual producer eligibility, permanent contact/destination deduplication and
|
|
1465
|
+
delivery remain server checks. Other goal profiles are unsupported.
|
|
1466
|
+
|
|
1467
|
+
The declaration's explicit statement is
|
|
1468
|
+
`DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING`; its category is `general`,
|
|
1469
|
+
`housing`, `employment` or `financial_products_services`. The server binds it
|
|
1470
|
+
to actual source, account, creative, copy, destination and region scope, with
|
|
1471
|
+
the actual declarant UUID, timestamp and original
|
|
1472
|
+
`declaredForCampaignRevision`. No permanent statement is inferred from a brand
|
|
1473
|
+
or site. These fields aren't approval identities. The exact statement and
|
|
1474
|
+
resource effects are reviewed within the same campaign mandate.
|
|
1475
|
+
|
|
1476
|
+
`parseResonanceGoogleConfigurationSnapshot` reads the canonical public snapshot
|
|
1477
|
+
with `configurationRevision` and `configurationDigest`. Its top-level mode
|
|
1478
|
+
remains explicit. Existing-mode native goal name and revision may be `null`
|
|
1479
|
+
when draft evidence is unavailable; a real empty provider label stays empty.
|
|
1480
|
+
`parseResonanceGoogleConfigurationReview` requires actual name and SHA-256
|
|
1481
|
+
revision for existing mode.
|
|
1482
|
+
|
|
1483
|
+
Setup mode contains `setupSpec` and `setupDigest`, with no `nativeGoal` or
|
|
1484
|
+
purported native ID/revision. `ResonanceGoogleUploadClicksCustomGoalSpec` has
|
|
1485
|
+
one singular `action`, one matching `goalActionKey`, fixed local dependency
|
|
1486
|
+
keys, requested names and `exclusive_custom_goal_v1`. There are no
|
|
1487
|
+
`actions[]` or `goalActionKeys[]` aliases. The bounded first setup profile is
|
|
1488
|
+
`qualified_lead` with `unique_qualified_contact`, an `UPLOAD_CLICKS` action,
|
|
1489
|
+
`QUALIFIED_LEAD`, `ONE_PER_CLICK`, `primaryForGoal: false`, and the exact
|
|
1490
|
+
objective attribution window from 1 through 90 days. Other new setup pairs
|
|
1491
|
+
are unsupported; longer windows aren't clamped. Actual contact deduplication
|
|
1492
|
+
and delivery identity remain upstream responsibilities. Native per-click
|
|
1493
|
+
counting doesn't implement global contact deduplication. Canonical outcomes
|
|
1494
|
+
and provider reports remain separate.
|
|
1495
|
+
|
|
1496
|
+
`projectResonanceGoogleConfiguration(snapshot, { ready, activationReadiness,
|
|
1497
|
+
reasonCodes })` is the one public view/review projection. The view renames
|
|
1498
|
+
`configurationRevision` to `revision` and adds fresh resolver metadata.
|
|
1499
|
+
`ready` means reviewable, not activated: planned setup uses `pending_setup`,
|
|
1500
|
+
unready configuration uses `blocked`, and existing setup requires final
|
|
1501
|
+
verification or verified native evidence. An unready view returns
|
|
1502
|
+
`review: null`. The corresponding view/save-response parsers validate these
|
|
1503
|
+
shapes without granting authority.
|
|
1504
|
+
|
|
1505
|
+
`resonanceGoogleSetupDigestInput` and
|
|
1506
|
+
`resonanceGoogleConfigurationDigestInput` return canonical JSON for the server
|
|
1507
|
+
hash function. The configuration input omits only its self
|
|
1508
|
+
`configurationDigest`; initial content needs no placeholder. Private
|
|
1509
|
+
eligibility or authorization evidence doesn't belong in this public snapshot.
|
|
1510
|
+
`RESONANCE_GOOGLE_SOURCE_CATEGORIES` and `googleConversionActionSemantics`
|
|
1511
|
+
share native vocabulary with explicit counting and window inputs; vocabulary
|
|
1512
|
+
membership grants no broader setup eligibility.
|
|
1513
|
+
`googleUploadClicksSetupSemantics({ source, countingUnit, attributionWindowDays })`
|
|
1514
|
+
is the shared narrow policy check. It doesn't establish an actual source
|
|
1515
|
+
producer or delivery identity.
|
|
1516
|
+
|
|
1517
|
+
Every prepared preview requires `googleConfiguration`: a strict existing or
|
|
1518
|
+
setup review for Google Search, explicit `null` for other channel kinds.
|
|
1519
|
+
Project, campaign, channel, site, account binding, source, measurement,
|
|
1520
|
+
counting, window and regions must match the enclosing plan. Preparing setup
|
|
1521
|
+
performs no provider mutation. After the same native mandate and admission,
|
|
1522
|
+
actual receipts resolve local keys to native IDs without rewriting the
|
|
1523
|
+
accepted public plan. Activation still needs current native eligibility,
|
|
1524
|
+
source, consent and authority checks. No parser proves those checks occurred.
|
|
1525
|
+
|
|
1526
|
+
|
|
1527
|
+
### Original Meta website-visit feed
|
|
1528
|
+
|
|
1529
|
+
`ResonanceMandateScope` accepts an optional `websiteVisitFeed` with the profile `sonor_sdk_page_view_fresh_v1` and a `channels` list. Each entry selects an original Meta channel, a `measurementConfigRef`, `resourceRuleRefs` and a `matchingProfileRef`. Account, dataset and site come from that same channel in the reviewed plan. The matching-profile reference identifies the protected configuration-save receipt, its positive integer CAS revision and its digest. No feed is granted when the field is absent. A launch permission, measurement setting or visitor consent alone doesn't grant this feed.
|
|
1530
|
+
|
|
1531
|
+
`RESONANCE_WEBSITE_VISIT_PROFILE` is the fixed, immutable local policy. `resonanceWebsiteVisitProfileDigestInput()` returns its canonical bytes for the server to hash. `resonanceMeasurementConfigDigestInput(config)` parses the measurement config and returns canonical semantic bytes, excluding only `expiresAt`. Current expiry still needs a separate check at capture and every dispatch. Renewal changes no original grant window; a semantic change at the same revision changes the digest. Both helpers retain approved list order and use the same canonical serializer as the existing mandate and command digests.
|
|
1532
|
+
|
|
1533
|
+
The existing command union adds `deliver_website_visit` for the protected native operation path. It carries one original Meta channel and an internal `occurrenceId`, alongside the existing plan, review, revision, idempotency and mandate references. It carries no matching values, timestamps, dataset or provider body. `parseResonanceCommand(value, { preparedPlan, mandate, now })` checks original public grant consistency; it can't establish a protected producer, native claim or permission to send. Manual, public API and MCP entry points must reject attempts to originate this command. Native consumers must use the existing action ledger, standing approval and durable admission path.
|
|
1534
|
+
|
|
1535
|
+
Measurement occurrences gain optional `pagePath` and `metaCookieObservation` fields on `page_view` only. The cookie observation has source `sdk_reported_first_party_cookie` and one or both actual reported `fbp`/`fbc` values. Each value is limited to 1–1024 characters with no whitespace or controls. Matching requires the path and existing resource reference on that same occurrence and navigation. The API must verify the owned site and exact approved rule/path/resource. A separate-origin API can't infer the site's first-party cookies from its own Cookie header. Raw matching belongs only in protected capture persistence, never ledger payloads, operation requests, results, receipts, public configuration or read responses.
|
|
1536
|
+
|
|
1537
|
+
This is an SDK-reported observation. It doesn't prove that a person rendered a page or create a qualified lead or business conversion. The server-only event ID is the internal occurrence UUID; browser/server pairing is unsupported when the browser uses its different public event ID.
|
|
1538
|
+
|
|
1539
|
+
`resonanceWebsiteVisitEventTime({ occurredAt, receivedAt }, { mandate, approvedAt, now })` checks the local time arithmetic and returns epoch seconds from the original reported `occurredAt`. The first receipt and final attempt must each be within 300,000 milliseconds of that original time, inclusive, with zero future allowance. Both original times must follow the original accepted feed approval and stay within its original window. It never substitutes receipt, retry or regrant time. This is Sonor's conservative policy, not a Meta age limit or acceptance guarantee. An authenticated exact-body replay must return its original stored identity and first receipt before new-capture age checks, without insertion, enrichment, queueing or resend. Current consent epochs, grant, kill, claim and global dedupe checks remain native owner responsibilities.
|
|
1540
|
+
|
|
1541
|
+
These pure contracts don't install capture, a protected configuration writer, a matching-profile producer or native delivery. Those owners must implement and verify the actual preparation, original-delivery and terminal non-effect response boundaries before adoption. Parsing a valid payload doesn't make a provider ready or prove delivery.
|
|
1542
|
+
|
|
1543
|
+
### Original Meta age selection
|
|
1544
|
+
|
|
1545
|
+
An original Meta channel accepts optional `ageConstraint: { mode: 'bounded', min, max } | { mode: 'omitted' } | { mode: 'provider_managed' }`. The provider-managed intent has separate native observation requirements described below. Bounded values are integers from 1 to 120 with `min <= max`; these are local transport bounds, not country, category or provider policy. An absent field preserves legacy bytes and leaves new preparation unresolved. It doesn't select a default. Explicit omission or bounds require an actual current policy witness, and native readback must account for any source-backed normalization. Adapters must block unknown policy rather than ignore the selection or invent ages. This representation doesn't establish that a compiler, account or provider supports it.
|
|
1546
|
+
|
|
1547
|
+
### Native measurement bootstrap and Meta configuration
|
|
1548
|
+
|
|
1549
|
+
The pure setup contracts describe native owner inputs and saved projections. They don't create provider resources, grant visitor consent, approve spend, or enable the website-visit feed. Native API, SQL, preparation, approval and provider owners must adopt and verify them separately.
|
|
1550
|
+
|
|
1551
|
+
`ResonanceMeasurementConfigurationSaveCommand` selects actual native pages using `{pageId, observedRevision, observedDigest}`. Its closed input also includes `schemaVersion: 1`, `site`, `expectedCampaignRevision`, `expectedConfigurationRevision`, `idempotencyKey`, `enabled` and the basic consent-purpose requirements. It accepts no caller path, rule ID, resource reference, expiry or readiness flag. The three advertising purpose requirements are mandatory; a requirement doesn't grant that purpose to a visitor.
|
|
1552
|
+
|
|
1553
|
+
The native sequence starts with a managed draft and its owned sites; channels can be absent or empty. Measurement bootstrap uses that real draft as an operation audit home. It creates no complete advertising channel. After saving real page rules, the existing audience owner can create logical rules, and the campaign owner can save a complete Meta channel with those returned references. Meta configuration then maps those same logical rules to existing native audiences or admitted creation intent. A present channel still requires its complete original fields.
|
|
1554
|
+
|
|
1555
|
+
Measurement configuration CAS is scoped to project/site. Zero expects actual absence; a legacy or malformed row without protected provenance must block. An audit campaign's revision check doesn't partition the site configuration or advance that campaign's review revision. `projectResonanceMeasurementConfiguration(command, context)` accepts an authorized project, protected current projection, reloaded safe page facts and a native transport expiry. It derives one rule per actual page UUID, sorted by page ID. The page resource revision is canonical UTC milliseconds; the rule revision is the existing full native evidence digest. This preserves distinctions between source updates within one millisecond. Native SQL must independently validate the facts and recompute CAS decisions under its locks.
|
|
1556
|
+
|
|
1557
|
+
Native semantic `configRevision` and `policyRevision` are positive decimal strings. Identical semantics and a new cache expiry preserve them. Page evidence, selected rules or enabled-state changes advance the configuration revision; only consent-policy changes advance the policy revision. Initial provider destinations are `[]`; updates preserve explicitly configured destinations. The helper returns the configuration, friendly page projections and `configurationDigestInput` from the existing `resonanceMeasurementConfigDigestInput`. Hash that exact string once. The save-request digest helper retains original request array order, while derived semantic pages and purposes are sorted.
|
|
1558
|
+
|
|
1559
|
+
Measurement `Current` distinguishes actual `unconfigured` revision zero from a saved `configured` projection with current reasons. `Snapshot` contains the original audit campaign, operation, configuration and friendly page evidence. `SaveResponse` adds `replayed`. The native owner must return an exact original same-key result before fresh CAS/source checks, while enforcing current read permission; a changed request conflicts. No parser proves native provenance.
|
|
1560
|
+
|
|
1561
|
+
The agreed native freshness model is one read-only current-configuration resolver. It checks actual current ownership, protected saved provenance, native page evidence, configuration and policy, then issues a 300-second cache envelope from the database clock. All native purpose, consent, intake, audience, attribution and feed gates must use that same resolver. Reads must not mutate settings, create renewal operations or change original saved bytes. The cache envelope never extends consent, capability, mandate, feed, flight or kill authority. Source drift requires an explicit protected save. This is an adoption requirement, not a claim that those native ports are implemented by this package.
|
|
1562
|
+
|
|
1563
|
+
`ResonanceMetaConfigurationSaveCommand` contains the expected campaign/configuration revisions, schema version, idempotency key and exact original logical audience mappings:
|
|
1564
|
+
|
|
1565
|
+
```ts
|
|
1566
|
+
{ audienceRuleId, mode: 'existing', nativeAudienceRef: { externalId, revision } }
|
|
1567
|
+
// or
|
|
1568
|
+
{ audienceRuleId, mode: 'admitted_setup' }
|
|
1569
|
+
```
|
|
1570
|
+
|
|
1571
|
+
The original channel remains the editable account, dataset, Page, Instagram, country, category, age, budget, creative and destination definition. Save accepts no duplicate channel, provider request, created audience ID for setup intent, matching data or approval flag. The existing native audience reference uses its actual numeric external ID and source evidence revision.
|
|
1572
|
+
|
|
1573
|
+
`ResonanceMetaConfigurationSnapshot` freezes the original channel, root/configuration revisions, reviewed definition digest, saved operation UUID, advertiser and nullable native names, measurement/profile references, friendly rules and resolved audiences. Each audience row is `{audienceRuleRef, name, resourceRuleRef, excludedResourceRuleRefs, selection}`. Its logical name is separate from `selection.nativeAudienceName`; its positive rule is separate from exclusions. Existing selection carries the native reference/name. Admitted selection carries `setup: {kind: 'meta_website_audience_v1', localOutputKey, specDigest}`. The local key is the original SDK `audience:<id>:<revision>` key; `specDigest` identifies the existing SDK audience input. Native HTTP request and compiled graph identities remain distinct private preparation evidence.
|
|
1574
|
+
|
|
1575
|
+
The matching-profile ID is the actual persisted save operation UUID. Its revision is the positive **integer** configuration CAS; measurement configuration/policy strings are different fields. Native save must atomically persist the real operation, settings and snapshot before exposing that reference. A new explicit Meta save advances its configuration CAS and campaign review revision; the snapshot carries the resulting root revision. A replay advances neither. Draft metadata receipts don't require fabricated prepared versions or operational channel rows.
|
|
1576
|
+
|
|
1577
|
+
`resonanceMetaConfigurationDigestInput` omits only its self digest and preserves all original material, including friendly labels. `projectResonanceMetaConfiguration(snapshot, currentMetadata)` returns `{view, review}`. Metadata contains `currentCampaignRevision`, native-owner-derived `currentDefinitionDigest`, `observedAt`, nullable `expiresAt`, `reasonCodes` and `pendingRequirements`. `readyForReview` is derived output: no blockers, a current root revision at least as new as the saved audit revision, an exact match between the current semantic definition digest and the saved reviewed definition digest, and a nonexpired observation horizon. Metadata-only root revision bumps can therefore preserve multiple unchanged channel configurations; original snapshots keep their real save revisions. Native owners must still verify the exact original channel, configuration CAS, saved operation, configuration digest and current source/resource/account/policy facts. A matching campaign digest never substitutes for those checks. The review is the unchanged original snapshot when those prerequisites hold, otherwise `null`. Pending native creation, validation or age observation never grants execution. Pure timestamp ordering doesn't prove freshness when a cached view is consumed; the actual owner and UI must withdraw stale reviewability.
|
|
1578
|
+
|
|
1579
|
+
### Explicit feed selection and original review
|
|
1580
|
+
|
|
1581
|
+
`parseResonanceMandateDraftRequest` preserves the existing `{expectedRevision, allowedOperations, expiresAt}` request and accepts an optional minimal selection:
|
|
1582
|
+
|
|
1583
|
+
```ts
|
|
1584
|
+
websiteVisitFeedSelection: {
|
|
1585
|
+
channels: [{ channelId, expectedConfigurationRevision, resourceRuleRefs: [{ id, revision }] }]
|
|
1586
|
+
}
|
|
1587
|
+
```
|
|
1588
|
+
|
|
1589
|
+
Absent selection preserves no-feed behavior. Empty lists, duplicate selectors, full editable grants and copied destination/profile/readiness fields are rejected. The native owner resolves the exact saved configuration, profile receipt and positive rule versions through the existing mandate authority. An excluded-only page can't become a selected feed permission.
|
|
1590
|
+
|
|
1591
|
+
The existing mandate-draft response remains the raw `ResonanceMandateApprovalPayload`. Before acceptance, reviewers use that original payload with exact immutable configuration review snapshots; mismatched refs, digests, revisions or plan material block review. Latest labels must not replace original reviewed labels. Actual native approval can use the existing legitimate member or invited delegated-agent authority.
|
|
1592
|
+
|
|
1593
|
+
`ResonanceWebsiteVisitFeedReview` is a separate **post-acceptance** projection: `{schemaVersion: 1, approval, mandateRef, configurations, current}`. It requires a genuine nonnull accepted mandate reference. Before acceptance, the native read returns its typed unavailable/not-found result. Original historical snapshots remain readable under current authorized scope when current state is invalidated or unavailable. `eligible` describes current review observation and grants no execution authority. No-feed requires `not_enabled` and an empty configuration list. The saved configuration audit revision can precede the exact original approval/plan revision, but can never follow it. The optional original prepared-plan context checks exact approval/plan revision, matching channel material and definition digest. Native original reads must supply the actual stored plan and verify the selected original configuration identities. Preparation, approval, claim and acceptance still require the exact current native root revision; this configuration review rule does not relax those fences. Actual approval provenance, hashes, source facts, consent and admission remain native checks.
|
|
1594
|
+
|
|
1595
|
+
Native owners plan separate original configuration and accepted feed-review reads under the existing protected configuration/mandate owners. This package adds no endpoint, approval surface or provider client. Public, manual and MCP entry points must continue to reject internal `deliver_website_visit` before filing; a parser or service label never proves protected origin.
|
|
1596
|
+
|
|
1597
|
+
### Provider-managed age intent
|
|
1598
|
+
|
|
1599
|
+
The additional closed original Meta intent is `{mode: 'provider_managed'}`. It accepts no bounds, default flag or observed native values and never replaces absent, `omitted` or `bounded` intent. Its review promise is: “Use Meta age settings; record the initial observed configuration before activation.”
|
|
1600
|
+
|
|
1601
|
+
Native create and validation requests must omit both age keys. Before activation, the first genuine same-root PAUSED AdSet creator receipt and complete scoped read must seal initial age values **and key presence** once in the existing protected operation. Activation must compare that unchanged observation and every independent non-age, consent, authority and budget gate. Later changes block. This intent makes no claim about exclusive default authorship, unlimited ages, legality or serving. Existing three-mode consumers need explicit preservation, editing and review support before adopting this branch.
|
|
@@ -85,6 +85,14 @@ export declare const BROADCAST_STYLES: readonly ['glass', 'editorial', 'poster',
|
|
|
85
85
|
export type BroadcastStyleId = (typeof BROADCAST_STYLES)[number];
|
|
86
86
|
export declare const DEFAULT_BROADCAST_STYLE: BroadcastStyleId;
|
|
87
87
|
export declare const isBroadcastStyleId: (value: unknown) => value is BroadcastStyleId;
|
|
88
|
+
/** Explicit per-review photo presentation; absence keeps the existing automatic layout. */
|
|
89
|
+
export declare const REVIEW_PHOTO_PRESENTATIONS: readonly ['background'];
|
|
90
|
+
export type ReviewPhotoPresentation = (typeof REVIEW_PHOTO_PRESENTATIONS)[number];
|
|
91
|
+
/**
|
|
92
|
+
* A supported explicit photo presentation. Optional input boundaries handle
|
|
93
|
+
* omission (preserve) and null (clear) separately; neither is an explicit value.
|
|
94
|
+
*/
|
|
95
|
+
export declare const isReviewPhotoPresentation: (value: unknown) => value is ReviewPhotoPresentation;
|
|
88
96
|
/**
|
|
89
97
|
* The review compositions Broadcast draws: `signature` (photo up top, the
|
|
90
98
|
* quote low) and `frame` (centered). Order matters: a review whose v1 draw
|
|
@@ -29,6 +29,8 @@ var SAVED_PUBLICATION_CARD_LAYOUTS = [AUTO_CARD_LAYOUT, ...CARD_LAYOUTS];
|
|
|
29
29
|
var BROADCAST_STYLES = ["glass", "editorial", "poster", "cinematic", "blueprint", "focus"];
|
|
30
30
|
var DEFAULT_BROADCAST_STYLE = "glass";
|
|
31
31
|
var isBroadcastStyleId = (value) => typeof value === "string" && BROADCAST_STYLES.includes(value);
|
|
32
|
+
var REVIEW_PHOTO_PRESENTATIONS = ["background"];
|
|
33
|
+
var isReviewPhotoPresentation = (value) => typeof value === "string" && REVIEW_PHOTO_PRESENTATIONS.includes(value);
|
|
32
34
|
var REVIEW_CARD_VARIATIONS = ["signature", "frame"];
|
|
33
35
|
var DEFAULT_REVIEW_CARD_VARIATION = "signature";
|
|
34
36
|
var RETIRED_REVIEW_CARD_VARIATIONS = {
|
|
@@ -71,12 +73,14 @@ exports.REVIEW_CARD_VARIATIONS = REVIEW_CARD_VARIATIONS;
|
|
|
71
73
|
exports.REVIEW_CARD_VARIATION_LABELS = REVIEW_CARD_VARIATION_LABELS;
|
|
72
74
|
exports.REVIEW_CARD_VARIATION_OPTIONS = REVIEW_CARD_VARIATION_OPTIONS;
|
|
73
75
|
exports.REVIEW_CARD_VARIATION_V1_DRAW = REVIEW_CARD_VARIATION_V1_DRAW;
|
|
76
|
+
exports.REVIEW_PHOTO_PRESENTATIONS = REVIEW_PHOTO_PRESENTATIONS;
|
|
74
77
|
exports.SAVED_PUBLICATION_CARD_LAYOUTS = SAVED_PUBLICATION_CARD_LAYOUTS;
|
|
75
78
|
exports.isArticleCoverLayoutId = isArticleCoverLayoutId;
|
|
76
79
|
exports.isBroadcastStyleId = isBroadcastStyleId;
|
|
77
80
|
exports.isCardLayoutId = isCardLayoutId;
|
|
78
81
|
exports.isRetiredCardLayoutId = isRetiredCardLayoutId;
|
|
79
82
|
exports.isReviewCardVariation = isReviewCardVariation;
|
|
83
|
+
exports.isReviewPhotoPresentation = isReviewPhotoPresentation;
|
|
80
84
|
exports.normalizeArticleCoverLayout = normalizeArticleCoverLayout;
|
|
81
85
|
exports.normalizeReviewCardVariation = normalizeReviewCardVariation;
|
|
82
86
|
exports.reviewCardVariationFromDigest = reviewCardVariationFromDigest;
|
|
@@ -27,6 +27,8 @@ var SAVED_PUBLICATION_CARD_LAYOUTS = [AUTO_CARD_LAYOUT, ...CARD_LAYOUTS];
|
|
|
27
27
|
var BROADCAST_STYLES = ["glass", "editorial", "poster", "cinematic", "blueprint", "focus"];
|
|
28
28
|
var DEFAULT_BROADCAST_STYLE = "glass";
|
|
29
29
|
var isBroadcastStyleId = (value) => typeof value === "string" && BROADCAST_STYLES.includes(value);
|
|
30
|
+
var REVIEW_PHOTO_PRESENTATIONS = ["background"];
|
|
31
|
+
var isReviewPhotoPresentation = (value) => typeof value === "string" && REVIEW_PHOTO_PRESENTATIONS.includes(value);
|
|
30
32
|
var REVIEW_CARD_VARIATIONS = ["signature", "frame"];
|
|
31
33
|
var DEFAULT_REVIEW_CARD_VARIATION = "signature";
|
|
32
34
|
var RETIRED_REVIEW_CARD_VARIATIONS = {
|
|
@@ -53,4 +55,4 @@ function reviewCardVariationFromDigest(digest) {
|
|
|
53
55
|
return isReviewCardVariation(drawn) ? drawn : REVIEW_CARD_VARIATIONS[uint32BE(digest, 4) % REVIEW_CARD_VARIATIONS.length];
|
|
54
56
|
}
|
|
55
57
|
|
|
56
|
-
export { ARTICLE_COVER_LAYOUTS, AUTO_CARD_LAYOUT, BROADCAST_LAYOUTS_CONTRACT_VERSION, BROADCAST_STYLES, CARD_LAYOUTS, CARD_LAYOUT_LABELS, CARD_LAYOUT_OPTIONS, DEFAULT_BROADCAST_STYLE, DEFAULT_REVIEW_CARD_VARIATION, PUBLICATION_CARD_LAYOUTS, RETIRED_CARD_LAYOUTS, RETIRED_REVIEW_CARD_VARIATIONS, REVIEW_CARD_VARIATIONS, REVIEW_CARD_VARIATION_LABELS, REVIEW_CARD_VARIATION_OPTIONS, REVIEW_CARD_VARIATION_V1_DRAW, SAVED_PUBLICATION_CARD_LAYOUTS, isArticleCoverLayoutId, isBroadcastStyleId, isCardLayoutId, isRetiredCardLayoutId, isReviewCardVariation, normalizeArticleCoverLayout, normalizeReviewCardVariation, reviewCardVariationFromDigest, reviewCompositionSeed };
|
|
58
|
+
export { ARTICLE_COVER_LAYOUTS, AUTO_CARD_LAYOUT, BROADCAST_LAYOUTS_CONTRACT_VERSION, BROADCAST_STYLES, CARD_LAYOUTS, CARD_LAYOUT_LABELS, CARD_LAYOUT_OPTIONS, DEFAULT_BROADCAST_STYLE, DEFAULT_REVIEW_CARD_VARIATION, PUBLICATION_CARD_LAYOUTS, RETIRED_CARD_LAYOUTS, RETIRED_REVIEW_CARD_VARIATIONS, REVIEW_CARD_VARIATIONS, REVIEW_CARD_VARIATION_LABELS, REVIEW_CARD_VARIATION_OPTIONS, REVIEW_CARD_VARIATION_V1_DRAW, REVIEW_PHOTO_PRESENTATIONS, SAVED_PUBLICATION_CARD_LAYOUTS, isArticleCoverLayoutId, isBroadcastStyleId, isCardLayoutId, isRetiredCardLayoutId, isReviewCardVariation, isReviewPhotoPresentation, normalizeArticleCoverLayout, normalizeReviewCardVariation, reviewCardVariationFromDigest, reviewCompositionSeed };
|