Michiu / marketing reference

name: penn-outreach-log-spec type: brand-asset / penn-facilitation-tool / press-tracking-spec status: drafted by Casper (agency lead) 2026-05-13 — operational workflow doc for the press outreach log Penn maintains across every NL Tier-1 + future Tier-2/3 pitch applies_to: every reference to "Penn outreach log" in docs/penn-press-pitches-q1-2026.md §2.13 / §3.13 / §4.13 (pre-flight checklists); §2.14 / §3.14 / §4.14 (follow-up cadence status updates); §2.15 / §3.15 / §4.15 (outcome scenario log entries); §1 master template ("Penn outreach log records every pitch + outcome") helpers_must_consult: Penn (owner — sole writer to the log) · Insight (consumes the §7 weekly digest output) · Sun (briefs Penn on pitch timing per cultural-moments calendar + supplies cross-pitch coordination) · Michelle (per-pitch approval gate per §8.4 strategy doc escalation list) references:

  • docs/penn-press-pitches-q1-2026.md (every §X.13 + §X.14 + §X.15 references this log)
  • docs/strategy/2026-baseline.md §5.5 (Penn Power-Ups including press_outreach_log Power-Up — this spec is its operational doc)
  • docs/strategy/2026-baseline.md §4.4 (Tier-1 NL press table — the outlet master list this log tracks pitches against)
  • supabase/migrations/0041_press_outlets.sql (the outlet master table — outreach log rows FK to outlets via outlet_id)
  • supabase/migrations/0043_click_tracking.sql (m_campaign attribution loop; outreach log status transitions can trigger click_tracking events)
  • supabase/migrations/0053_campaigns.sql (pre-apply; future state: each pitch ladder belongs to a Campaign archetype, e.g. press_het_parool_grimm_mid_autumn_2026 Campaign holds the pitch attempts)
  • docs/q1-2026-operator-checklist.md §3 (Penn's punch-list — every pitch row produces log entries)

Penn outreach log — operational workflow spec

Penn maintains one structured record per pitch attempt. The same log surfaces: (a) what's pending right now; (b) when each outlet is re-pitchable; (c) the §7 weekly digest Insight consumes; (d) institutional memory across years. One writer (Penn). Many readers.


1. Purpose + scope

The Penn outreach log captures every press-pitch lifecycle from pre-pitch through one of the terminal states (published_* / closed_no_response). It supports:

  • Per-pitch tracking — what's been sent, what's pending follow-up, what's published
  • Cross-pitch coordination — preventing marketing-bomb anti-patterns (multiple outlets pitched the same angle in the same week)
  • Re-pitch eligibility calculation — per outlet, per outcome, when can Penn next legitimately reach out
  • Hit-rate analytics — published_* count / total sent, by outlet + by quarter
  • Institutional memory — outlet preferences, critic histories, what worked + what didn't

Scope: every press attempt to any outlet, across all tiers. Tier-1 NL critics (Grimm / Broekaert / Versprille) are the immediate use-case; Tier-2 NL trade press (Misset Horeca / Foodlog / De Volkskrant ankle-pages / etc.) + Tier-3 international (Vogue / FT Weekend / NYT Food) extend later with the same structure.

NOT in scope: review-reply tracking (Siren owns; separate domain), DM-inbox tracking (Anna owns), influencer outreach (not currently a Michiu channel per §11.2 strategy doc).


2. Workflow — when Penn writes to the log

Penn writes to the log at five lifecycle moments per pitch:

MomentStatus transitionTrigger
Pre-flight check passed(none)pre-pitchAll §X.13 pre-flight checklist items ✅; row created, send-date scheduled
Sendpre-pitchsentPenn clicks send; subject + body + recipient + send-time logged
Day 6 + Day 14 follow-upssentnudged_day6closed_no_response (if silent)Per the §X.14 follow-up cadence; status updates happen at the scheduled reminder
Reply / eventVarious transitions per §5 state machineWhen the critic responds OR an outcome event happens (article publishes; pre-tasting visit happens)
Terminal closure(any active state) → terminalWhen publication lands OR closed_no_response triggers; row freezes, re-pitch-eligibility-date set

Penn does NOT write to the log:

  • During real-time conversations with the critic (capture happens after; never in front of them)
  • For speculative ideas ("maybe we'll pitch X someday"); log is for committed lifecycle, not brainstorm
  • For outcomes that haven't happened ("pitch goes well next month"); the log is past-tense + present-tense, not forecast

3. Per-pitch capture record (one row per pitch attempt)

Schema reconciliation (2026-05-13): the §3 capture-form below is Penn's working tracking — broader than what the press_outreach_log schema persists. Per §8.1, the schema persists: outlet_id + contact + pitch_subject + pitch_angle + related_tactic_ref + m_campaign_slug + status (7-enum) + lifecycle timestamps + citation_* fields + free-text notes. The richer fields in this capture form (Day-6/Day-14 cadence, visit logistics, operational follow-through, re-pitch eligibility) live in Penn's calendar + the notes field as semi-structured prose. What's missing from schema persistence is not missing from Penn's workflow — it's just not enforced by columns.

═══════════════════════════════════════════════════════════
PITCH RECORD #[N]                                Status: [pre-pitch | sent | nudged_day6 | inbound_questions | inbound_verification_request | pitch_accepted_embargo_pending | tasting_confirmed | declined_politely | closed_no_response | visited_no_publication | published_strong | published_mid_score | published_destructive]
═══════════════════════════════════════════════════════════

IDENTITY
--------
Campaign slug:               [press_<outlet>_<critic>_<topic>_<year>]
                             e.g. press_het_parool_grimm_mid_autumn_2026
Outlet:                      [Het Parool | NRC | Volkskrant Magazine | Vrij Nederland | ...]
Critic / column / surface:   [Mara Grimm — Proefwerk column | Joël Broekaert — NRC reviews | ...]
Pitch angle:                 [reference to §X.X of penn-press-pitches-q1-2026.md OR future similar doc]
m_campaign tracking code:    [matches Campaign slug; cross-link to migration 0043 click_tracking]
press_outlets row FK:        [outlet_id from migration 0041]
Campaign archetype FK:       [campaign_id from migration 0053 — post-apply; null pre-apply]

SEND DETAILS
------------
Send date + time:            [YYYY-MM-DD HH:MM]
Send window slot:            [from §X.12 send-window matrix — e.g. "Tue 11 Aug 09:30 primary"]
Subject line (final):        [exact subject text]
Body version:                [reference to §X.8 or §X.9 — NL or EN]
Recipient address:           [exact email — verified against outlet vs personal vs Vogue per §X.7 anti-patterns]
Pre-read packet ready:       [yes — list components from §X.10 | no | conditional]
Pre-read packet shipped on:  [date — null until critic accepts]
One-link target:             [exact URL referenced in the body]

FOLLOW-UP CADENCE
-----------------
Day 6 nudge scheduled:       [date]
Day 6 nudge sent:            [date | n/a — critic responded before Day 6]
Day 14 soft-close scheduled: [date]
Day 14 soft-close sent:      [date | n/a]

REPLY + EVENTS LOG
------------------
[Date]:                      [Event description — "Reply received: asks for [topic]; replied within 24h with [named answers]"]
[Date]:                      [Event description]
[continue chronologically as events happen]

VISIT (if applicable)
---------------------
Visit confirmed:             [yes — date + party size + service shape (pre-tasting Grimm / regular Broekaert / regular Versprille) | no]
Visit date:                  [YYYY-MM-DD]
Anna prep notes:             [pre-tasting evening / regular-service / kitchen-accessibility level]
Visit outcome:               [happened-no-issues | declined-after-confirmation | re-scheduled | issue]
Post-visit Anna debrief:     [1-2 line summary captured within 24h while fresh — table-side observations, critic's questions]

PUBLICATION (if applicable)
----------------------------
Article published:           [date]
Article URL:                 [exact URL]
Score (if given):            [N/10 | n/a]
Key quotes (verbatim):       [verbatim quote 1; verbatim quote 2 — for §5.5 press page]
Booking impact observed:     [n/a until measurable; capture from Anna's Zenchef reservation surge data — Versprille moderate, Broekaert "four reservations per second", Grimm column-cycle]
Operational follow-through:  [if strong review: booking-surge prep complete? / if destructive: root-cause fix completed by date?]
LinkedIn quote-card created:  [yes — date + URL | no | not-applicable]

RE-PITCH ELIGIBILITY
--------------------
Closed-no-response window:   [outlet-specific — Grimm 6mo / Versprille 7mo / Broekaert 9mo / Tier-2/3 default 6mo]
Next pitch eligible from:    [calculated date — terminal_state_date + closed-no-response window]
Block-reason:                [if non-trivial, why this outlet is "do not pitch" for the eligibility window — e.g. "destructive review; structural soft-spot fix required first"]

PENN'S INTERNAL NOTES
---------------------
Soft-spot analysis:          [for mediocre/destructive reviews — what the critic flagged + root-cause analysis]
Future-pitch hooks:          [things the critic mentioned in passing that suggest future pitch angles]
Outlet relationship state:   [warm | neutral | cold | difficult — Penn's qualitative read]
Cross-pitch coordination:    [outlets pitched in the same 30-day window with adjacent angles — to flag for Sun's awareness]

═══════════════════════════════════════════════════════════

4. Field definitions — non-obvious fields

FieldDefinition + capture rule
Campaign slugpress_<outlet-slug>_<critic-slug>_<topic-slug>_<year> snake-case. The slug is the m_campaign tracking code; it appears in any URLs the pitch links + in the migration 0043 click_tracking events. Unique per pitch attempt — re-pitches to the same outlet/critic in a later year get a new slug (e.g. press_het_parool_grimm_yue_do_essay_2027)
Pitch angleExact §-reference in the pitch doc (e.g. §2.4 Mid-Autumn pop-up primary or §3.5 Grandmother Sundays secondary). Pitch angles are NOT interchangeable — pitching the same outlet with the same angle twice is the §2.7 anti-pattern that breaks credibility
StatusOne value from the §5 state machine. NEVER fuzzy ("kind of pending"). If status is ambiguous, the lifecycle is broken — capture an event in the reply-log and reflect it as a clean state transition
Day 6 nudge sentThe cadence in §X.14 is Day 6, not Day 7 or Day 3. Earlier reads as desperate; later misses the editorial-week. Penn's calendar reminder fires at the scheduled date; deviation is captured in the reply-log
Visit outcomeThe fact that a visit happened is its own milestone separate from publication. Critics can visit and not publish — the visit itself is a useful signal Penn can reference in future pitches
Closed-no-response windowPer outlet, per the §X.14 follow-up cadence. Grimm 6 months (Het Parool weekly column rhythm); Versprille 7 months (Volkskrant weekly + cook-background cycle); Broekaert 9 months (NRC slower-cycle). Tier-2/3 default 6mo unless outlet-specific cadence is documented
Cross-pitch coordinationPenn manually flags any pitch where another outlet was pitched the SAME angle within the last 30 days. The §1 master template anti-pattern "don't pitch within 14 days of a prior pitch to the same outlet" is the per-outlet rule; the cross-outlet rule is similar but applied across outlets pitching the same angle

5. Status state machine

Schema reconciliation (2026-05-13): the actual press_outreach_log.status enum has 7 values, not 15drafted / sent / responded / declined / no_response / cited / archived. The 15 states below are Penn's working-state taxonomy that map onto those 7 for persistence. Granular states (inbound_questions, tasting_confirmed, published_strong/mid_score/destructive, etc.) collapse into responded or cited + citation_sentiment enum + free-text notes. Penn maintains the granular distinction in working memory / calendar / notes field; schema persists the canonical 7-state lifecycle.

Schema-state mapping table:

Working state (this spec §5)Persists as schema stateAdditional schema fields populated
pre-pitchdrafted
sentsentsent_at
nudged_day6sent (still — nudge is an event in notes, not a state)append nudge-date to notes
inbound_questions / inbound_verification_request / pitch_accepted_embargo_pending / tasting_confirmedrespondedresponded_at + sub-state captured in notes
declined_politelydeclinedresponded_at + reason in notes
closed_no_responseno_response (cron auto-promotes from sent after pitch_window_lead_days * 2)
visited_no_publicationresponded (still — visit-without-publication keeps the row alive until cited or archived)visit date + Anna debrief in notes
published_strong / published_mid_score / published_destructivecitedcited_at + citation_url + citation_excerpt + citation_sentiment (positive/mixed/negative)
(Penn explicitly archives — outlet pivoted, ceased coverage, etc.)archived
FromToTrigger
(none)pre-pitchRow created when §X.13 pre-flight checklist passes; send-date scheduled
pre-pitchsentPenn clicks send
sentnudged_day6Day 6 silence → light nudge sent per §X.14
sentinbound_questionsCritic replies with questions (any day)
sentinbound_verification_requestCritic asks for supplier verification (Versprille-specific per §4.15)
sentpitch_accepted_embargo_pendingCritic accepts; pre-read packet to ship within 24h
sentdeclined_politelyCritic declines
nudged_day6closed_no_responseDay 14 silence → soft-close sent → terminal
nudged_day6inbound_questions / inbound_verification_request / pitch_accepted_embargo_pending / declined_politelyCritic responds after Day 6 nudge
inbound_questionspitch_accepted_embargo_pending / declined_politely / closed_no_responseCritic decides after Q&A
inbound_verification_requestpitch_accepted_embargo_pending / declined_politelyCritic decides post-verification
pitch_accepted_embargo_pendingtasting_confirmed (Grimm) / direct to regular-service visit window (Broekaert / Versprille)Visit scheduled
tasting_confirmedvisited_no_publication / published_strong / published_mid_score / published_destructiveVisit happens + critic decides
visited_no_publicationpublished_* (later landing)Article eventually publishes — could be days, weeks, or months later
visited_no_publication (no publication after 6 months)TerminalIf no publication after the outlet's closed-window, treat as terminal but distinct from closed_no_response (visit-happened-no-write is its own data point)
published_strong / published_mid_score / published_destructiveTerminalRow freezes; re-pitch eligibility date set
declined_politelyTerminalRow freezes; re-pitch eligibility shorter window (3-6 months) since the critic engaged
closed_no_responseTerminalRow freezes; re-pitch eligibility longer window (6-9 months per outlet) since the critic didn't engage

Terminal states are not editable beyond corrections of factual errors. Penn does not retroactively change closed_no_response to published_strong if the article eventually lands months later — instead, log a new event in the reply-log + create a NEW row with status published_strong and previous_pitch_id FK pointing at the prior row.


6. Re-pitch eligibility cadence (per outlet, per outcome)

OutletAfter closed_no_responseAfter declined_politelyAfter published_strongAfter published_mid_scoreAfter published_destructive
Het Parool — Grimm6 months3 months6 months12 monthsIndefinite — Michelle approves any re-pitch attempt
NRC — Broekaert9 months4 months6 months18 monthsIndefinite — same as above
Volkskrant — Versprille7 months4 months6 months18 monthsIndefinite — same as above
Tier-2 NL trade press6 months (default)3 months6 months9 months12 months
Tier-3 international6 months (default)3 months6 months9 months12 months

Window-shortening on accepted-engagement: an outlet that engaged (declined politely after dialogue, OR mid-score published with the critic visible-and-attentive) shortens the next window vs an outlet that ghosted. Engagement-without-publication is more valuable to track than no-engagement.

Indefinite window on destructive review: the §X.15 destructive-review row of the pitch docs requires crisis-mode handling + structural soft-spot fix within 14-30 days. Re-pitching the same outlet after a destructive review without a documented operational fix violates Penn's discipline and the §X.15 rule.


7. Weekly digest output — what Insight consumes

Every Monday 09:00 Penn (or an Insight cron Power-Up post-0053-apply) produces a digest:

═══════════════════════════════════════════════════════════
PENN OUTREACH LOG — WEEK OF [DATE]
═══════════════════════════════════════════════════════════

ACTIVE PITCHES (non-terminal)
-----------------------------
- [Campaign slug] · [outlet] · [critic] · status [N] · sent [date] · days-since [N]
- [continue per active row]

FOLLOW-UPS DUE THIS WEEK
------------------------
- [Campaign slug]: Day 6 nudge scheduled [date]
- [Campaign slug]: Day 14 soft-close scheduled [date]

RECENTLY PUBLISHED (last 14 days)
---------------------------------
- [Campaign slug] · [outlet] · score [N/10] · [URL] · operational-follow-through-status

UPCOMING SEND WINDOWS (next 14 days)
------------------------------------
- [Campaign slug] · [outlet] · scheduled send [date + slot]

OUTLETS APPROACHING RE-PITCH ELIGIBILITY
-----------------------------------------
- [Outlet] · last attempt [date] · outcome [status] · eligible from [date]

OUTLETS NEVER PITCHED (Tier-1 + Tier-2 cold-start opportunities)
----------------------------------------------------------------
- [Outlet] · default cadence window [N months] · pitch-angle candidates [from §4.4 strategy doc]

CROSS-PITCH COORDINATION FLAGS
-------------------------------
- [Campaign slug A] + [Campaign slug B] · same angle within 30 days · risk [low/medium/high]
- [If any flags present, Sun coordinates timing with Penn]

═══════════════════════════════════════════════════════════

Insight feeds this into Michelle's Monday-morning dashboard per §10.4 of the strategy doc — the press health row.


8. Cross-link to schema

8.1 press_outlets + press_outreach_log tables (migration 0041 — shipped; verified 2026-05-13)

Migration 0041 ships two tables + seeds 16 outlets across 3 tiers (8 NL Tier-1 + 3 global Tier-2 + 5 Reddit Tier-3). Penn does NOT have to enter outlets by hand — they exist on day one.

press_outlets (outlet master — reference data):

ColumnTypeNotes
idUUID PKgen_random_uuid()
account_idTEXTdefault 'michiu'; FKs to accounts
slugTEXT NOT NULLunique per account; e.g. nrc, parool, volkskrant
display_nameTEXT NOT NULLe.g. "NRC food (Achterpagina + Lekker)"
tierINTEGER NOT NULL1 = NL press, 2 = global English, 3 = Reddit/organic
outlet_typeTEXT NOT NULLCHECK: 8 values — national_press / city_press / trade_press / online_press / travel_press / aggregator / reddit / ranking_list
languageTEXT NOT NULLnl / en / mixed
primary_contact_nameTEXTe.g. "Joël Broekaert" (NULL for tier-3 reddit rows)
primary_contact_roleTEXTe.g. "Restaurant critic"
primary_contact_emailTEXTNULL in seed; Penn populates as obtained
primary_contact_handleTEXTLinkedIn URL / Twitter / subreddit name
contact_notesTEXTVerification + replacement history (e.g. "Verified 2026-05-11. Succeeded Mac van Dinther.")
pitch_cadenceTEXTCHECK: quarterly / bi_monthly / monthly / continuous / organic_only
pitch_window_lead_daysINTEGEROutlet-level lead time (Grimm: 21, Broekaert: 28, Versprille: 28)
m_campaign_slugTEXT NOT NULLConvention: press_<outlet_slug> short form (e.g. press_nrc, press_parool). Override per-pitch via the outreach-log row if multi-pitch tracking needed
urlTEXTOutlet homepage / section / subreddit URL
pitch_angle_notesTEXTPenn's strategic-fit reasoning at pitch-drafting time
is_activeBOOLEANSoft delete; default true
created_at / updated_atTIMESTAMPTZStandard timestamps

press_outreach_log (Penn's per-pitch activity log — what this spec governs):

ColumnTypeNotes
idUUID PKgen_random_uuid()
account_idTEXTdefault 'michiu'
outlet_idUUID NOT NULLFK to press_outlets.id; ON DELETE RESTRICT
contact_nameTEXT NOT NULLPer-pitch contact (may differ from outlet primary — e.g. multi-contact outlets)
contact_roleTEXT
pitch_subjectTEXT NOT NULLExact subject line of the email
pitch_angleTEXT NOT NULLe.g. "Mid-Autumn cha-chaan-teng pop-up (§2.4)"
related_tactic_refTEXTFree-text reference to §2 tactic — e.g. "Tactic 2.1" (will FK to campaigns once 0053 applies)
m_campaign_slugTEXT NOT NULLDefaults to outlet's m_campaign_slug; can override per-pitch (e.g. press_parool_grimm_2026 for multi-pitch tracking within one outlet across years)
statusTEXT NOT NULLCHECK: 7 values — drafted / sent / responded / declined / no_response / cited / archived. Default drafted
drafted_atTIMESTAMPTZ NOT NULL= created_at semantically
sent_atTIMESTAMPTZ
responded_atTIMESTAMPTZ
cited_atTIMESTAMPTZ
citation_urlTEXTPopulated when status = cited
citation_excerptTEXTVerbatim quote from the published article
citation_sentimentTEXTCHECK: positive / mixed / negative / neutral / NULL
notesTEXTFree-text — pitch context, response details, follow-up cadence tracking, anything not in the structured columns
created_at / updated_atTIMESTAMPTZStandard

Indexes: (account_id, outlet_id, status) + (account_id, status, drafted_at DESC) + a partial index (account_id, cited_at DESC) WHERE status = 'cited' for the §10 lagging-indicator query.

Seeded outlets (8 + 3 + 5 = 16):

  • Tier 1 (8 NL): nrc, parool, volkskrant, misset, foodie_amsterdam, entree, eet_nu, iens
  • Tier 2 (3 global EN): eater, cnt, timeout_ams
  • Tier 3 (5 Reddit): reddit_amsterdam, reddit_thenetherlands, reddit_askculinary, reddit_finedining, reddit_sake

8.2 campaigns table (migration 0053 — pre-apply, code-complete per CLAUDE.md)

Once 0053 ships, each pitch is wrapped in a Campaign archetype. The outreach log row gets a campaign_id FK. The Campaign holds:

  • Campaign slug (e.g. press_het_parool_grimm_mid_autumn_2026)
  • Strategy brief
  • KPIs (Penn-defined: was the pitch accepted, did a visit happen, did publication land)
  • Approval state (Michelle's §8.4 escalation gate)
  • m_campaign tracking code

Pre-apply: outreach log rows use just the press_outlets.id FK. Post-apply: add campaign_id. Backfill the historical rows once 0053 lands.

8.3 click_tracking (migration 0043 — shipped)

Every URL the pitch body links + every embargo-packet URL has the campaign slug as m_campaign. Outreach log status transitions can correlate with click_tracking events: e.g. pitch_accepted_embargo_pending correlates with the embargo-packet URL being clicked-through within 24-48h.


9. Anti-patterns

9.1 Don't write to the log during a live critic conversation

Capture happens after a conversation, not during. Critics talking to someone who's visibly typing notes feel handled, not heard.

9.2 Don't backfill from memory more than 7 days old

The log is a chain of small captures, not an act of memory-reconstruction. If an event is >7 days old and not captured, log it but mark backfilled with the date of capture vs the date of event. Future-Penn knows the gap.

9.3 Don't pitch the same outlet with the same angle twice

The §2.7 / §3.7 / §4.7 anti-patterns make this clear. The log enforces it: the §6 re-pitch eligibility cadence + the pitch angle field comparison + the cross-pitch coordination flag in §7 weekly digest.

9.4 Don't ship embargo packets to outlets that haven't accepted

The status state machine enforces this: pre-read packets ship only when status transitions to pitch_accepted_embargo_pending. Premature shipping (sending the dossier alongside the initial pitch) is the §X.10 anti-pattern (raises spam-score, reads as PR-heavy).

9.5 Don't reference internal log mechanics in conversation with the critic

Critics don't need to know that Michiu tracks pitches in a structured log with status transitions and re-pitch eligibility windows. The log is Penn's discipline; the conversation is the relationship.

9.6 Don't optimize log for "wins"

Hit-rate analytics (§7 digest, §8 schema) are useful operationally but should NOT drive pitch decisions. Pitching outlets purely because they have high published_*/total_sent ratios distorts coverage toward easy outlets. Tier-1 NL critics like Broekaert are LOW-hit-rate (he declines or destroys most pitches) but his strong reviews are 10× more valuable than 10 Tier-3 hits. Penn's qualitative judgment overrides the ratio.

9.7 Don't merge declined-politely into closed-no-response

The two terminal states look similar in a dashboard view but are operationally different. Declined politely = the critic engaged + said no; shorter re-pitch window + warm-to-cold relationship state. Closed-no-response = the critic ghosted; longer re-pitch window + cold relationship state. Merging them loses signal.


10. Worked example — Grimm Mid-Autumn pitch lifecycle (hypothetical)

For format-reference only; uses placeholder dates + outcomes.

═══════════════════════════════════════════════════════════
PITCH RECORD #001                                Status: tasting_confirmed
═══════════════════════════════════════════════════════════

IDENTITY
--------
Campaign slug:               press_parool *(outlet-default per schema convention; could override to press_parool_grimm_2026 if multi-pitch tracking matters across years)*
Outlet:                      Het Parool
Critic / column / surface:   Mara Grimm — Proefwerk column
Pitch angle:                 §2.4 Mid-Autumn pop-up primary (per penn-press-pitches-q1-2026.md)
m_campaign tracking code:    press_het_parool_grimm_mid_autumn_2026
press_outlets row FK:        [outlet_id 17]
Campaign archetype FK:       [null — 0053 not yet applied]

SEND DETAILS
------------
Send date + time:            2026-06-16 09:32
Send window slot:            Tue 16 Jun 09:30 (primary slot per §2.12)
Subject line (final):        Yue-do in Amsterdam-Zuid — mooncake-programma voor de Mid-Autumn 25 september
Body version:                §2.8 NL (placeholders filled by Michelle 2026-06-12 Saturday session)
Recipient address:           [Grimm's Het Parool editorial inbox — verified per §2.13]
Pre-read packet ready:       yes — 5 components per §2.10 (Michelle bio + Yue-do one-pager + dish detail card + pop-up logistics card + cha-chaan-teng context note)
Pre-read packet shipped on:  2026-06-19 (within 24h of Grimm's accept)
One-link target:             michiu.nl/en/about-us

FOLLOW-UP CADENCE
-----------------
Day 6 nudge scheduled:       2026-06-22
Day 6 nudge sent:            n/a — Grimm responded 2026-06-18
Day 14 soft-close scheduled: 2026-06-30
Day 14 soft-close sent:      n/a

REPLY + EVENTS LOG
------------------
2026-06-18 14:23:            Reply received — Grimm interested; asks for pre-read packet + pre-tasting evening 22 Sep
2026-06-19 09:00:            Penn ships §2.10 pre-read packet under embargo
2026-06-19 09:00:            Status → pitch_accepted_embargo_pending
2026-06-23 11:00:            Anna confirms 22 Sep 22:30 closing-service window with FOH
2026-06-23 11:00:            Status → tasting_confirmed

VISIT (if applicable)
---------------------
Visit confirmed:             yes — 2026-09-22 22:30, party of 2
Visit date:                  2026-09-22
Anna prep notes:             Pre-tasting in closing service; Michelle in-kitchen walks the dish; mooncake-only single-plate tasting + tea
Visit outcome:               [TBD — event scheduled, not yet happened at log-write time]
Post-visit Anna debrief:     [TBD]

PUBLICATION (if applicable)
----------------------------
[TBD pending visit + critic decision]

RE-PITCH ELIGIBILITY
--------------------
Closed-no-response window:   6 months (Het Parool — Grimm cadence)
Next pitch eligible from:    [TBD — calculated from terminal_state_date]
Block-reason:                [n/a until terminal]

PENN'S INTERNAL NOTES
---------------------
Soft-spot analysis:          [n/a until publication]
Future-pitch hooks:          Grimm's reply mentioned she's working on a Q4 piece about Asian patisserie evolution — possible follow-up angle for the §2.5 position-essay pitch in Q3 2026
Outlet relationship state:   warm (rapid reply + accepted pre-read + confirmed visit)
Cross-pitch coordination:    none active — Versprille pitch (press_volkskrant_versprille_sourcing_2026) scheduled for 2026-09-08, different angle, no conflict

═══════════════════════════════════════════════════════════

11. Decision log

  • 2026-05-13 — Drafted by Casper (agency lead) to formalize the "Penn outreach log" referenced across §X.13 / §X.14 / §X.15 of all three NL Tier-1 pitch packs. Same hybrid pattern as cast-1on1-question-set + supplier-dossier-template — structured capture format + workflow + state machine + worked example + anti-patterns + cross-link to schema.
  • 2026-05-13 — Status state machine designed with terminal-state freeze rule (no retroactive editing of closed_no_response if article eventually lands; new row with previous_pitch_id FK instead). Reason: the original close was a real event; rewriting history destroys institutional memory of the silence period.
  • 2026-05-13 — Re-pitch eligibility cadences (§6) per-outlet because the §X.14 follow-up cadences in the pitch docs are explicitly per-critic: Grimm 6mo / Versprille 7mo / Broekaert 9mo. The terminal-state windows mirror those forward.
  • 2026-05-13declined_politely vs closed_no_response kept as separate terminal states (anti-pattern §9.7). Engagement-without-publication is more valuable signal than no-engagement; merging them destroys it.
  • 2026-05-13visited_no_publication is non-terminal because publication can land months later. Only after the outlet's closed-window does it become terminal (or transition to published_* if/when).
  • 2026-05-13 — Weekly digest format (§7) is text-mode prose + bullets, not a dashboard view. Reason: Insight consumes this into Michelle's Monday-morning dashboard widget; the source format is text Penn can write to manually pre-0053-apply (no UI dependency), and Insight's downstream cron Power-Up can parse + format for the dashboard.
  • 2026-05-13 — Hit-rate analytics (§7 + §8) flagged as observability, NOT decision-driver (§9.6 anti-pattern). Tier-1 critics like Broekaert have low hit rates structurally — that's expected; their strong reviews are 10× more valuable than easier outlets.
  • Pending — Penn reviews + iterates. The state machine transitions in §5 are the highest-stakes content; Penn validates against the §X.14 + §X.15 cadences in the pitch docs to confirm no transition is missing.
  • Pending — Insight + Sun coordinate on the §7 weekly-digest cron Power-Up once 0053_campaigns.sql is applied live. Pre-apply: Penn writes the digest manually each Monday.
  • Pending — First pitch lifecycle (Grimm Mid-Autumn, Q2 2026) runs through this template end-to-end; lessons learned go into §11 decision log as v2 revisions.
  • 2026-05-13 — Read 0041_press_outlets.sql end-to-end and reconciled the spec with the actual schema. Critical mismatches resolved: (a) §8.1 replaced placeholder with verbatim field lists for BOTH tables; (b) §5 status state machine — schema enum is 7 values not 15, added a working-state→schema-state mapping table at section top; (c) §3 capture form — added a reconciliation note clarifying that richer fields live in notes text + Penn's calendar rather than dedicated schema columns; (d) §10 worked example — m_campaign_slug corrected from verbose press_het_parool_grimm_mid_autumn_2026 to schema convention press_parool (the override pattern is supported but not default). Also surfaced: schema seeds 16 outlets across 3 tiers, not just NL Tier-1 — Penn has Reddit + aggregator + trade-press outlets available on day one without manual entry.

12. Related references

  • Pitch packs: docs/penn-press-pitches-q1-2026.md §1 master template (Penn outreach log mention) + §2 Grimm / §3 Broekaert / §4 Versprille subsections §X.13 / §X.14 / §X.15 (the lifecycle moments this log captures)
  • Strategy doc: docs/strategy/2026-baseline.md §4.4 (Tier-1 NL press table — outlet master); §5.5 (Penn Power-Ups including press_outreach_log Power-Up — this spec is its operational doc); §10.4 (Michelle Monday-morning dashboard widget — the §7 digest feeds the press health row)
  • Operator punch-list: docs/q1-2026-operator-checklist.md §3 (Penn's pitch rows — each produces log entries)
  • Schema: migration 0041_press_outlets.sql (outlet master FK target); migration 0043_click_tracking.sql (m_campaign attribution); migration 0053_campaigns.sql (Campaign archetype FK — pre-apply)
  • Sister facilitation tools: docs/cast-1on1-question-set.md (Sun's parallel — structured capture for cast 1:1s); docs/supplier-dossier-template.md (Anna's parallel — structured capture for supplier dossier compilation)
  • Banned phrases: 0038_banned_phrases_2026_felt_not_told.sql (Julius runs on all pitch language before any status enters sent)

Source: michiu-marketing/docs/content/penn-outreach-log-spec.md. To edit, change the file in the repo and redeploy.