Skip to article

LinkedIn retargeting for B2B: build the audience and choose the next message

Start with the action

Four separate states for source, audience population, delivery and business outcome
Keep source, population, delivery and outcome separate. A missing state returns Hold with a named request.

LinkedIn retargeting works when you begin with a recorded action, not a vague group called “warm traffic.” Choose the LinkedIn source that can prove that action. Record what is available now. Exclude people who have already completed the next step. Then choose one message that answers the question their action is likely to raise.

Keep the plan on Hold when the source, permission, audience status, suppression or downstream measurement is missing. A complete plan is ready for an operator to review. It does not create an audience, authorize spend, launch ads or prove results.

Use the source-to-message planner on this page to produce both a readable handoff and a structured record. The same record keeps four states separate:

  1. Source: Is the qualifying action available and supported by evidence?
  2. Population: Has LinkedIn processed enough matched member accounts for the audience to be usable?
  3. Delivery: Did an approved ad set actually serve to this audience?
  4. Outcome: Did the next action reach the CRM and contribute to a qualified business event?

A signal can exist while the other three states remain Unknown.

Choose the source that matches the action

LinkedIn currently documents website visits, single-image engagement, document engagement, video views, Lead Gen Form activity, Conversation Ad activity, Company Page activity, Event activity and Conversions API signals as retargeting sources. LinkedIn also supports Matched Audiences built from contact lists.

Use that list to choose a source. Finish the plan with current evidence, suppressions, the next message and downstream measurement. Start with the action you can actually observe.

Observed actionLinkedIn sourceChoice you must recordFirst evidence request
Visited a pricing, product or other specific pageWebsiteWebsite Action or URL rule; lookback windowActive Insight Tag, exact page/action rule and current signal state
Viewed a video adVideoAt least 25%, 50%, 75% or 97% viewed; 30, 60, 90, 180 or 365 daysSelected video ad set, threshold, window and current audience status
Opened or submitted a Lead Gen FormLead Gen FormOpened versus submitted; 30, 60, 90, 180 or 365 daysSelected form/ad set, action, window and current audience status
Interacted with a single-image adSingle imageAny interaction versus chargeable click; a window from 30 to 365 daysSelected ad set, interaction rule and current audience status
Downloaded, interacted with or clicked a document adDocumentDownload/interaction versus chargeable click; a window from 30 to 365 daysSelected ad set, action rule and current audience status
Opened a Conversation Ad or clicked one of its CTAsConversationOpen versus CTA click; 30, 60, 90, 180 or 365 daysSelected ad set, action rule and current audience status
Viewed a Company Page or clicked its header CTACompany PagePage view versus CTA action and selected windowAssociated Page, account/Page access and current audience status
Responded to or engaged with a LinkedIn EventEventClicked to attend, registered and attended, registered but did not attend, or engaged without registeringSelected Event, exact event action and current audience status
Appears in an approved first-party listContact listContact source, use permission and refresh ruleApproved source, permission record, upload owner and current audience status

Choose one row for the first plan. If your source could mean two different actions, split it. Someone who opened a form and someone who submitted it should not inherit the same message merely because both touched the same form.

What “Matched Audience” proves—and what it does not

A Matched Audience is LinkedIn's audience segment built from source data. Its status is a platform-processing state.

LinkedIn's current status guide includes Building, Ready, Updating, Failed, Expired, Archived, Website: sending signal and Website: no signal. LinkedIn defines Ready as fully processed and ready to use in ad sets. Building and Updating can take up to 48 hours and, in rare cases, 72 hours.

Use those labels for the questions they actually answer:

  • Website: sending signal means the audience received a signal event.
  • Ready means LinkedIn processed the audience for ad-set use.
  • Failed means the uploaded list or data-integration segment has a problem.
  • Expired means the segment needs to be reactivated or uploaded again before use.

They do not show whether an ad served, whether a qualified person clicked, whether a CRM event arrived or whether revenue resulted.

LinkedIn says a retargeting audience needs at least 300 matched member accounts before it can be used in ad-set targeting. Treat 300 as a platform-use threshold. It is not a recommended audience size, a forecast, a match-rate promise or evidence that your campaign will deliver.

Do not infer matched population from an upstream count. LinkedIn specifically warns that video views and Lead Gen Form opens or completions do not correspond directly to matched member accounts. The same discipline applies to page visits and engagement totals: ask for the audience's current matched state.

Set up website retargeting without assuming history

Website retargeting needs the LinkedIn Insight Tag. LinkedIn documents two ways to define the audience:

  • Use Website Actions collected on tagged pages, such as button clicks, page visits and form submissions.
  • Add a URL rule using starts with, equals or contains.

Record the actual action or URL expression. “High-intent website visitors” is too loose to review.

LinkedIn says a website audience starts building on the day you create it. It does not include website activity from before that date. If you create a 30-day audience today, the selected window does not give you the previous 30 days of visitors. The audience fills as new events arrive.

Before calling the source usable, collect:

  1. The ad account and Insight Tag identity.
  2. A current active-tag or signal receipt.
  3. The exact Website Action or URL rule.
  4. The audience creation date and selected window.
  5. The current audience status and matched population state.
  6. The pages that must be excluded from the inclusion rule.
  7. The owner responsible for the tag, audience and downstream event.

Privacy belongs in the source decision. LinkedIn says the Insight Tag collects the page URL, referrer, IP address, device and browser characteristics and timestamp, with stated pseudonymization and deletion practices. It also says the tag should not be installed on pages that collect or contain sensitive data, including certain consumer health and financial pages. Ask the appropriate privacy or legal owner to approve the page set when that restriction could apply. A media buyer's planned install is not approval.

Choose the window from the decision you need to make

A longer window produces a broader group whose original action may say less about what they need now. A shorter window preserves recency but may never reach a usable matched population.

Use three inputs:

  1. How specific is the action? A pricing-page visit usually says more than a homepage visit. A 75% video view says more than a 25% view, but it may create a smaller source pool.
  2. How long is the real evaluation cycle? The audience should have a reason to remain useful for the full window.
  3. Can LinkedIn populate it? Record the current matched state instead of guessing from visits or views.

If the useful action cannot reach a usable audience, do not dilute the definition immediately. First test whether adjacent actions ask the same next question. You might combine two product-page rules that reflect one evaluation task. Do not combine a broad homepage visit and a form submission merely to reach 300.

When no honest combination exists, keep the narrow plan on Hold, use the source for measurement, or choose another eligible channel. The platform threshold is a constraint. It should not rewrite the meaning of the audience.

Suppress people who should not receive the next ask

Retargeting breaks when acquisition messaging keeps following people who have already completed the step. Define suppressions from auditable sources rather than wishful labels.

Consider four branches:

  • Completed step: form submitters, registrants, demo requests or other people who completed the action your ad asks for.
  • Customers: current customers when the message is only for prospects.
  • Open opportunities: active deals when the paid message would conflict with sales or repeat an offer already in progress.
  • Privacy and preference: records that should not be used because permission is absent, revoked or restricted.

Each suppression needs a source, owner, refresh rule and current state. “Exclude customers” is not complete if nobody can identify the list, CRM property, sync or owner.

Do not let a missing suppression vanish behind a general targeting note. Return Hold with a focused request such as:

RevOps owner: confirm the CRM property and synced audience that identifies current open opportunities for this offer. Supply the list/audience reference, refresh rule and current status.

Match the next message to the question behind the action

The strongest competitor pages explain source types. The harder job is deciding what to say next. Use the action to form a hypothesis, then choose one message job.

SignalLikely questionUseful message jobProof or assetDestination
Broad educational visit or 25% video view“What is changing, and why should I care?”OrientClear category explanation or playbookRelevant guide
Product or use-case page visit“Can this solve my situation?”Provide proofSpecific customer story, product walkthrough or before/after processCase study or product detail
Deep video view or document interaction“How should I evaluate the options?”Help evaluationChecklist, comparison or implementation guideEvaluation resource
Pricing visit or repeated high-intent action“Is the next conversation worth it?”Invite evaluationCustomer-led session, diagnostic or scoped assessmentRegistration or booking page
Known completed step“What happens next?”Stop acquisition or change branchOnboarding, follow-up or account-specific informationOwned follow-up path

This is a planning hypothesis. The public ad examples below show visible message and offer choices. Their Ad Library records do not reveal whether the advertisers used them for retargeting.

Orientation: Microsoft Advertising's playbook

Microsoft Advertising playbook carouselSix public carousel cards illustrate an orientation message job.Public creative shows the visible message and offer only. It does not prove retargeting, audience, delivery or results.Open the original LinkedIn Ad Library record ↗

Microsoft Advertising's six-card carousel opens with a change in how shoppers discover and compare products, then offers a playbook. That is an orientation job. It helps a reader name a changing category before asking for a sales conversation.

The adaptation: use an education asset when the source action shows initial attention but does not establish active vendor evaluation. The next message should make the problem easier to understand, not pretend the visitor asked for a demo.

Proof: Canva's franchise customer story

Canva franchise customer storyThe full sponsored card preserves the author, sponsor and opening copy.Public creative shows the visible message and offer only. It does not prove retargeting, audience, delivery or results.Open the original LinkedIn Ad Library record ↗

Canva's sponsored post presents the franchise problem, names Brand Kits, locked templates and approval workflows, and uses F45 Training as the customer proof. The quoted turnaround and scale remain Canva's advertiser claims.

The adaptation: follow a relevant product or vertical page visit with proof from the same operating context. Preserve the customer attribution. Do not turn the advertiser's claim into an independent result or assume the ad reached franchise buyers.

Evaluation: Fleetio's buying checklist

Fleetio government-fleet checklistNine public carousel cards illustrate an evaluation checklist.Public creative shows the visible message and offer only. It does not prove retargeting, audience, delivery or results.Open the original LinkedIn Ad Library record ↗

Fleetio's nine-card carousel frames government fleet management as a multi-criterion software decision and makes the checklist visible across the cards.

The adaptation: a warm evaluator may need criteria more than another product claim. Offer a checklist when the source action suggests comparison or implementation research. The public record does not prove that government accounts saw or acted on the ad.

Evaluation invitation: Intuit Accountants' customer session

Intuit Accountants customer sessionThe full card shows the customer-session invitation and visible advertiser claims.Public creative shows the visible message and offer only. It does not prove retargeting, audience, delivery or results.Open the original LinkedIn Ad Library record ↗

Intuit Accountants' ad invites readers to a customer migration session. Its customer scale and reduction figures remain advertiser claims.

The adaptation: use a customer-led session when the source action justifies a higher-commitment next step and the session actually answers the likely question. A webinar is not automatically the right retargeting offer. The topic, speaker, destination and registration handoff must be real and verified.

Direct next step: Ramp's construction workflow

Ramp construction workflowThe captured public ad card shows the workflow headline and learn-more CTA.Public creative shows the visible message and offer only. It does not prove retargeting, audience, delivery or results.Open the original LinkedIn Ad Library record ↗

Ramp's ad names a construction expense workflow, uses “Six job sites. One dashboard.” as the headline and asks the reader to learn more. The captured packet contains the visible ad card, not the playable video. Its “5,500+” statement remains an advertiser claim.

The adaptation: use a direct product step when the source action identifies a concrete workflow and the destination continues that story. A generic homepage would break the handoff.

A useful practitioner view of the next message

Choose the job of the next messageImpactable practitioner passage, 01:39–03:57, published 2022-05-09.Dated practitioner strategy. Current LinkedIn Help governs source eligibility and status.Watch the checked passage on YouTube ↗

In a 2022 Impactable video, the passage from 01:39 to 03:57 treats the first website action as an intent signal and argues that the next message should address timing, familiarity, trust or credibility. It suggests testimonials, case studies, press and other proof formats.

Use the passage as practitioner strategy for choosing the next-message job. Use current LinkedIn Help pages for setup and eligibility. The video does not establish today's LinkedIn source rules, windows, prices or results.

Three worked LinkedIn retargeting plans

Every company, person, account state and result in the following cases is fictional. The examples demonstrate the record and its decisions. They are not Maestro campaigns or client results.

Fictional case 1: website pricing visit to proof

Northstar Security sells access-governance software to mid-market IT teams. Its proposed qualifying action is a visit to /pricing. The fictional ad account has an active Insight Tag receipt and a website audience created on September 10, 2026, using an exact URL rule. The selected window is 90 days. LinkedIn shows Website: sending signal, but the audience is still Building and no matched count receipt has been supplied.

The next message job is proof. The team proposes a customer story about reducing manual access-review work, leading to the full case study. Demo requesters, customers and open opportunities should be suppressed through named CRM audiences.

The plan remains Hold. The source is available, but population is not ready and the open-opportunity suppression has no current audience reference.

FieldFictional value
Source/actionWebsite; exact /pricing visit
Source evidenceActive tag receipt and sending-signal state supplied
Window90 days; audience begins from its September 10 creation date
Audience stateBuilding; matched population Unknown
SuppressionsDemo requesters and customers identified; open-opportunity audience missing
Message jobProvide proof
Proof and destinationFictional customer story → full case-study page
Downstream eventcase_study_view joined to CRM account by approved first-party key
OwnerPaid media: Alex Rivera; RevOps: Jordan Lee
DecisionHold
Exact requestsLinkedIn audience Ready/matched-state receipt; open-opportunity suppression reference and refresh rule

Fictional case 2: deep video view to evaluation checklist

Harbor Systems sells fleet-maintenance software. The proposed source is a video-ad audience containing people who watched at least 75% of a product walkthrough in the past 90 days. The selected video ad set, threshold, window and current Ready receipt are supplied. A Ready receipt proves processing for ad-set use. It does not prove delivery.

The next message job is evaluation. The fictional offer is a maintenance-software checklist leading to a guide with criteria for inspections, parts, work orders and reporting. Existing customers and people who downloaded the checklist are suppressed through documented current sources.

The plan is Ready for operator review. It is not launched. Delivery and outcome remain Unknown until an authorized campaign is created and the evidence arrives.

FieldFictional value
Source/actionVideo; at least 75% viewed
Window90 days
Audience stateReady receipt supplied; source-event and matched counts kept separate
SuppressionsCurrent customers and checklist downloaders, with named source owners
Message jobHelp evaluation
Proof and destinationFictional buying checklist → evaluation guide
Downstream eventevaluation_guide_download with campaign and contact keys
OwnerPaid media: Priya Shah; RevOps: Morgan Lee
DecisionReady for operator review
Unknowns that remainDelivery, qualified actions, opportunity influence and revenue

Fictional case 3: contact list with missing permission

Summit Analytics proposes uploading a list of contacts who attended an owned workshop. The file exists, but the team has not supplied the collection notice, approved use purpose, opt-out handling or a current owner approval. No LinkedIn upload or audience receipt exists.

The proposed next message is an evaluation invitation to a product diagnostic. That creative idea does not repair the missing permission.

The plan stays Hold. Do not upload the list, include raw identifiers in the planner or treat attendance as permission for every advertising use.

FieldFictional value
Source/actionContact list; attended an owned workshop
Permission stateUnknown
Audience stateNot created; matched population Unknown
SuppressionsCustomers and open opportunities proposed but unverified
Message jobInvite evaluation
OwnerData owner requested; paid-media owner supplied
DecisionHold
Exact requestsCollection/notice source, approved advertising use, opt-out treatment, data owner, suppression sources and later LinkedIn status receipt

Measure the handoff beyond LinkedIn

Do not finish the plan at “website conversion.” Name the event and the system that receives it.

Record:

  • The destination URL and its owner.
  • The exact downstream event, such as a guide download, registration or qualified demo request.
  • The campaign, contact and account keys used to join the event.
  • The CRM field or object that stores the result.
  • The person who checks the handoff.
  • The review trigger and timing.

Keep the evidence chain in order:

  1. Source action observed.
  2. Matched Audience processed.
  3. Approved ad set delivered.
  4. Destination action received.
  5. CRM handoff verified.
  6. Qualified business event observed.

A later step cannot repair a missing earlier receipt. A CRM opportunity does not prove this audience caused it. A Ready audience does not prove an impression.

Build the portable source-to-message handoff

Build the source-to-message handoff

Load a fictional example or start blank. Every edit recomputes the decision and evidence requests. Ready means ready for operator review.

Decision
Source
Population
Business outcome
Business and source
Source prerequisite and permission
Audience state
Suppressions
Completed step
Customer
Open opportunity
Privacy / preference
Next message
Measurement

Evidence requests

    Readable Markdown handoff

    Canonical JSON record

    Planning tool. It does not create an audience, upload data, authorize spend or launch a campaign.

    Download the LinkedIn retargeting kit

    The JSON records and two prompts use the same contract as the planner. The prompts work without this article.

    Copy the full build prompt
    Contract `maestro.linkedin-retargeting-plan.v1` version `1.1.0`.
    
    Reference summary:
    Current first-party summary observed 2026-09-29: LinkedIn documents website, single-image, document, video, Lead Gen Form, Conversation Ad, Company Page, Event and CAPI retargeting sources. Website audiences require the Insight Tag and begin building on creation; they do not backfill earlier site activity. Video thresholds are 25, 50, 75 or 97 percent with documented windows. Source event/view/form counts do not directly equal matched member accounts. Ready means processed for ad-set use, not delivered or commercially successful. EEA/Switzerland matching is subject to member preferences.
    
    Current source: https://www.linkedin.com/help/lms/answer/a427551
    Status source: https://www.linkedin.com/help/lms/answer/a795242
    Website source: https://www.linkedin.com/help/lms/answer/a420433/
    
    Use only supplied facts. Preserve source facts byte for byte. Never invent audience size, permission, source availability, Ready state, suppression, delivery, outcomes, owner approval or dates. Natural-language denial, pending, planned, requested, expected or unavailable evidence is not affirmative. Ready is only `ready_for_operator_review`; it does not authorize audience creation, upload, spend or launch. Keep source availability, population, delivery and business outcome separate.
    
    Evaluation contract:
    - Contract ID `maestro.linkedin-retargeting-plan.v1`, version `1.1.0`. A mismatch emits `REQ-CONTRACT` and cannot be Ready.
    - Decision precedence: hold > ready_for_operator_review. This evaluator returns Hold for any request and `ready_for_operator_review` only with none.
    - Discard imported derived values before evaluation.
    - Source binding: source.route must equal the top-level route. Changing route never reuses evidence gathered for another route.
    - Timestamp rule: source.observed_at and audience.status_observed_at must be calendar-valid timezone-aware ISO 8601 timestamps.
    - Evidence rule: Evidence references must be present and affirmative. Natural-language denied, pending, planned, requested, expected or unavailable references are not receipts.
    - Population rule: usable requires an integer matched_accounts_count of at least 300; zero requires count 0; below_threshold requires an integer count from 0 through 299.
    - Unknown, No, numeric Zero and valid Not applicable are distinct. Whole-value aliases Unknown, Not applicable, n/a, na, pending, unavailable, denied, none, null, tbd, to be determined, planned, requested, expected and placeholder are unresolved unless a route explicitly permits the state.
    - Broadly missing rule: Three or more incomplete planning groups. Groups are {"scope": ["business.name", "business.offer", "business.buyer_scope"], "source": ["route", "source.route", "source.qualifying_action"], "message": ["message.job", "message.buyer_question", "message.offer", "message.destination_url"], "owners": ["business.owner", "permission.owner", "message.owner", "measurement.owner"], "measurement": ["measurement.downstream_event", "measurement.crm_key", "measurement.review_trigger"]}. In that branch emit only missing PLAN-* requests, in scope/source/message/owners/measurement order, plus REQ-CONTRACT when applicable. Do not ask for account receipts.
    - Once fewer than three planning groups are incomplete, validate the selected route, timestamps, affirmative permission, Ready audience and usable count, all four suppressions, message and measurement. Emit requests in contract/source/tag/permission/audience/completed/customer/opportunity/privacy/message/measurement order.
    
    Stable request vocabulary (copy IDs and request text exactly):
    - `REQ-CONTRACT`: Use contract maestro.linkedin-retargeting-plan.v1 version 1.1.0 and migrate the record before review.
    - `PLAN-SCOPE`: Supply the business, offer and buyer scope for this plan.
    - `PLAN-SOURCE`: Choose one supported source route and name the exact qualifying action.
    - `PLAN-MESSAGE`: Supply the next-message job, buyer question, offer and destination.
    - `PLAN-OWNERS`: Assign owners for the plan, data permission, message and measurement.
    - `PLAN-MEASUREMENT`: Supply the downstream event, CRM key and review trigger.
    - `REQ-SOURCE`: Supply the current selected source/action reference and observation date.
    - `REQ-TAG`: Supply the current active Insight Tag and website signal receipt.
    - `REQ-PERMISSION`: Supply explicit approved data-use evidence, owner and opt-out handling.
    - `REQ-AUDIENCE`: Supply the current LinkedIn audience status receipt and matched population state.
    - `REQ-SUPPRESSION-COMPLETED`: Supply the completed-step suppression source, refresh rule, owner and current read-back.
    - `REQ-SUPPRESSION-CUSTOMER`: Supply the customer suppression source, refresh rule, owner and current read-back.
    - `REQ-SUPPRESSION-OPPORTUNITY`: Supply the open-opportunity suppression source, refresh rule, owner and current read-back.
    - `REQ-SUPPRESSION-PRIVACY`: Supply the privacy/preference suppression source, refresh rule, owner and current read-back.
    - `REQ-MESSAGE`: Supply the next-message job, real proof asset, offer and destination.
    - `REQ-MEASUREMENT`: Supply the downstream event, CRM key, owner and review trigger.
    
    Route contract:
    - `website`: required source.route, source.qualifying_action, source.rule, source.window_days, source.observed_at, source.evidence_ref, source.insight_tag_state, source.insight_tag_evidence_ref, audience.status, audience.status_evidence_ref; allowed windows [30, 60, 90, 180, 365]
    - `video`: required source.route, source.qualifying_action, source.asset_ref, source.video_view_threshold, source.window_days, source.observed_at, source.evidence_ref, audience.status, audience.status_evidence_ref; allowed windows [30, 60, 90, 180, 365]; thresholds [25, 50, 75, 97]
    - `lead_gen_form`: required source.route, source.qualifying_action, source.asset_ref, source.lead_form_action, source.window_days, source.observed_at, source.evidence_ref, audience.status, audience.status_evidence_ref; allowed windows [30, 60, 90, 180, 365]; actions ['opened', 'submitted']
    - `single_image`: required source.route, source.qualifying_action, source.asset_ref, source.single_image_action, source.window_days, source.observed_at, source.evidence_ref, audience.status, audience.status_evidence_ref; allowed windows [30, 60, 90, 180, 365]; actions ['any_interaction', 'chargeable_click']
    - `document`: required source.route, source.qualifying_action, source.asset_ref, source.document_action, source.window_days, source.observed_at, source.evidence_ref, audience.status, audience.status_evidence_ref; allowed windows [30, 60, 90, 180, 365]; actions ['download_or_interaction', 'chargeable_click']
    - `conversation`: required source.route, source.qualifying_action, source.asset_ref, source.conversation_action, source.window_days, source.observed_at, source.evidence_ref, audience.status, audience.status_evidence_ref; allowed windows [30, 60, 90, 180, 365]; actions ['opened', 'cta_click']
    - `company_page`: required source.route, source.qualifying_action, source.asset_ref, source.company_page_action, source.window_days, source.observed_at, source.evidence_ref, audience.status, audience.status_evidence_ref; allowed windows [30, 60, 90, 180, 365]; actions ['page_view', 'header_cta_click']
    - `event`: required source.route, source.qualifying_action, source.asset_ref, source.event_action, source.observed_at, source.evidence_ref, audience.status, audience.status_evidence_ref; actions ['clicked_to_attend', 'registered_attended', 'registered_not_attended', 'engaged_not_registered_or_attended']
    - `contact_list`: required source.route, source.qualifying_action, source.asset_ref, source.observed_at, source.evidence_ref, permission.state, permission.evidence_ref, permission.owner, audience.status, audience.status_evidence_ref
    - `capi`: required source.route, source.qualifying_action, source.asset_ref, source.observed_at, source.evidence_ref, permission.state, permission.evidence_ref, permission.owner, audience.status, audience.status_evidence_ref
    
    Readable Markdown renderer grammar, in this exact section order:
    1. H1 `LinkedIn retargeting source-to-message handoff`.
    2. `Record and decision`: Contract ID, Contract version, Record ID, Fixture status, Decision, Input SHA-256.
    3. `Business and route`: Business, Offer, Buyer scope, Plan owner, Route, Source evidence kind.
    4. `Source`: Qualifying action, Source rule, Source asset or list reference, Window days, Observed at, Source evidence reference, Insight Tag state, Insight Tag evidence reference, Video view threshold, Lead Form action, Single-image action, Document action, Conversation action, Company Page action, Event action, Source event count.
    5. `Permission`: State, Evidence reference, Owner, Notice reference, Opt-out process.
    6. `Audience`: Audience name, Status, Status observed at, Status evidence reference, Matched population state, Matched account count.
    7. `Suppressions`: one H3 per supplied suppression, named by `kind`, with State, Source, Refresh rule, Owner and Evidence reference. If no suppression array is supplied, write `No suppression records supplied.`
    8. `Next message`: Job, Buyer question, Proof asset, Offer, Destination URL, CTA, Owner.
    9. `Measurement`: Downstream event, CRM key, Owner, Review trigger, Delivery state, Delivery evidence reference, Business outcome state, Business outcome evidence reference.
    10. `Decision reasons`: one bullet per `derived.reasons` value in evaluator order; if absent, write `Unknown`.
    11. `Evidence requests`: one bullet per request as `**ID** — owner: exact request Reason: exact reason`; if none, write `No planning evidence requests remain. Account-specific launch checks still apply.`
    12. `Next action`: copy `derived.next_action` exactly.
    
    For every label above, render the corresponding canonical field even when it is null, zero, false, Unknown, No or Not applicable. Render null or missing as `Unknown`; render numeric zero as `0`; never drop an off-route field. Escape literal `|` as `\|`. This readable handoff is complete field-semantic output, not a selected summary.
    
    Canonical JSON renderer rules:
    - Preserve every supplied non-derived field and value exactly. Do not silently migrate a mismatched contract.
    - Remove imported `derived`, recompute it, then append keys in this order: decision, reasons, requests, next_action, input_sha256.
    - Request objects use keys in this order: id, owner, reason, request. Deduplicate by ID and retain evaluator order.
    - Compute `input_sha256` from UTF-8 JSON of the non-derived record with recursively sorted object keys, compact separators and unescaped Unicode.
    - Ready next action is exactly `An authorized operator reviews the record and performs account-specific launch checks.`
    - Hold next action is exactly the first request's `request`.
    
    Normative standalone evaluator implementation follows. This is the complete validation-to-request mapping, reason vocabulary, owner selection, fallback rule, deduplication behavior and hash algorithm. Use the embedded contract JSON as `CONTRACT`. Do not summarize, rename or improvise any request object. If code execution is available, run this implementation. Otherwise apply it line by line.
    
    Embedded contract JSON:
    ```json
    {
      "contract_id": "maestro.linkedin-retargeting-plan.v1",
      "contract_version": "1.1.0",
      "authoritative_input_rule": "Only fields outside derived are source facts. Discard imported derived values and recompute them.",
      "unknown_semantics": "Unknown means evidence is absent. No means an observed negative. Zero means an observed numeric zero. Not applicable requires a selected route where the check truly does not apply.",
      "decision_precedence": [
        "hold",
        "ready_for_operator_review"
      ],
      "routes": {
        "website": {
          "required": [
            "source.route",
            "source.qualifying_action",
            "source.rule",
            "source.window_days",
            "source.observed_at",
            "source.evidence_ref",
            "source.insight_tag_state",
            "source.insight_tag_evidence_ref",
            "audience.status",
            "audience.status_evidence_ref"
          ],
          "allowed_windows": [
            30,
            60,
            90,
            180,
            365
          ]
        },
        "video": {
          "required": [
            "source.route",
            "source.qualifying_action",
            "source.asset_ref",
            "source.video_view_threshold",
            "source.window_days",
            "source.observed_at",
            "source.evidence_ref",
            "audience.status",
            "audience.status_evidence_ref"
          ],
          "thresholds": [
            25,
            50,
            75,
            97
          ],
          "allowed_windows": [
            30,
            60,
            90,
            180,
            365
          ]
        },
        "lead_gen_form": {
          "required": [
            "source.route",
            "source.qualifying_action",
            "source.asset_ref",
            "source.lead_form_action",
            "source.window_days",
            "source.observed_at",
            "source.evidence_ref",
            "audience.status",
            "audience.status_evidence_ref"
          ],
          "actions": [
            "opened",
            "submitted"
          ],
          "allowed_windows": [
            30,
            60,
            90,
            180,
            365
          ]
        },
        "single_image": {
          "required": [
            "source.route",
            "source.qualifying_action",
            "source.asset_ref",
            "source.single_image_action",
            "source.window_days",
            "source.observed_at",
            "source.evidence_ref",
            "audience.status",
            "audience.status_evidence_ref"
          ],
          "actions": [
            "any_interaction",
            "chargeable_click"
          ],
          "allowed_windows": [
            30,
            60,
            90,
            180,
            365
          ]
        },
        "document": {
          "required": [
            "source.route",
            "source.qualifying_action",
            "source.asset_ref",
            "source.document_action",
            "source.window_days",
            "source.observed_at",
            "source.evidence_ref",
            "audience.status",
            "audience.status_evidence_ref"
          ],
          "actions": [
            "download_or_interaction",
            "chargeable_click"
          ],
          "allowed_windows": [
            30,
            60,
            90,
            180,
            365
          ]
        },
        "conversation": {
          "required": [
            "source.route",
            "source.qualifying_action",
            "source.asset_ref",
            "source.conversation_action",
            "source.window_days",
            "source.observed_at",
            "source.evidence_ref",
            "audience.status",
            "audience.status_evidence_ref"
          ],
          "actions": [
            "opened",
            "cta_click"
          ],
          "allowed_windows": [
            30,
            60,
            90,
            180,
            365
          ]
        },
        "company_page": {
          "required": [
            "source.route",
            "source.qualifying_action",
            "source.asset_ref",
            "source.company_page_action",
            "source.window_days",
            "source.observed_at",
            "source.evidence_ref",
            "audience.status",
            "audience.status_evidence_ref"
          ],
          "actions": [
            "page_view",
            "header_cta_click"
          ],
          "allowed_windows": [
            30,
            60,
            90,
            180,
            365
          ]
        },
        "event": {
          "required": [
            "source.route",
            "source.qualifying_action",
            "source.asset_ref",
            "source.event_action",
            "source.observed_at",
            "source.evidence_ref",
            "audience.status",
            "audience.status_evidence_ref"
          ],
          "actions": [
            "clicked_to_attend",
            "registered_attended",
            "registered_not_attended",
            "engaged_not_registered_or_attended"
          ]
        },
        "contact_list": {
          "required": [
            "source.route",
            "source.qualifying_action",
            "source.asset_ref",
            "source.observed_at",
            "source.evidence_ref",
            "permission.state",
            "permission.evidence_ref",
            "permission.owner",
            "audience.status",
            "audience.status_evidence_ref"
          ]
        },
        "capi": {
          "required": [
            "source.route",
            "source.qualifying_action",
            "source.asset_ref",
            "source.observed_at",
            "source.evidence_ref",
            "permission.state",
            "permission.evidence_ref",
            "permission.owner",
            "audience.status",
            "audience.status_evidence_ref"
          ]
        }
      },
      "affirmative_evidence": {
        "source": "A current non-placeholder reference to the selected source/action and its observed state.",
        "permission": "Explicit approved state, named owner and current non-placeholder approval/reference. Planned, requested, expected, pending or inferred language fails.",
        "audience": "Current LinkedIn status reference. Ready proves processing only.",
        "suppression": "Named current source, refresh rule, owner, observed yes/no state and non-placeholder reference.",
        "delivery": "Actual ad-set delivery read-back with object IDs and observation time. Audience Ready does not satisfy it.",
        "outcome": "Actual destination/CRM event read-back with join key and observation time. Delivery does not satisfy it."
      },
      "stable_requests": {
        "REQ-CONTRACT": "Use contract maestro.linkedin-retargeting-plan.v1 version 1.1.0 and migrate the record before review.",
        "PLAN-SCOPE": "Supply the business, offer and buyer scope for this plan.",
        "PLAN-SOURCE": "Choose one supported source route and name the exact qualifying action.",
        "PLAN-MESSAGE": "Supply the next-message job, buyer question, offer and destination.",
        "PLAN-OWNERS": "Assign owners for the plan, data permission, message and measurement.",
        "PLAN-MEASUREMENT": "Supply the downstream event, CRM key and review trigger.",
        "REQ-SOURCE": "Supply the current selected source/action reference and observation date.",
        "REQ-TAG": "Supply the current active Insight Tag and website signal receipt.",
        "REQ-PERMISSION": "Supply explicit approved data-use evidence, owner and opt-out handling.",
        "REQ-AUDIENCE": "Supply the current LinkedIn audience status receipt and matched population state.",
        "REQ-SUPPRESSION-COMPLETED": "Supply the completed-step suppression source, refresh rule, owner and current read-back.",
        "REQ-SUPPRESSION-CUSTOMER": "Supply the customer suppression source, refresh rule, owner and current read-back.",
        "REQ-SUPPRESSION-OPPORTUNITY": "Supply the open-opportunity suppression source, refresh rule, owner and current read-back.",
        "REQ-SUPPRESSION-PRIVACY": "Supply the privacy/preference suppression source, refresh rule, owner and current read-back.",
        "REQ-MESSAGE": "Supply the next-message job, real proof asset, offer and destination.",
        "REQ-MEASUREMENT": "Supply the downstream event, CRM key, owner and review trigger."
      },
      "launch_boundary": "ready_for_operator_review is not audience creation, upload, spend authorization, campaign launch, delivery or business outcome.",
      "broadly_missing_rule": {
        "threshold": "Three or more incomplete planning groups",
        "groups": {
          "scope": [
            "business.name",
            "business.offer",
            "business.buyer_scope"
          ],
          "source": [
            "route",
            "source.route",
            "source.qualifying_action"
          ],
          "message": [
            "message.job",
            "message.buyer_question",
            "message.offer",
            "message.destination_url"
          ],
          "owners": [
            "business.owner",
            "permission.owner",
            "message.owner",
            "measurement.owner"
          ],
          "measurement": [
            "measurement.downstream_event",
            "measurement.crm_key",
            "measurement.review_trigger"
          ]
        },
        "behavior": "Return only the missing PLAN-* requests until fewer than three planning groups are incomplete. Do not ask for account receipts in this branch."
      },
      "source_route_binding": "source.route must equal the top-level route. Changing route never reuses evidence gathered for another route.",
      "timestamp_rule": "source.observed_at and audience.status_observed_at must be calendar-valid timezone-aware ISO 8601 timestamps.",
      "evidence_reference_rule": "Evidence references must be present and affirmative. Natural-language denied, pending, planned, requested, expected or unavailable references are not receipts.",
      "matched_population_rule": "usable requires an integer matched_accounts_count of at least 300; zero requires count 0; below_threshold requires an integer count from 0 through 299."
    }
    ```
    
    Reference implementation:
    ```python
    #!/usr/bin/env python3
    import copy,hashlib,json,re,sys
    from datetime import datetime
    from pathlib import Path
    HERE=Path(__file__).resolve().parent
    CONTRACT=json.loads((HERE/'contract.json').read_text())
    BAD=re.compile(r'^(?:unknown|not applicable|n/?a|na|pending|unavailable|denied|none|null|tbd|to be determined|planned|requested|expected|placeholder)$',re.I)
    NEGATIVE_REF=re.compile(r'\b(?:denied|pending|planned|requested|expected|unavailable|not\s+approved|not\s+available|not\s+complete|will\s+be|to\s+be\s+(?:added|provided|confirmed|verified))\b',re.I)
    ACTION_PATHS={'lead_gen_form':'source.lead_form_action','single_image':'source.single_image_action','document':'source.document_action','conversation':'source.conversation_action','company_page':'source.company_page_action','event':'source.event_action'}
    SUPPRESSION_IDS={'completed_next_step':'REQ-SUPPRESSION-COMPLETED','customer':'REQ-SUPPRESSION-CUSTOMER','open_opportunity':'REQ-SUPPRESSION-OPPORTUNITY','privacy_preference':'REQ-SUPPRESSION-PRIVACY'}
    PLAN_IDS={'scope':'PLAN-SCOPE','source':'PLAN-SOURCE','message':'PLAN-MESSAGE','owners':'PLAN-OWNERS','measurement':'PLAN-MEASUREMENT'}
    
    def present(v):
        if v is None or v is False:return False
        if isinstance(v,str):return bool(v.strip()) and not BAD.fullmatch(v.strip())
        return True
    def affirmative_ref(v):return present(v) and not (isinstance(v,str) and NEGATIVE_REF.search(v))
    def get(obj,path):
        cur=obj
        for part in path.split('.'):
            if not isinstance(cur,dict):return None
            cur=cur.get(part)
        return cur
    def valid_time(v):
        if not isinstance(v,str):return False
        try:
            parsed=datetime.fromisoformat(v.replace('Z','+00:00'))
            return parsed.tzinfo is not None
        except ValueError:return False
    def req(reqs,id,owner,reason):
        if any(x['id']==id for x in reqs):return
        reqs.append({'id':id,'owner':owner or 'Owner assignment required','reason':reason,'request':CONTRACT['stable_requests'][id]})
    def finish(x,requests):
        decision='ready_for_operator_review' if not requests else 'hold'
        reasons=[q['reason'] for q in requests] if requests else ['Planning, permission, audience, suppression, message and measurement evidence are complete.']
        clean=json.dumps(x,sort_keys=True,separators=(',',':'),ensure_ascii=False).encode()
        x['derived']={'decision':decision,'reasons':reasons,'requests':requests,'next_action':'An authorized operator reviews the record and performs account-specific launch checks.' if not requests else requests[0]['request'],'input_sha256':hashlib.sha256(clean).hexdigest()}
        return x
    
    def evaluate(source):
        x=copy.deepcopy(source);x.pop('derived',None);requests=[]
        if x.get('contract_id')!=CONTRACT['contract_id'] or x.get('contract_version')!=CONTRACT['contract_version']:
            req(requests,'REQ-CONTRACT',get(x,'business.owner'),'The contract identity or version is incompatible.')
        group_gaps={name:[p for p in paths if not present(get(x,p))] for name,paths in CONTRACT['broadly_missing_rule']['groups'].items()}
        incomplete=[name for name,gaps in group_gaps.items() if gaps]
        if len(incomplete)>=3:
            for name in ('scope','source','message','owners','measurement'):
                if name in incomplete:req(requests,PLAN_IDS[name],get(x,'business.owner'),f'The {name} planning group is incomplete: {", ".join(group_gaps[name])}.')
            return finish(x,requests)
        route=x.get('route')
        if route not in CONTRACT['routes']:
            req(requests,'REQ-SOURCE',get(x,'business.owner'),'Choose one supported route and supply its source evidence.')
        else:
            spec=CONTRACT['routes'][route]
            if get(x,'source.route')!=route:req(requests,'REQ-SOURCE',get(x,'business.owner'),'The source evidence kind does not match the selected route.')
            for field in spec['required']:
                value=get(x,field);ok=affirmative_ref(value) if field.endswith('evidence_ref') else present(value)
                if not ok:
                    id='REQ-TAG' if 'insight_tag' in field else 'REQ-PERMISSION' if field.startswith('permission.') else 'REQ-AUDIENCE' if field.startswith('audience.') else 'REQ-SOURCE'
                    req(requests,id,get(x,'permission.owner') or get(x,'business.owner'),f'Missing or non-affirmative {field}.')
            if spec.get('allowed_windows') and get(x,'source.window_days') not in spec['allowed_windows']:req(requests,'REQ-SOURCE',get(x,'business.owner'),'The source window is not valid for the selected route.')
            if spec.get('thresholds') and get(x,'source.video_view_threshold') not in spec['thresholds']:req(requests,'REQ-SOURCE',get(x,'business.owner'),'The video threshold is not valid for the selected route.')
            if spec.get('actions') and get(x,ACTION_PATHS[route]) not in spec['actions']:req(requests,'REQ-SOURCE',get(x,'business.owner'),'The source action is not valid for the selected route.')
            if route=='website' and get(x,'source.insight_tag_state')!='yes':req(requests,'REQ-TAG',get(x,'business.owner'),'The website route lacks an affirmative active Insight Tag state.')
        if not valid_time(get(x,'source.observed_at')):req(requests,'REQ-SOURCE',get(x,'business.owner'),'The source observation time is not a calendar-valid timezone-aware ISO 8601 value.')
        if get(x,'permission.state')!='approved' or not affirmative_ref(get(x,'permission.evidence_ref')) or not present(get(x,'permission.owner')) or not present(get(x,'permission.opt_out_process')):req(requests,'REQ-PERMISSION',get(x,'permission.owner'),'Explicit current data-use approval is incomplete.')
        if get(x,'audience.status')!='ready' or not affirmative_ref(get(x,'audience.status_evidence_ref')) or get(x,'audience.matched_accounts_state')!='usable' or not valid_time(get(x,'audience.status_observed_at')):req(requests,'REQ-AUDIENCE',get(x,'business.owner'),'LinkedIn Ready status and usable matched-population evidence are incomplete.')
        state=get(x,'audience.matched_accounts_state');count=get(x,'audience.matched_accounts_count');count_ok=isinstance(count,int) and not isinstance(count,bool)
        if (state=='usable' and (not count_ok or count<300)) or (state=='zero' and count!=0) or (state=='below_threshold' and (not count_ok or not 0<=count<300)):req(requests,'REQ-AUDIENCE',get(x,'business.owner'),'Matched population state and numeric count are inconsistent.')
        supplied={s.get('kind'):s for s in x.get('suppressions',[]) if isinstance(s,dict)}
        for kind,id in SUPPRESSION_IDS.items():
            s=supplied.get(kind,{})
            if s.get('state')!='yes' or not all(present(s.get(k)) for k in ('source','refresh_rule','owner')) or not affirmative_ref(s.get('evidence_ref')):req(requests,id,s.get('owner'),f'{kind} suppression lacks affirmative current evidence.')
        m=x.get('message',{})
        if not all(present(m.get(k)) for k in ('job','buyer_question','proof_asset','offer','destination_url','owner')):req(requests,'REQ-MESSAGE',m.get('owner'),'The next-message handoff is incomplete.')
        z=x.get('measurement',{})
        if not all(present(z.get(k)) for k in ('downstream_event','crm_key','owner','review_trigger')):req(requests,'REQ-MEASUREMENT',z.get('owner'),'The downstream measurement handoff is incomplete.')
        return finish(x,requests)
    
    if __name__=='__main__':
        source=json.load(open(sys.argv[1])) if len(sys.argv)>1 else json.load(sys.stdin)
        print(json.dumps(evaluate(source),indent=2,ensure_ascii=False))
    
    ```
    
    Canonical blank shape:
    ```json
    {
      "contract_id": "maestro.linkedin-retargeting-plan.v1",
      "contract_version": "1.1.0",
      "record_id": null,
      "fixture_status": "blank",
      "business": {
        "name": null,
        "offer": null,
        "buyer_scope": null,
        "owner": null
      },
      "route": null,
      "source": {
        "qualifying_action": null,
        "rule": null,
        "asset_ref": null,
        "window_days": null,
        "observed_at": null,
        "evidence_ref": null,
        "insight_tag_state": "unknown",
        "insight_tag_evidence_ref": null,
        "video_view_threshold": null,
        "lead_form_action": null,
        "single_image_action": null,
        "document_action": null,
        "conversation_action": null,
        "company_page_action": null,
        "event_action": null,
        "source_event_count": null,
        "route": null
      },
      "permission": {
        "state": "unknown",
        "evidence_ref": null,
        "owner": null,
        "notice_ref": null,
        "opt_out_process": null
      },
      "audience": {
        "name": null,
        "status": "unknown",
        "status_observed_at": null,
        "status_evidence_ref": null,
        "matched_accounts_state": "unknown",
        "matched_accounts_count": null
      },
      "suppressions": [
        {
          "kind": "completed_next_step",
          "source": null,
          "refresh_rule": null,
          "owner": null,
          "state": "unknown",
          "evidence_ref": null
        },
        {
          "kind": "customer",
          "source": null,
          "refresh_rule": null,
          "owner": null,
          "state": "unknown",
          "evidence_ref": null
        },
        {
          "kind": "open_opportunity",
          "source": null,
          "refresh_rule": null,
          "owner": null,
          "state": "unknown",
          "evidence_ref": null
        },
        {
          "kind": "privacy_preference",
          "source": null,
          "refresh_rule": null,
          "owner": null,
          "state": "unknown",
          "evidence_ref": null
        }
      ],
      "message": {
        "job": null,
        "buyer_question": null,
        "proof_asset": null,
        "offer": null,
        "destination_url": null,
        "cta": null,
        "owner": null
      },
      "measurement": {
        "downstream_event": null,
        "crm_key": null,
        "owner": null,
        "review_trigger": null,
        "delivery_state": "unknown",
        "delivery_evidence_ref": null,
        "business_outcome_state": "unknown",
        "business_outcome_evidence_ref": null
      }
    }
    ```
    
    Task: turn the pasted business facts into one canonical source-to-message record. Ask only the bounded planning questions in the broadly missing branch. Once the plan is coherent, request exact account evidence.
    
    Return exactly: (1) route and decision; (2) concise readable handoff using the renderer grammar; (3) discrepancies for review or focused planning questions for build; (4) exact stable requests; (5) canonical JSON in one code fence; (6) one exact next action.
    
    PASTE FACTS OR A RECORD BELOW:
    
    Copy the independent review prompt
    Contract `maestro.linkedin-retargeting-plan.v1` version `1.1.0`.
    
    Reference summary:
    Current first-party summary observed 2026-09-29: LinkedIn documents website, single-image, document, video, Lead Gen Form, Conversation Ad, Company Page, Event and CAPI retargeting sources. Website audiences require the Insight Tag and begin building on creation; they do not backfill earlier site activity. Video thresholds are 25, 50, 75 or 97 percent with documented windows. Source event/view/form counts do not directly equal matched member accounts. Ready means processed for ad-set use, not delivered or commercially successful. EEA/Switzerland matching is subject to member preferences.
    
    Current source: https://www.linkedin.com/help/lms/answer/a427551
    Status source: https://www.linkedin.com/help/lms/answer/a795242
    Website source: https://www.linkedin.com/help/lms/answer/a420433/
    
    Use only supplied facts. Preserve source facts byte for byte. Never invent audience size, permission, source availability, Ready state, suppression, delivery, outcomes, owner approval or dates. Natural-language denial, pending, planned, requested, expected or unavailable evidence is not affirmative. Ready is only `ready_for_operator_review`; it does not authorize audience creation, upload, spend or launch. Keep source availability, population, delivery and business outcome separate.
    
    Evaluation contract:
    - Contract ID `maestro.linkedin-retargeting-plan.v1`, version `1.1.0`. A mismatch emits `REQ-CONTRACT` and cannot be Ready.
    - Decision precedence: hold > ready_for_operator_review. This evaluator returns Hold for any request and `ready_for_operator_review` only with none.
    - Discard imported derived values before evaluation.
    - Source binding: source.route must equal the top-level route. Changing route never reuses evidence gathered for another route.
    - Timestamp rule: source.observed_at and audience.status_observed_at must be calendar-valid timezone-aware ISO 8601 timestamps.
    - Evidence rule: Evidence references must be present and affirmative. Natural-language denied, pending, planned, requested, expected or unavailable references are not receipts.
    - Population rule: usable requires an integer matched_accounts_count of at least 300; zero requires count 0; below_threshold requires an integer count from 0 through 299.
    - Unknown, No, numeric Zero and valid Not applicable are distinct. Whole-value aliases Unknown, Not applicable, n/a, na, pending, unavailable, denied, none, null, tbd, to be determined, planned, requested, expected and placeholder are unresolved unless a route explicitly permits the state.
    - Broadly missing rule: Three or more incomplete planning groups. Groups are {"scope": ["business.name", "business.offer", "business.buyer_scope"], "source": ["route", "source.route", "source.qualifying_action"], "message": ["message.job", "message.buyer_question", "message.offer", "message.destination_url"], "owners": ["business.owner", "permission.owner", "message.owner", "measurement.owner"], "measurement": ["measurement.downstream_event", "measurement.crm_key", "measurement.review_trigger"]}. In that branch emit only missing PLAN-* requests, in scope/source/message/owners/measurement order, plus REQ-CONTRACT when applicable. Do not ask for account receipts.
    - Once fewer than three planning groups are incomplete, validate the selected route, timestamps, affirmative permission, Ready audience and usable count, all four suppressions, message and measurement. Emit requests in contract/source/tag/permission/audience/completed/customer/opportunity/privacy/message/measurement order.
    
    Stable request vocabulary (copy IDs and request text exactly):
    - `REQ-CONTRACT`: Use contract maestro.linkedin-retargeting-plan.v1 version 1.1.0 and migrate the record before review.
    - `PLAN-SCOPE`: Supply the business, offer and buyer scope for this plan.
    - `PLAN-SOURCE`: Choose one supported source route and name the exact qualifying action.
    - `PLAN-MESSAGE`: Supply the next-message job, buyer question, offer and destination.
    - `PLAN-OWNERS`: Assign owners for the plan, data permission, message and measurement.
    - `PLAN-MEASUREMENT`: Supply the downstream event, CRM key and review trigger.
    - `REQ-SOURCE`: Supply the current selected source/action reference and observation date.
    - `REQ-TAG`: Supply the current active Insight Tag and website signal receipt.
    - `REQ-PERMISSION`: Supply explicit approved data-use evidence, owner and opt-out handling.
    - `REQ-AUDIENCE`: Supply the current LinkedIn audience status receipt and matched population state.
    - `REQ-SUPPRESSION-COMPLETED`: Supply the completed-step suppression source, refresh rule, owner and current read-back.
    - `REQ-SUPPRESSION-CUSTOMER`: Supply the customer suppression source, refresh rule, owner and current read-back.
    - `REQ-SUPPRESSION-OPPORTUNITY`: Supply the open-opportunity suppression source, refresh rule, owner and current read-back.
    - `REQ-SUPPRESSION-PRIVACY`: Supply the privacy/preference suppression source, refresh rule, owner and current read-back.
    - `REQ-MESSAGE`: Supply the next-message job, real proof asset, offer and destination.
    - `REQ-MEASUREMENT`: Supply the downstream event, CRM key, owner and review trigger.
    
    Route contract:
    - `website`: required source.route, source.qualifying_action, source.rule, source.window_days, source.observed_at, source.evidence_ref, source.insight_tag_state, source.insight_tag_evidence_ref, audience.status, audience.status_evidence_ref; allowed windows [30, 60, 90, 180, 365]
    - `video`: required source.route, source.qualifying_action, source.asset_ref, source.video_view_threshold, source.window_days, source.observed_at, source.evidence_ref, audience.status, audience.status_evidence_ref; allowed windows [30, 60, 90, 180, 365]; thresholds [25, 50, 75, 97]
    - `lead_gen_form`: required source.route, source.qualifying_action, source.asset_ref, source.lead_form_action, source.window_days, source.observed_at, source.evidence_ref, audience.status, audience.status_evidence_ref; allowed windows [30, 60, 90, 180, 365]; actions ['opened', 'submitted']
    - `single_image`: required source.route, source.qualifying_action, source.asset_ref, source.single_image_action, source.window_days, source.observed_at, source.evidence_ref, audience.status, audience.status_evidence_ref; allowed windows [30, 60, 90, 180, 365]; actions ['any_interaction', 'chargeable_click']
    - `document`: required source.route, source.qualifying_action, source.asset_ref, source.document_action, source.window_days, source.observed_at, source.evidence_ref, audience.status, audience.status_evidence_ref; allowed windows [30, 60, 90, 180, 365]; actions ['download_or_interaction', 'chargeable_click']
    - `conversation`: required source.route, source.qualifying_action, source.asset_ref, source.conversation_action, source.window_days, source.observed_at, source.evidence_ref, audience.status, audience.status_evidence_ref; allowed windows [30, 60, 90, 180, 365]; actions ['opened', 'cta_click']
    - `company_page`: required source.route, source.qualifying_action, source.asset_ref, source.company_page_action, source.window_days, source.observed_at, source.evidence_ref, audience.status, audience.status_evidence_ref; allowed windows [30, 60, 90, 180, 365]; actions ['page_view', 'header_cta_click']
    - `event`: required source.route, source.qualifying_action, source.asset_ref, source.event_action, source.observed_at, source.evidence_ref, audience.status, audience.status_evidence_ref; actions ['clicked_to_attend', 'registered_attended', 'registered_not_attended', 'engaged_not_registered_or_attended']
    - `contact_list`: required source.route, source.qualifying_action, source.asset_ref, source.observed_at, source.evidence_ref, permission.state, permission.evidence_ref, permission.owner, audience.status, audience.status_evidence_ref
    - `capi`: required source.route, source.qualifying_action, source.asset_ref, source.observed_at, source.evidence_ref, permission.state, permission.evidence_ref, permission.owner, audience.status, audience.status_evidence_ref
    
    Readable Markdown renderer grammar, in this exact section order:
    1. H1 `LinkedIn retargeting source-to-message handoff`.
    2. `Record and decision`: Contract ID, Contract version, Record ID, Fixture status, Decision, Input SHA-256.
    3. `Business and route`: Business, Offer, Buyer scope, Plan owner, Route, Source evidence kind.
    4. `Source`: Qualifying action, Source rule, Source asset or list reference, Window days, Observed at, Source evidence reference, Insight Tag state, Insight Tag evidence reference, Video view threshold, Lead Form action, Single-image action, Document action, Conversation action, Company Page action, Event action, Source event count.
    5. `Permission`: State, Evidence reference, Owner, Notice reference, Opt-out process.
    6. `Audience`: Audience name, Status, Status observed at, Status evidence reference, Matched population state, Matched account count.
    7. `Suppressions`: one H3 per supplied suppression, named by `kind`, with State, Source, Refresh rule, Owner and Evidence reference. If no suppression array is supplied, write `No suppression records supplied.`
    8. `Next message`: Job, Buyer question, Proof asset, Offer, Destination URL, CTA, Owner.
    9. `Measurement`: Downstream event, CRM key, Owner, Review trigger, Delivery state, Delivery evidence reference, Business outcome state, Business outcome evidence reference.
    10. `Decision reasons`: one bullet per `derived.reasons` value in evaluator order; if absent, write `Unknown`.
    11. `Evidence requests`: one bullet per request as `**ID** — owner: exact request Reason: exact reason`; if none, write `No planning evidence requests remain. Account-specific launch checks still apply.`
    12. `Next action`: copy `derived.next_action` exactly.
    
    For every label above, render the corresponding canonical field even when it is null, zero, false, Unknown, No or Not applicable. Render null or missing as `Unknown`; render numeric zero as `0`; never drop an off-route field. Escape literal `|` as `\|`. This readable handoff is complete field-semantic output, not a selected summary.
    
    Canonical JSON renderer rules:
    - Preserve every supplied non-derived field and value exactly. Do not silently migrate a mismatched contract.
    - Remove imported `derived`, recompute it, then append keys in this order: decision, reasons, requests, next_action, input_sha256.
    - Request objects use keys in this order: id, owner, reason, request. Deduplicate by ID and retain evaluator order.
    - Compute `input_sha256` from UTF-8 JSON of the non-derived record with recursively sorted object keys, compact separators and unescaped Unicode.
    - Ready next action is exactly `An authorized operator reviews the record and performs account-specific launch checks.`
    - Hold next action is exactly the first request's `request`.
    
    Normative standalone evaluator implementation follows. This is the complete validation-to-request mapping, reason vocabulary, owner selection, fallback rule, deduplication behavior and hash algorithm. Use the embedded contract JSON as `CONTRACT`. Do not summarize, rename or improvise any request object. If code execution is available, run this implementation. Otherwise apply it line by line.
    
    Embedded contract JSON:
    ```json
    {
      "contract_id": "maestro.linkedin-retargeting-plan.v1",
      "contract_version": "1.1.0",
      "authoritative_input_rule": "Only fields outside derived are source facts. Discard imported derived values and recompute them.",
      "unknown_semantics": "Unknown means evidence is absent. No means an observed negative. Zero means an observed numeric zero. Not applicable requires a selected route where the check truly does not apply.",
      "decision_precedence": [
        "hold",
        "ready_for_operator_review"
      ],
      "routes": {
        "website": {
          "required": [
            "source.route",
            "source.qualifying_action",
            "source.rule",
            "source.window_days",
            "source.observed_at",
            "source.evidence_ref",
            "source.insight_tag_state",
            "source.insight_tag_evidence_ref",
            "audience.status",
            "audience.status_evidence_ref"
          ],
          "allowed_windows": [
            30,
            60,
            90,
            180,
            365
          ]
        },
        "video": {
          "required": [
            "source.route",
            "source.qualifying_action",
            "source.asset_ref",
            "source.video_view_threshold",
            "source.window_days",
            "source.observed_at",
            "source.evidence_ref",
            "audience.status",
            "audience.status_evidence_ref"
          ],
          "thresholds": [
            25,
            50,
            75,
            97
          ],
          "allowed_windows": [
            30,
            60,
            90,
            180,
            365
          ]
        },
        "lead_gen_form": {
          "required": [
            "source.route",
            "source.qualifying_action",
            "source.asset_ref",
            "source.lead_form_action",
            "source.window_days",
            "source.observed_at",
            "source.evidence_ref",
            "audience.status",
            "audience.status_evidence_ref"
          ],
          "actions": [
            "opened",
            "submitted"
          ],
          "allowed_windows": [
            30,
            60,
            90,
            180,
            365
          ]
        },
        "single_image": {
          "required": [
            "source.route",
            "source.qualifying_action",
            "source.asset_ref",
            "source.single_image_action",
            "source.window_days",
            "source.observed_at",
            "source.evidence_ref",
            "audience.status",
            "audience.status_evidence_ref"
          ],
          "actions": [
            "any_interaction",
            "chargeable_click"
          ],
          "allowed_windows": [
            30,
            60,
            90,
            180,
            365
          ]
        },
        "document": {
          "required": [
            "source.route",
            "source.qualifying_action",
            "source.asset_ref",
            "source.document_action",
            "source.window_days",
            "source.observed_at",
            "source.evidence_ref",
            "audience.status",
            "audience.status_evidence_ref"
          ],
          "actions": [
            "download_or_interaction",
            "chargeable_click"
          ],
          "allowed_windows": [
            30,
            60,
            90,
            180,
            365
          ]
        },
        "conversation": {
          "required": [
            "source.route",
            "source.qualifying_action",
            "source.asset_ref",
            "source.conversation_action",
            "source.window_days",
            "source.observed_at",
            "source.evidence_ref",
            "audience.status",
            "audience.status_evidence_ref"
          ],
          "actions": [
            "opened",
            "cta_click"
          ],
          "allowed_windows": [
            30,
            60,
            90,
            180,
            365
          ]
        },
        "company_page": {
          "required": [
            "source.route",
            "source.qualifying_action",
            "source.asset_ref",
            "source.company_page_action",
            "source.window_days",
            "source.observed_at",
            "source.evidence_ref",
            "audience.status",
            "audience.status_evidence_ref"
          ],
          "actions": [
            "page_view",
            "header_cta_click"
          ],
          "allowed_windows": [
            30,
            60,
            90,
            180,
            365
          ]
        },
        "event": {
          "required": [
            "source.route",
            "source.qualifying_action",
            "source.asset_ref",
            "source.event_action",
            "source.observed_at",
            "source.evidence_ref",
            "audience.status",
            "audience.status_evidence_ref"
          ],
          "actions": [
            "clicked_to_attend",
            "registered_attended",
            "registered_not_attended",
            "engaged_not_registered_or_attended"
          ]
        },
        "contact_list": {
          "required": [
            "source.route",
            "source.qualifying_action",
            "source.asset_ref",
            "source.observed_at",
            "source.evidence_ref",
            "permission.state",
            "permission.evidence_ref",
            "permission.owner",
            "audience.status",
            "audience.status_evidence_ref"
          ]
        },
        "capi": {
          "required": [
            "source.route",
            "source.qualifying_action",
            "source.asset_ref",
            "source.observed_at",
            "source.evidence_ref",
            "permission.state",
            "permission.evidence_ref",
            "permission.owner",
            "audience.status",
            "audience.status_evidence_ref"
          ]
        }
      },
      "affirmative_evidence": {
        "source": "A current non-placeholder reference to the selected source/action and its observed state.",
        "permission": "Explicit approved state, named owner and current non-placeholder approval/reference. Planned, requested, expected, pending or inferred language fails.",
        "audience": "Current LinkedIn status reference. Ready proves processing only.",
        "suppression": "Named current source, refresh rule, owner, observed yes/no state and non-placeholder reference.",
        "delivery": "Actual ad-set delivery read-back with object IDs and observation time. Audience Ready does not satisfy it.",
        "outcome": "Actual destination/CRM event read-back with join key and observation time. Delivery does not satisfy it."
      },
      "stable_requests": {
        "REQ-CONTRACT": "Use contract maestro.linkedin-retargeting-plan.v1 version 1.1.0 and migrate the record before review.",
        "PLAN-SCOPE": "Supply the business, offer and buyer scope for this plan.",
        "PLAN-SOURCE": "Choose one supported source route and name the exact qualifying action.",
        "PLAN-MESSAGE": "Supply the next-message job, buyer question, offer and destination.",
        "PLAN-OWNERS": "Assign owners for the plan, data permission, message and measurement.",
        "PLAN-MEASUREMENT": "Supply the downstream event, CRM key and review trigger.",
        "REQ-SOURCE": "Supply the current selected source/action reference and observation date.",
        "REQ-TAG": "Supply the current active Insight Tag and website signal receipt.",
        "REQ-PERMISSION": "Supply explicit approved data-use evidence, owner and opt-out handling.",
        "REQ-AUDIENCE": "Supply the current LinkedIn audience status receipt and matched population state.",
        "REQ-SUPPRESSION-COMPLETED": "Supply the completed-step suppression source, refresh rule, owner and current read-back.",
        "REQ-SUPPRESSION-CUSTOMER": "Supply the customer suppression source, refresh rule, owner and current read-back.",
        "REQ-SUPPRESSION-OPPORTUNITY": "Supply the open-opportunity suppression source, refresh rule, owner and current read-back.",
        "REQ-SUPPRESSION-PRIVACY": "Supply the privacy/preference suppression source, refresh rule, owner and current read-back.",
        "REQ-MESSAGE": "Supply the next-message job, real proof asset, offer and destination.",
        "REQ-MEASUREMENT": "Supply the downstream event, CRM key, owner and review trigger."
      },
      "launch_boundary": "ready_for_operator_review is not audience creation, upload, spend authorization, campaign launch, delivery or business outcome.",
      "broadly_missing_rule": {
        "threshold": "Three or more incomplete planning groups",
        "groups": {
          "scope": [
            "business.name",
            "business.offer",
            "business.buyer_scope"
          ],
          "source": [
            "route",
            "source.route",
            "source.qualifying_action"
          ],
          "message": [
            "message.job",
            "message.buyer_question",
            "message.offer",
            "message.destination_url"
          ],
          "owners": [
            "business.owner",
            "permission.owner",
            "message.owner",
            "measurement.owner"
          ],
          "measurement": [
            "measurement.downstream_event",
            "measurement.crm_key",
            "measurement.review_trigger"
          ]
        },
        "behavior": "Return only the missing PLAN-* requests until fewer than three planning groups are incomplete. Do not ask for account receipts in this branch."
      },
      "source_route_binding": "source.route must equal the top-level route. Changing route never reuses evidence gathered for another route.",
      "timestamp_rule": "source.observed_at and audience.status_observed_at must be calendar-valid timezone-aware ISO 8601 timestamps.",
      "evidence_reference_rule": "Evidence references must be present and affirmative. Natural-language denied, pending, planned, requested, expected or unavailable references are not receipts.",
      "matched_population_rule": "usable requires an integer matched_accounts_count of at least 300; zero requires count 0; below_threshold requires an integer count from 0 through 299."
    }
    ```
    
    Reference implementation:
    ```python
    #!/usr/bin/env python3
    import copy,hashlib,json,re,sys
    from datetime import datetime
    from pathlib import Path
    HERE=Path(__file__).resolve().parent
    CONTRACT=json.loads((HERE/'contract.json').read_text())
    BAD=re.compile(r'^(?:unknown|not applicable|n/?a|na|pending|unavailable|denied|none|null|tbd|to be determined|planned|requested|expected|placeholder)$',re.I)
    NEGATIVE_REF=re.compile(r'\b(?:denied|pending|planned|requested|expected|unavailable|not\s+approved|not\s+available|not\s+complete|will\s+be|to\s+be\s+(?:added|provided|confirmed|verified))\b',re.I)
    ACTION_PATHS={'lead_gen_form':'source.lead_form_action','single_image':'source.single_image_action','document':'source.document_action','conversation':'source.conversation_action','company_page':'source.company_page_action','event':'source.event_action'}
    SUPPRESSION_IDS={'completed_next_step':'REQ-SUPPRESSION-COMPLETED','customer':'REQ-SUPPRESSION-CUSTOMER','open_opportunity':'REQ-SUPPRESSION-OPPORTUNITY','privacy_preference':'REQ-SUPPRESSION-PRIVACY'}
    PLAN_IDS={'scope':'PLAN-SCOPE','source':'PLAN-SOURCE','message':'PLAN-MESSAGE','owners':'PLAN-OWNERS','measurement':'PLAN-MEASUREMENT'}
    
    def present(v):
        if v is None or v is False:return False
        if isinstance(v,str):return bool(v.strip()) and not BAD.fullmatch(v.strip())
        return True
    def affirmative_ref(v):return present(v) and not (isinstance(v,str) and NEGATIVE_REF.search(v))
    def get(obj,path):
        cur=obj
        for part in path.split('.'):
            if not isinstance(cur,dict):return None
            cur=cur.get(part)
        return cur
    def valid_time(v):
        if not isinstance(v,str):return False
        try:
            parsed=datetime.fromisoformat(v.replace('Z','+00:00'))
            return parsed.tzinfo is not None
        except ValueError:return False
    def req(reqs,id,owner,reason):
        if any(x['id']==id for x in reqs):return
        reqs.append({'id':id,'owner':owner or 'Owner assignment required','reason':reason,'request':CONTRACT['stable_requests'][id]})
    def finish(x,requests):
        decision='ready_for_operator_review' if not requests else 'hold'
        reasons=[q['reason'] for q in requests] if requests else ['Planning, permission, audience, suppression, message and measurement evidence are complete.']
        clean=json.dumps(x,sort_keys=True,separators=(',',':'),ensure_ascii=False).encode()
        x['derived']={'decision':decision,'reasons':reasons,'requests':requests,'next_action':'An authorized operator reviews the record and performs account-specific launch checks.' if not requests else requests[0]['request'],'input_sha256':hashlib.sha256(clean).hexdigest()}
        return x
    
    def evaluate(source):
        x=copy.deepcopy(source);x.pop('derived',None);requests=[]
        if x.get('contract_id')!=CONTRACT['contract_id'] or x.get('contract_version')!=CONTRACT['contract_version']:
            req(requests,'REQ-CONTRACT',get(x,'business.owner'),'The contract identity or version is incompatible.')
        group_gaps={name:[p for p in paths if not present(get(x,p))] for name,paths in CONTRACT['broadly_missing_rule']['groups'].items()}
        incomplete=[name for name,gaps in group_gaps.items() if gaps]
        if len(incomplete)>=3:
            for name in ('scope','source','message','owners','measurement'):
                if name in incomplete:req(requests,PLAN_IDS[name],get(x,'business.owner'),f'The {name} planning group is incomplete: {", ".join(group_gaps[name])}.')
            return finish(x,requests)
        route=x.get('route')
        if route not in CONTRACT['routes']:
            req(requests,'REQ-SOURCE',get(x,'business.owner'),'Choose one supported route and supply its source evidence.')
        else:
            spec=CONTRACT['routes'][route]
            if get(x,'source.route')!=route:req(requests,'REQ-SOURCE',get(x,'business.owner'),'The source evidence kind does not match the selected route.')
            for field in spec['required']:
                value=get(x,field);ok=affirmative_ref(value) if field.endswith('evidence_ref') else present(value)
                if not ok:
                    id='REQ-TAG' if 'insight_tag' in field else 'REQ-PERMISSION' if field.startswith('permission.') else 'REQ-AUDIENCE' if field.startswith('audience.') else 'REQ-SOURCE'
                    req(requests,id,get(x,'permission.owner') or get(x,'business.owner'),f'Missing or non-affirmative {field}.')
            if spec.get('allowed_windows') and get(x,'source.window_days') not in spec['allowed_windows']:req(requests,'REQ-SOURCE',get(x,'business.owner'),'The source window is not valid for the selected route.')
            if spec.get('thresholds') and get(x,'source.video_view_threshold') not in spec['thresholds']:req(requests,'REQ-SOURCE',get(x,'business.owner'),'The video threshold is not valid for the selected route.')
            if spec.get('actions') and get(x,ACTION_PATHS[route]) not in spec['actions']:req(requests,'REQ-SOURCE',get(x,'business.owner'),'The source action is not valid for the selected route.')
            if route=='website' and get(x,'source.insight_tag_state')!='yes':req(requests,'REQ-TAG',get(x,'business.owner'),'The website route lacks an affirmative active Insight Tag state.')
        if not valid_time(get(x,'source.observed_at')):req(requests,'REQ-SOURCE',get(x,'business.owner'),'The source observation time is not a calendar-valid timezone-aware ISO 8601 value.')
        if get(x,'permission.state')!='approved' or not affirmative_ref(get(x,'permission.evidence_ref')) or not present(get(x,'permission.owner')) or not present(get(x,'permission.opt_out_process')):req(requests,'REQ-PERMISSION',get(x,'permission.owner'),'Explicit current data-use approval is incomplete.')
        if get(x,'audience.status')!='ready' or not affirmative_ref(get(x,'audience.status_evidence_ref')) or get(x,'audience.matched_accounts_state')!='usable' or not valid_time(get(x,'audience.status_observed_at')):req(requests,'REQ-AUDIENCE',get(x,'business.owner'),'LinkedIn Ready status and usable matched-population evidence are incomplete.')
        state=get(x,'audience.matched_accounts_state');count=get(x,'audience.matched_accounts_count');count_ok=isinstance(count,int) and not isinstance(count,bool)
        if (state=='usable' and (not count_ok or count<300)) or (state=='zero' and count!=0) or (state=='below_threshold' and (not count_ok or not 0<=count<300)):req(requests,'REQ-AUDIENCE',get(x,'business.owner'),'Matched population state and numeric count are inconsistent.')
        supplied={s.get('kind'):s for s in x.get('suppressions',[]) if isinstance(s,dict)}
        for kind,id in SUPPRESSION_IDS.items():
            s=supplied.get(kind,{})
            if s.get('state')!='yes' or not all(present(s.get(k)) for k in ('source','refresh_rule','owner')) or not affirmative_ref(s.get('evidence_ref')):req(requests,id,s.get('owner'),f'{kind} suppression lacks affirmative current evidence.')
        m=x.get('message',{})
        if not all(present(m.get(k)) for k in ('job','buyer_question','proof_asset','offer','destination_url','owner')):req(requests,'REQ-MESSAGE',m.get('owner'),'The next-message handoff is incomplete.')
        z=x.get('measurement',{})
        if not all(present(z.get(k)) for k in ('downstream_event','crm_key','owner','review_trigger')):req(requests,'REQ-MEASUREMENT',z.get('owner'),'The downstream measurement handoff is incomplete.')
        return finish(x,requests)
    
    if __name__=='__main__':
        source=json.load(open(sys.argv[1])) if len(sys.argv)>1 else json.load(sys.stdin)
        print(json.dumps(evaluate(source),indent=2,ensure_ascii=False))
    
    ```
    
    Canonical blank shape:
    ```json
    {
      "contract_id": "maestro.linkedin-retargeting-plan.v1",
      "contract_version": "1.1.0",
      "record_id": null,
      "fixture_status": "blank",
      "business": {
        "name": null,
        "offer": null,
        "buyer_scope": null,
        "owner": null
      },
      "route": null,
      "source": {
        "qualifying_action": null,
        "rule": null,
        "asset_ref": null,
        "window_days": null,
        "observed_at": null,
        "evidence_ref": null,
        "insight_tag_state": "unknown",
        "insight_tag_evidence_ref": null,
        "video_view_threshold": null,
        "lead_form_action": null,
        "single_image_action": null,
        "document_action": null,
        "conversation_action": null,
        "company_page_action": null,
        "event_action": null,
        "source_event_count": null,
        "route": null
      },
      "permission": {
        "state": "unknown",
        "evidence_ref": null,
        "owner": null,
        "notice_ref": null,
        "opt_out_process": null
      },
      "audience": {
        "name": null,
        "status": "unknown",
        "status_observed_at": null,
        "status_evidence_ref": null,
        "matched_accounts_state": "unknown",
        "matched_accounts_count": null
      },
      "suppressions": [
        {
          "kind": "completed_next_step",
          "source": null,
          "refresh_rule": null,
          "owner": null,
          "state": "unknown",
          "evidence_ref": null
        },
        {
          "kind": "customer",
          "source": null,
          "refresh_rule": null,
          "owner": null,
          "state": "unknown",
          "evidence_ref": null
        },
        {
          "kind": "open_opportunity",
          "source": null,
          "refresh_rule": null,
          "owner": null,
          "state": "unknown",
          "evidence_ref": null
        },
        {
          "kind": "privacy_preference",
          "source": null,
          "refresh_rule": null,
          "owner": null,
          "state": "unknown",
          "evidence_ref": null
        }
      ],
      "message": {
        "job": null,
        "buyer_question": null,
        "proof_asset": null,
        "offer": null,
        "destination_url": null,
        "cta": null,
        "owner": null
      },
      "measurement": {
        "downstream_event": null,
        "crm_key": null,
        "owner": null,
        "review_trigger": null,
        "delivery_state": "unknown",
        "delivery_evidence_ref": null,
        "business_outcome_state": "unknown",
        "business_outcome_evidence_ref": null
      }
    }
    ```
    
    Task: independently review and correct the pasted source-to-message record. Use the same broadly missing branch. Report every discrepancy before the corrected record.
    
    Return exactly: (1) route and decision; (2) concise readable handoff using the renderer grammar; (3) discrepancies for review or focused planning questions for build; (4) exact stable requests; (5) canonical JSON in one code fence; (6) one exact next action.
    
    PASTE RECORD AND RECEIPTS BELOW:
    

    Download the next-message video brief →

    The planner should produce one record with:

    • Source type and qualifying action
    • Source prerequisite and observation date
    • Window and audience status
    • Population state
    • Suppressions and their evidence
    • Message job, proof asset and offer
    • Destination and downstream event
    • CRM key and owner
    • Delivery and outcome states
    • Stable evidence requests
    • Decision and next action

    The readable Markdown and structured JSON should preserve the same values. Unknown, No, Zero and Not applicable are different values. Zero matched members is an observed number. Unknown means the evidence is missing. Not applicable needs a real route-specific reason.

    A complete record can become Ready for operator review. Launch still requires the actual account, permission, audience, destination, suppression and approval checks. If any critical fact is missing, the planner should keep the decision on Hold and state exactly who must supply what.

    LinkedIn retargeting checklist

    Before you hand the plan to an operator, confirm:

    • One observed action maps to one supported LinkedIn source route.
    • The source prerequisite and current account evidence are recorded.
    • The selected action or rule and window are explicit.
    • The audience status and population evidence are current.
    • Event, visit, view or form counts are not treated as matched population.
    • Completed-step, customer, open-opportunity and privacy suppressions have real sources and owners.
    • The next message follows from the action and leads to a continuing destination.
    • Public creative examples are treated as message examples, not proof of retargeting or results.
    • The downstream event, CRM key, owner and review trigger are named.
    • Delivery and business outcome remain Unknown until their own evidence exists.
    • Missing facts produce a Hold decision with focused requests.
    • Review does not create an audience, authorize spend or launch a campaign.

    If you can check every applicable item, the plan is ready for operator review. If you cannot, keep it on Hold. Give the next person a record that states exactly what is known, what is missing and what to do next.