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_logPower-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_2026Campaign 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:
| Moment | Status transition | Trigger |
|---|---|---|
| Pre-flight check passed | (none) → pre-pitch | All §X.13 pre-flight checklist items ✅; row created, send-date scheduled |
| Send | pre-pitch → sent | Penn clicks send; subject + body + recipient + send-time logged |
| Day 6 + Day 14 follow-ups | sent → nudged_day6 → closed_no_response (if silent) | Per the §X.14 follow-up cadence; status updates happen at the scheduled reminder |
| Reply / event | Various transitions per §5 state machine | When the critic responds OR an outcome event happens (article publishes; pre-tasting visit happens) |
| Terminal closure | (any active state) → terminal | When 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_logschema 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-textnotes. 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 + thenotesfield 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
| Field | Definition + capture rule |
|---|---|
| Campaign slug | press_<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 angle | Exact §-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 |
| Status | One 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 sent | The 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 outcome | The 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 window | Per 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 coordination | Penn 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.statusenum has 7 values, not 15 —drafted/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 intorespondedorcited+citation_sentimentenum + free-textnotes. Penn maintains the granular distinction in working memory / calendar /notesfield; schema persists the canonical 7-state lifecycle.Schema-state mapping table:
Working state (this spec §5) Persists as schema state Additional schema fields populated pre-pitchdrafted— sentsentsent_atnudged_day6sent(still — nudge is an event innotes, not a state)append nudge-date to notesinbound_questions/inbound_verification_request/pitch_accepted_embargo_pending/tasting_confirmedrespondedresponded_at+ sub-state captured innotesdeclined_politelydeclinedresponded_at+ reason innotesclosed_no_responseno_response(cron auto-promotes fromsentafterpitch_window_lead_days * 2)— visited_no_publicationresponded(still — visit-without-publication keeps the row alive until cited or archived)visit date + Anna debrief in notespublished_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—
| From | To | Trigger |
|---|---|---|
(none) | pre-pitch | Row created when §X.13 pre-flight checklist passes; send-date scheduled |
pre-pitch | sent | Penn clicks send |
sent | nudged_day6 | Day 6 silence → light nudge sent per §X.14 |
sent | inbound_questions | Critic replies with questions (any day) |
sent | inbound_verification_request | Critic asks for supplier verification (Versprille-specific per §4.15) |
sent | pitch_accepted_embargo_pending | Critic accepts; pre-read packet to ship within 24h |
sent | declined_politely | Critic declines |
nudged_day6 | closed_no_response | Day 14 silence → soft-close sent → terminal |
nudged_day6 | inbound_questions / inbound_verification_request / pitch_accepted_embargo_pending / declined_politely | Critic responds after Day 6 nudge |
inbound_questions | pitch_accepted_embargo_pending / declined_politely / closed_no_response | Critic decides after Q&A |
inbound_verification_request | pitch_accepted_embargo_pending / declined_politely | Critic decides post-verification |
pitch_accepted_embargo_pending | tasting_confirmed (Grimm) / direct to regular-service visit window (Broekaert / Versprille) | Visit scheduled |
tasting_confirmed | visited_no_publication / published_strong / published_mid_score / published_destructive | Visit happens + critic decides |
visited_no_publication | published_* (later landing) | Article eventually publishes — could be days, weeks, or months later |
visited_no_publication (no publication after 6 months) | Terminal | If 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_destructive | Terminal | Row freezes; re-pitch eligibility date set |
declined_politely | Terminal | Row freezes; re-pitch eligibility shorter window (3-6 months) since the critic engaged |
closed_no_response | Terminal | Row 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)
| Outlet | After closed_no_response | After declined_politely | After published_strong | After published_mid_score | After published_destructive |
|---|---|---|---|---|---|
| Het Parool — Grimm | 6 months | 3 months | 6 months | 12 months | Indefinite — Michelle approves any re-pitch attempt |
| NRC — Broekaert | 9 months | 4 months | 6 months | 18 months | Indefinite — same as above |
| Volkskrant — Versprille | 7 months | 4 months | 6 months | 18 months | Indefinite — same as above |
| Tier-2 NL trade press | 6 months (default) | 3 months | 6 months | 9 months | 12 months |
| Tier-3 international | 6 months (default) | 3 months | 6 months | 9 months | 12 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):
| Column | Type | Notes |
|---|---|---|
id | UUID PK | gen_random_uuid() |
account_id | TEXT | default 'michiu'; FKs to accounts |
slug | TEXT NOT NULL | unique per account; e.g. nrc, parool, volkskrant |
display_name | TEXT NOT NULL | e.g. "NRC food (Achterpagina + Lekker)" |
tier | INTEGER NOT NULL | 1 = NL press, 2 = global English, 3 = Reddit/organic |
outlet_type | TEXT NOT NULL | CHECK: 8 values — national_press / city_press / trade_press / online_press / travel_press / aggregator / reddit / ranking_list |
language | TEXT NOT NULL | nl / en / mixed |
primary_contact_name | TEXT | e.g. "Joël Broekaert" (NULL for tier-3 reddit rows) |
primary_contact_role | TEXT | e.g. "Restaurant critic" |
primary_contact_email | TEXT | NULL in seed; Penn populates as obtained |
primary_contact_handle | TEXT | LinkedIn URL / Twitter / subreddit name |
contact_notes | TEXT | Verification + replacement history (e.g. "Verified 2026-05-11. Succeeded Mac van Dinther.") |
pitch_cadence | TEXT | CHECK: quarterly / bi_monthly / monthly / continuous / organic_only |
pitch_window_lead_days | INTEGER | Outlet-level lead time (Grimm: 21, Broekaert: 28, Versprille: 28) |
m_campaign_slug | TEXT NOT NULL | Convention: press_<outlet_slug> short form (e.g. press_nrc, press_parool). Override per-pitch via the outreach-log row if multi-pitch tracking needed |
url | TEXT | Outlet homepage / section / subreddit URL |
pitch_angle_notes | TEXT | Penn's strategic-fit reasoning at pitch-drafting time |
is_active | BOOLEAN | Soft delete; default true |
created_at / updated_at | TIMESTAMPTZ | Standard timestamps |
press_outreach_log (Penn's per-pitch activity log — what this spec governs):
| Column | Type | Notes |
|---|---|---|
id | UUID PK | gen_random_uuid() |
account_id | TEXT | default 'michiu' |
outlet_id | UUID NOT NULL | FK to press_outlets.id; ON DELETE RESTRICT |
contact_name | TEXT NOT NULL | Per-pitch contact (may differ from outlet primary — e.g. multi-contact outlets) |
contact_role | TEXT | |
pitch_subject | TEXT NOT NULL | Exact subject line of the email |
pitch_angle | TEXT NOT NULL | e.g. "Mid-Autumn cha-chaan-teng pop-up (§2.4)" |
related_tactic_ref | TEXT | Free-text reference to §2 tactic — e.g. "Tactic 2.1" (will FK to campaigns once 0053 applies) |
m_campaign_slug | TEXT NOT NULL | Defaults 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) |
status | TEXT NOT NULL | CHECK: 7 values — drafted / sent / responded / declined / no_response / cited / archived. Default drafted |
drafted_at | TIMESTAMPTZ NOT NULL | = created_at semantically |
sent_at | TIMESTAMPTZ | |
responded_at | TIMESTAMPTZ | |
cited_at | TIMESTAMPTZ | |
citation_url | TEXT | Populated when status = cited |
citation_excerpt | TEXT | Verbatim quote from the published article |
citation_sentiment | TEXT | CHECK: positive / mixed / negative / neutral / NULL |
notes | TEXT | Free-text — pitch context, response details, follow-up cadence tracking, anything not in the structured columns |
created_at / updated_at | TIMESTAMPTZ | Standard |
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_responseif article eventually lands; new row withprevious_pitch_idFK 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-13 —
declined_politelyvsclosed_no_responsekept as separate terminal states (anti-pattern §9.7). Engagement-without-publication is more valuable signal than no-engagement; merging them destroys it. - 2026-05-13 —
visited_no_publicationis non-terminal because publication can land months later. Only after the outlet's closed-window does it become terminal (or transition topublished_*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.sqlis 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.sqlend-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 innotestext + Penn's calendar rather than dedicated schema columns; (d) §10 worked example — m_campaign_slug corrected from verbosepress_het_parool_grimm_mid_autumn_2026to schema conventionpress_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 includingpress_outreach_logPower-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); migration0043_click_tracking.sql(m_campaign attribution); migration0053_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 enterssent)