chore(linkedin-studio): M0-13 — 4 D2 templates + scrub leak + scaffold fallback

This commit is contained in:
Kjell Tore Guttormsen 2026-06-18 12:19:48 +02:00
commit 3797eaf6b1
7 changed files with 928 additions and 130 deletions

View file

@ -0,0 +1,211 @@
# Audience Demographics
Track WHO is actually engaging with your content. LinkedIn Analytics provides this data for free - use it to understand your real audience vs. your intended audience.
## How to Access This Data
1. Go to LinkedIn Analytics: https://www.linkedin.com/analytics/
2. Click on any post
3. Navigate to "Demographics" tab
4. Review data monthly and update this file
---
## Current Demographics (Last Updated: [Date])
### Industries (Top 10)
Based on LinkedIn Analytics → Post Analytics → Demographics
| Rank | Industry | % of Engagement | Trend |
|------|----------|----------------|--------|
| 1 | [Industry name] | [X]% | [↑/→/↓] |
| 2 | [Industry name] | [X]% | [↑/→/↓] |
| 3 | [Industry name] | [X]% | [↑/→/↓] |
| 4 | [Industry name] | [X]% | [↑/→/↓] |
| 5 | [Industry name] | [X]% | [↑/→/↓] |
| 6 | [Industry name] | [X]% | [↑/→/↓] |
| 7 | [Industry name] | [X]% | [↑/→/↓] |
| 8 | [Industry name] | [X]% | [↑/→/↓] |
| 9 | [Industry name] | [X]% | [↑/→/↓] |
| 10 | [Industry name] | [X]% | [↑/→/↓] |
**Key insights:**
- [Observation 1 - e.g., "60% from government sector, higher than expected"]
- [Observation 2 - e.g., "Tech companies underrepresented vs. my assumptions"]
- [Implication - e.g., "Should increase public sector case studies"]
---
### Job Functions (Top 10)
| Rank | Function | % of Engagement | Trend |
|------|----------|----------------|--------|
| 1 | [Function] | [X]% | [↑/→/↓] |
| 2 | [Function] | [X]% | [↑/→/↓] |
| 3 | [Function] | [X]% | [↑/→/↓] |
| 4 | [Function] | [X]% | [↑/→/↓] |
| 5 | [Function] | [X]% | [↑/→/↓] |
| 6 | [Function] | [X]% | [↑/→/↓] |
| 7 | [Function] | [X]% | [↑/→/↓] |
| 8 | [Function] | [X]% | [↑/→/↓] |
| 9 | [Function] | [X]% | [↑/→/↓] |
| 10 | [Function] | [X]% | [↑/→/↓] |
**Key insights:**
- [Who is actually engaging]
- [Implication for content framing]
---
### Seniority Levels
| Level | % of Engagement | Change vs. Last Month |
|-------|----------------|----------------------|
| Entry level | [X]% | [+/-X%] |
| Individual contributor | [X]% | [+/-X%] |
| Manager | [X]% | [+/-X%] |
| Director | [X]% | [+/-X%] |
| VP | [X]% | [+/-X%] |
| C-level | [X]% | [+/-X%] |
| Owner/Partner | [X]% | [+/-X%] |
**Key insights:**
- **Dominant level:** [Which level engages most]
- **Decision-maker presence:** [% at Director+ level]
- **Content implication:** [How technical/strategic should content be?]
---
### Geographic Distribution (Top 10 Countries)
| Rank | Country | % of Engagement | Trend |
|------|---------|----------------|--------|
| 1 | [Country] | [X]% | [↑/→/↓] |
| 2 | [Country] | [X]% | [↑/→/↓] |
| 3 | [Country] | [X]% | [↑/→/↓] |
| 4 | [Country] | [X]% | [↑/→/↓] |
| 5 | [Country] | [X]% | [↑/→/↓] |
| 6 | [Country] | [X]% | [↑/→/↓] |
| 7 | [Country] | [X]% | [↑/→/↓] |
| 8 | [Country] | [X]% | [↑/→/↓] |
| 9 | [Country] | [X]% | [↑/→/↓] |
| 10 | [Country] | [X]% | [↑/→/↓] |
**Key insights:**
- **Primary market:** [Where most engagement comes from]
- **Time zone implications:** [Optimal posting times]
- **Regional context:** [Does content need localization?]
---
### Company Size (Of Engagers)
| Size | % of Engagement | Trend |
|------|----------------|--------|
| 1-10 employees | [X]% | [↑/→/↓] |
| 11-50 | [X]% | [↑/→/↓] |
| 51-200 | [X]% | [↑/→/↓] |
| 201-500 | [X]% | [↑/→/↓] |
| 501-1000 | [X]% | [↑/→/↓] |
| 1001-5000 | [X]% | [↑/→/↓] |
| 5001-10000 | [X]% | [↑/→/↓] |
| 10000+ | [X]% | [↑/→/↓] |
**Key insights:**
- **Dominant segment:** [Enterprise/Mid-market/SMB]
- **Content implication:** [Scale of examples, budget assumptions]
- **Opportunity:** [Underserved segment to target]
---
## Intended vs. Actual Audience
### Who I Thought My Audience Was
- **Industries:** [Your original assumptions]
- **Roles:** [Your original assumptions]
- **Seniority:** [Your original assumptions]
- **Geography:** [Your original assumptions]
### Who My Audience Actually Is
- **Industries:** [Reality from data above]
- **Roles:** [Reality from data above]
- **Seniority:** [Reality from data above]
- **Geography:** [Reality from data above]
### Strategic Implications
**Content adjustments needed:**
1. [Adjustment 1 - e.g., "Increase public sector examples, decrease startup references"]
2. [Adjustment 2 - e.g., "Frame for Director-level, not just technical ICs"]
3. [Adjustment 3 - e.g., "Add European regulatory context"]
**Opportunities identified:**
1. [Opportunity 1 - e.g., "Large enterprise segment underserved by competitors"]
2. [Opportunity 2 - e.g., "Growing Nordic audience interested in topic X"]
---
## Follower vs. Engager Analysis
**Important distinction:**
- Your followers = who follows you
- Your engagers = who actually interacts with content
Often these are different groups. LinkedIn prioritizes showing your content to engagers, not just followers.
### Follower Demographics
[If you have LinkedIn Premium, note follower demographics here]
- [Key differences from engager demographics]
### Insight
[What the difference between followers and engagers tells you]
---
## Competitive Audience Analysis
How does your audience compare to key competitors/peers?
| Peer | Their Primary Industry | Their Seniority Level | Difference from Mine |
|------|----------------------|---------------------|---------------------|
| [Name] | [Industry] | [Level] | [What's different] |
| [Name] | [Industry] | [Level] | [What's different] |
| [Name] | [Industry] | [Level] | [What's different] |
**Content gap opportunity:**
[Where your unique audience positioning creates content opportunities]
---
## Month-over-Month Trends
### [Current Month] vs. [Previous Month]
**Industry shifts:**
- [What changed and why]
**Seniority shifts:**
- [What changed and why]
**Geographic shifts:**
- [What changed and why]
**Analysis:**
[What these trends indicate about content resonance and audience evolution]
---
## Update Schedule
- **Monthly:** Update all demographics from LinkedIn Analytics
- **Quarterly:** Deep analysis of trends and strategic implications
- **Yearly:** Major review of intended vs. actual audience fit
---
## Update Log
- **[Date]:** Initial demographics captured
- **[Date]:** Observed [significant change] in [demographic category]
- **[Date]:** Shifted content strategy based on [insight]

View file

@ -0,0 +1,267 @@
# My Audience Engagement Patterns
Track YOUR audience's specific behaviors and preferences here. This data is more valuable than generic "best practices" because it's based on YOUR actual results.
## Update Frequency
**Weekly (5 minutes):** Update posting times and add best-performing topic from the week
**Monthly (15 minutes):** Deep dive into patterns, update demographics, analyze format performance
---
## Best Posting Times (Based on MY Data)
**Important:** These should be YOUR times based on YOUR analytics, not generic advice. Track this in LinkedIn Analytics under "Post impressions by time of day."
### Primary Posting Windows
1. **[Day] at [Time]:** Avg. impressions: [X] | Avg. engagement: [Y]
- Why this works: [e.g., "My audience (public sector leaders) checks LinkedIn during lunch break"]
2. **[Day] at [Time]:** Avg. impressions: [X] | Avg. engagement: [Y]
- Why this works: [Your analysis]
3. **[Day] at [Time]:** Avg. impressions: [X] | Avg. engagement: [Y]
- Why this works: [Your analysis]
### Worst Posting Times (To Avoid)
- [Day/Time]: [Why it underperforms for YOUR audience]
- [Day/Time]: [Why it underperforms for YOUR audience]
**Update Log:**
- [Date]: [Change observed - e.g., "Tuesday 2pm now outperforms Friday 8am"]
---
## Top-Performing Topics (Last 90 Days)
Track which topics YOUR audience actually engages with, not what you think they should care about.
1. **[Topic]:** Avg. engagement: [X] | Posts: [Y]
- Best-performing post example: [Brief description]
- Why it resonates: [Your analysis]
2. **[Topic]:** Avg. engagement: [X] | Posts: [Y]
- Best-performing post example: [Brief description]
- Why it resonates: [Your analysis]
3. **[Topic]:** Avg. engagement: [X] | Posts: [Y]
- Best-performing post example: [Brief description]
- Why it resonates: [Your analysis]
### Topics That Surprisingly Underperformed
- **[Topic]:** [Why you thought it would work] → [Why it didn't]
- **[Topic]:** [Analysis]
**Implication for content strategy:**
[What you'll do differently based on this data]
---
## Format Performance (MY Audience)
Based on YOUR analytics, not generic benchmarks. Track in LinkedIn Analytics and your own spreadsheet.
### Format Rankings (By Engagement)
1. **[Format - e.g., "Story-based posts"]:**
- Avg. impressions: [X]
- Avg. engagement rate: [Y%]
- Best time to post: [When]
- Character sweet spot: [Range]
2. **[Format - e.g., "Framework posts"]:**
- Avg. impressions: [X]
- Avg. engagement rate: [Y%]
- Best time to post: [When]
- Character sweet spot: [Range]
3. **[Format - e.g., "Data/research posts"]:**
- [Same metrics]
4. **[Format - e.g., "Case study posts"]:**
- [Same metrics]
### Visual Content Performance
- **Posts with images:** Avg. engagement: [X] vs text-only: [Y]
- **Posts with documents:** Avg. engagement: [X]
- **Posts with carousels:** Avg. engagement: [X]
- **Video posts:** Avg. engagement: [X]
**Your insights:**
[What format performs best for YOUR audience and why]
---
## Hook Types That Work for ME
Not all hook styles work for all audiences. Track which hooks YOUR audience responds to.
### Top-Performing Hook Styles
1. **[Hook type - e.g., "Counterintuitive stat"]**
- Example: [Actual hook you used]
- Avg. engagement: [X]
- Why it works for your audience: [Analysis]
2. **[Hook type - e.g., "Bold contrarian statement"]**
- Example: [Actual hook]
- Avg. engagement: [X]
- Why it works: [Analysis]
3. **[Hook type - e.g., "Personal story opening"]**
- Example: [Actual hook]
- Avg. engagement: [X]
- Why it works: [Analysis]
### Hook Styles That Don't Work for YOUR Audience
- **[Hook type]:** [Why it underperforms with your specific audience]
- **[Hook type]:** [Why it underperforms]
---
## CTA Performance Analysis
Which calls-to-action actually drive engagement from YOUR audience?
### High-Performing CTAs
1. **[CTA type - e.g., "Specific implementation question"]**
- Example: "Which stage is your organization in?"
- Avg. comments generated: [X]
2. **[CTA type]**
- Example: [Actual CTA]
- Avg. comments generated: [X]
### Low-Performing CTAs (To Avoid)
- **[CTA type]:** [Why YOUR audience doesn't respond to this]
---
## Audience Demographics (Who Actually Engages)
Based on LinkedIn Analytics → Analytics → Demographics of people who interacted with your posts
### Industries (Top 5)
1. [Industry]: [% of engagement]
2. [Industry]: [% of engagement]
3. [Industry]: [% of engagement]
4. [Industry]: [% of engagement]
5. [Industry]: [% of engagement]
**Insight:** [What this means for content focus]
### Job Functions (Top 5)
1. [Function]: [% of engagement]
2. [Function]: [% of engagement]
3. [Function]: [% of engagement]
4. [Function]: [% of engagement]
5. [Function]: [% of engagement]
**Insight:** [How this should shape your content]
### Seniority Levels
- C-level: [%]
- VP/Director: [%]
- Manager: [%]
- Individual contributor: [%]
- Entry level: [%]
**Insight:** [Technical depth and framing implications]
### Geographic Distribution (Top 5 Countries)
1. [Country]: [%]
2. [Country]: [%]
3. [Country]: [%]
4. [Country]: [%]
5. [Country]: [%]
**Insight:** [Time zone and regional context considerations]
### Company Size (Of Engagers)
- 1-10 employees: [%]
- 11-50: [%]
- 51-200: [%]
- 201-500: [%]
- 501-1000: [%]
- 1001-5000: [%]
- 5001-10000: [%]
- 10000+: [%]
**Insight:** [Scale and organizational context implications]
---
## Content Length Performance (YOUR Data)
Track the optimal length for YOUR audience, not generic advice.
- **800-1000 characters:** Avg. engagement: [X]
- **1000-1200 characters:** Avg. engagement: [X]
- **1200-1500 characters:** Avg. engagement: [X]
- **1500-1900 characters:** Avg. engagement: [X]
- **1900+ characters:** Avg. engagement: [X]
**Your sweet spot:** [Range that consistently performs best]
**Why:** [Your analysis of why this works for your audience]
---
## Engagement Velocity Patterns
How quickly does YOUR content gain traction?
### First Hour Performance
- **Average engagement in first 60 minutes:** [X] likes, [Y] comments
- **Threshold for algorithm boost:** [Based on your data, when does reach accelerate?]
- **Your current hit rate:** [% of posts that hit the threshold]
### 24-Hour Patterns
- **Most engagement happens in:** [Time window - e.g., "First 3 hours"]
- **Secondary surge times:** [If applicable]
- **Typical engagement curve:** [Description of how your posts perform over 24 hours]
---
## Strategic Insights (The "So What")
Based on all the data above, what should you do differently?
### Content Strategy Adjustments
1. **More of this:** [What data says you should double down on]
2. **Less of this:** [What data says isn't working]
3. **Test this:** [New hypotheses based on patterns]
### Audience Alignment
- **Who you thought your audience was:** [Original assumption]
- **Who actually engages:** [Reality based on data]
- **Strategic implication:** [How content should shift]
### Competitive Edge Opportunities
Based on YOUR unique audience makeup:
- **Gap 1:** [Underserved need you could fill]
- **Gap 2:** [Content angle competitors miss]
- **Gap 3:** [Format opportunity]
---
## Monthly Comparison
Track month-over-month to see if patterns are stable or shifting.
### [Current Month]
- Avg. impressions per post: [X]
- Avg. engagement per post: [Y]
- Follower growth: [+X]
- Best-performing topic: [Topic]
- Best-performing format: [Format]
### [Previous Month]
- [Same metrics for comparison]
**Key changes:** [What's different and why]
---
## Update Log
- **[Date]:** [Significant finding - e.g., "Discovered Thursday posts now outperform Tuesday"]
- **[Date]:** [Pattern shift - e.g., "Framework posts have overtaken story posts in engagement"]
- **[Date]:** [Audience insight - e.g., "Realize 60% of engagers are from enterprise, not SMB"]

View file

@ -0,0 +1,60 @@
# High-Engagement Posts Collection
Store your top-performing posts here for pattern analysis. Add 5-10 of your best posts to identify what consistently works for YOUR audience.
> **Placeholder seed.** Your real, per-user collection lives in your external data
> dir (`~/.claude/linkedin-studio/examples/high-engagement-posts.md`). Replace the
> example structure below with your own posts.
## How to Use This File
After each successful post (high engagement relative to your baseline):
1. Add a new `## Post N` section (where N is a number) per saved post
2. Note engagement metrics and timing
3. Analyze WHY it worked (hook, angle, timing, CTA)
4. Document the replicable pattern
Claude studies these to learn your successful patterns and apply them to new content.
## Entry Format
Each saved post is one `## Post N` section with these fields:
- **Posted:** date, time, timezone
- **Engagement:** likes / comments / shares
- **Reach:** impressions and engagement rate
- **The Post:** the full post text
- **Why It Worked:** hook, angle, timing, CTA
- **Pattern to Replicate:** the elements you want to reuse
(Add your first `## Post N` section above this line once you have a high performer.)
## Patterns Across All High-Performing Posts
**Common Elements:**
- [ ] [Element you notice across your best posts]
- [ ] [Element 2]
**Audience Preferences (What YOUR Audience Responds To):**
- Format: [Your best-performing format]
- Length: [Your best-performing length]
- Tone: [Your best-performing tone]
- CTAs: [What drives replies for you]
**Topics That Resonate:**
1. [Topic]
2. [Topic]
**Best Posting Times (Based on YOUR Data):**
- Primary: [Time]
- Secondary: [Time]
- Avoid: [Time]
## Update Log
- [Date]: [What you added or learned]

View file

@ -2,157 +2,59 @@
Store your top-performing posts here for pattern analysis. Add 5-10 of your best posts to identify what consistently works for YOUR audience.
> **Placeholder seed.** Your real, per-user collection lives in your external data
> dir (`~/.claude/linkedin-studio/examples/high-engagement-posts.md`). Replace the
> example structure below with your own posts.
## How to Use This File
After each successful post (high engagement relative to your baseline):
1. Copy the full post text below
1. Add a new `## Post N` section (where N is a number) per saved post
2. Note engagement metrics and timing
3. Analyze WHY it worked (hook, angle, timing, CTA)
4. Document the replicable pattern
Claude will study these to understand your successful patterns and apply them to new content.
Claude studies these to learn your successful patterns and apply them to new content.
---
## Entry Format
## Post 1: Ralph Wiggum / Vibe Coding (BASELINE)
Each saved post is one `## Post N` section with these fields:
**Posted:** 2026-01-23, 23:13 CET (suboptimal timing)
**Engagement:** Likes: 19 | Comments: 6 | Shares: 0
**Reach:** 502 impressions
**Engagement Rate:** 4.98%
**Your Follower Count:** ~1,000
- **Posted:** date, time, timezone
- **Engagement:** likes / comments / shares
- **Reach:** impressions and engagement rate
- **The Post:** the full post text
- **Why It Worked:** hook, angle, timing, CTA
- **Pattern to Replicate:** the elements you want to reuse
**The Post:**
```
𝗘𝗻 𝗱𝗮𝗴. 𝟭𝟬 𝟬𝟬𝟬 𝗹𝗶𝗻𝗷𝗲𝗿. 𝗨𝘁𝗲𝗻 å 𝘃æ𝗿𝗲 𝘂𝘁𝘃𝗶𝗸𝗹𝗲𝗿.
Jeg er ikke utvikler. Jeg er KI-rådgiver. Jeg kan ikke skrive kode fra bunnen av.
Men jeg kan kommunisere med Claude Code. Og det viser seg at det er nok.
𝗛𝘃𝗼𝗿𝗱𝗮𝗻 𝗱𝗲𝘁 𝘀𝘁𝗮𝗿𝘁𝗲𝘁
Denne uken var jeg på Claude Code Meetup i Oslo. 250+ deltakere. Arrangert av Aleksander Stensby og Mesh Oslo.
Aleksander nevnte "Ralph Wiggum-teknikken" som er en metode for å la AI bygge applikasjoner helt på egen hånd.
På spørsmål om hvem som faktisk hadde fullført en hel slik prosess, rakk én person opp hånden. Av 250.
Den kvelden bestemte jeg meg: I morgen tester jeg dette.
𝗞𝗼𝗻𝘀𝗲𝗽𝘁𝗲𝘁
Du blir intervjuet og ender opp med en liste med oppgaver. Starter en prosess. Går og lager kaffe, eller sover.
Når du kommer tilbake er applikasjonen bygget.
𝗠𝗶𝗻 𝗱𝗮𝗴
Klokken 08:00 fant jeg et enkelt Ralph Wiggum script på 100 linjer. Klokken 23:00 hadde jeg 10 000 linjer og et komplett rammeverk.
Ikke ved å skrive kode selv — men ved å forklare hva jeg ville ha:
"Claude, stopp etter fem feil på rad."
"Claude, send meg Slack-melding når du er ferdig."
"Claude, lag en AI som vurderer om ting ser bra ut visuelt."
Claude foreslo løsninger. Jeg sa ja. Ferdig.
𝗙ø𝗹𝗲𝗹𝘀𝗲𝗻
Starte prosessen med 30 oppgaver. Gjør noe annet. Komme tilbake og se oppgavene tikke av. Én etter én.
Å våkne til en Slack-melding: "🎉 Ferdig. Alle 30 oppgaver fullført."
Å åpne mappen og se en fungerende app. Som jeg ikke skrev. Men som jeg 𝘥𝘦𝘧𝘪𝘯𝘦𝘳𝘵𝘦.
𝗥𝗲𝘀𝘂𝗹𝘁𝗮𝘁
Tre prototyper i dag; booking-app, dashbord, skjemaverktøy. Hver tok én time. Null linjer kode. Bare beskrivelser.
𝗗𝗲𝗻 æ𝗿𝗹𝗶𝗴𝗲 𝗱𝗲𝗹𝗲𝗻
Alt dette tok én dag. Og jeg skraper bare i overflaten.
Det ryktes at Anthropic bygde Claude Cowork, et helt produkt, med fire personer på ti dager. Vi er i starten av noe stort.
De som eksperimenterer nå kommer til å ha et forsprang. Det er ikke lenger AI som er begrensningen, det er deg og meg.
𝗦å 𝗷𝗮. 𝗥𝗮𝗹𝗽𝗵 𝗪𝗶𝗴𝗴𝘂𝗺.
Oppkalt etter Simpsons-karakteren som sier: "I'm learnding!"
Det føles passende :-)
Jeg jobber med KI i offentlig sektor. Mer om dette og andre eksperimenter i kommende innlegg.
𝗧𝗶𝗽𝘀: Claude Code Meetup i Oslo arrangeres jevnlig, sjekk [lenke]
#AI #ClaudeCode #VibeCoding #OffentligSektor #Innovasjon
```
**Why It Worked (Despite Mistakes):**
- **Hook:** Strong - "En dag. 10 000 linjer. Uten å være utvikler." Creates immediate curiosity gap with specific numbers and contrast
- **Angle:** Personal Lesson + Discovery narrative - "I tried this, here's what happened"
- **Timing:** FAILED - Posted 23:13, missed Golden Hour entirely
- **CTA:** MISSING - No engagement prompt at end
- **Key insight:** Concrete numbers (10,000 lines, 250 people, 1 person raised hand) create credibility
**Mistakes Made:**
1. Posted at 23:13 (should be 08:00)
2. Link in post body (should be in first comment)
3. 5 hashtags (should be 3-4)
4. No CTA (should ask question or invite discussion)
5. Em dash used (should avoid)
6. Post was in Norwegian (strategy says English)
**Pattern to Replicate:**
- Hook with specific numbers + contrast works well
- "I'm not X, but I did Y" framing creates relatability
- Concrete timeline (08:00 to 23:00) adds credibility
- "Følelsen" section (emotional payoff) resonates
- Bold-formatted section headers improve readability
**Audience Response Themes:**
- Interest in the technical process
- Questions about Ralph Wiggum technique
- Recognition from Claude Code community
**What to Test Next:**
- Same quality content, but posted at 08:00
- With proper CTA
- Without link in body
- In English
---
(Add your first `## Post N` section above this line once you have a high performer.)
## Patterns Across All High-Performing Posts
**Common Elements:**
- [x] Specific numbers in hook (10,000 lines, 250 people)
- [x] Personal story structure (I did X, here's what happened)
- [x] Concrete timeline and details
- [ ] Strong CTA (not yet tested)
- [ ] Optimal timing (not yet tested)
- [ ] [Element you notice across your best posts]
- [ ] [Element 2]
**Audience Preferences (What YOUR Audience Responds To):**
- Format: Story-based posts with concrete details
- Length: ~2,100 characters (slightly over optimal 1,800)
- Tone: Professional but personal, showing vulnerability ("I'm not a developer")
- CTAs: Unknown - need to test
- Format: [Your best-performing format]
- Length: [Your best-performing length]
- Tone: [Your best-performing tone]
- CTAs: [What drives replies for you]
**Topics That Resonate:**
1. AI-assisted coding / Vibe coding
2. [More data needed]
3. [More data needed]
1. [Topic]
2. [Topic]
**Best Posting Times (Based on YOUR Data):**
- Primary: Unknown - need to test 08:00 CET
- Secondary: Unknown - need to test
- **Avoid:** After 21:00 (confirmed by Ralph Wiggum failure)
- Primary: [Time]
- Secondary: [Time]
- Avoid: [Time]
## Update Log
- 2026-01-24: Added Ralph Wiggum post as baseline reference. Note: Post had good engagement rate (4.98%) despite multiple mistakes, suggesting content quality is strong. Focus on fixing timing, CTA, and link placement for next posts.
- [Date]: [What you added or learned]

View file

@ -0,0 +1,249 @@
# My Custom Post Templates
Save your proven post structures here. When you find a format that works consistently, document it so Claude can replicate the pattern.
---
## Template 1: [Name - e.g., "My Framework Introduction Template"]
**When to use:** [e.g., "When introducing a new framework or model I've developed"]
**Structure:**
```
[HOOK - Counterintuitive stat or bold statement]
(1-2 lines, <110 characters)
[CONTEXT - The problem this framework solves]
(2-3 lines explaining why people struggle)
[FRAMEWORK INTRODUCTION]
"I developed [Framework Name] to solve this."
(Brief one-line description)
[COMPONENT BREAKDOWN]
Stage 1: [Name]
→ [Key characteristic in one line]
Stage 2: [Name]
→ [Key characteristic in one line]
Stage 3: [Name]
→ [Key characteristic in one line]
[IMPLICATION]
"Most organizations are stuck at Stage 1.
Here's what moving to Stage 2 unlocks..."
(2-3 lines on practical value)
[CTA]
"Which stage is your organization in?"
```
**Why this works for me:**
- [Reason 1 - e.g., "My audience loves actionable frameworks"]
- [Reason 2 - e.g., "The diagnostic question always generates 15+ comments"]
**Example posts using this template:**
- [Link to post 1]
- [Link to post 2]
**Average engagement:** [Metrics]
---
## Template 2: [Name - e.g., "My Before/After Transformation Story"]
**When to use:** [e.g., "When sharing case study or project results"]
**Structure:**
```
[HOOK - The transformation in numbers]
"6 months ago: [painful metric]
Today: [improved metric]"
[THE BEFORE]
[Organization] was struggling with [specific problem].
(Paint picture of pain - 3-4 lines)
[THE TURNING POINT]
We decided to [key decision].
Most teams choose [alternative]. Here's why we didn't...
[THE APPROACH]
"Three things mattered:
• [Element 1]
• [Element 2]
• [Element 3]"
[THE AFTER]
Results:
→ [Metric 1]: [Before] → [After]
→ [Metric 2]: [Before] → [After]
→ [Metric 3]: [Before] → [After]
[KEY LESSON]
"The real breakthrough wasn't [expected thing].
It was [non-obvious insight]."
[CTA]
"What's been YOUR biggest lesson in [topic]?"
```
**Why this works for me:**
- [Reason 1]
- [Reason 2]
**Average engagement:** [Metrics]
---
## Template 3: [Name - e.g., "My Contrarian Take"]
**When to use:** [e.g., "When challenging conventional wisdom in my field"]
**Structure:**
```
[HOOK - Bold contrarian statement]
"Everyone says [conventional wisdom].
I think that's wrong."
[THE CONVENTIONAL APPROACH]
Most [target audience] believe [common belief].
(Explain the mainstream view fairly - 2-3 lines)
[WHY IT FAILS]
But here's the problem...
(2-3 specific reasons with examples)
[THE ALTERNATIVE]
Instead, try this:
→ [Alternative approach 1]
→ [Alternative approach 2]
→ [Alternative approach 3]
[EVIDENCE]
"I've seen this play out across [X] projects:
[Specific result/pattern you've observed]"
[NUANCE]
"To be clear: [conventional wisdom] works if [specific condition].
But for [your context], [your approach] is better because..."
[CTA]
"What's your experience? Am I missing something?"
```
**Why this works for me:**
- [Reason 1]
- [Reason 2]
**Average engagement:** [Metrics]
---
## Template 4: [Name - e.g., "My Failure Lesson Post"]
**When to use:** [e.g., "When sharing what didn't work to build trust"]
**Structure:**
```
[HOOK - Admission of failure]
"[Approach] should have worked.
It failed spectacularly."
[SETUP]
We were trying to [goal].
The plan: [what you intended to do]
On paper, perfect.
[THE FAILURE]
"Here's what actually happened..."
(Specific description of what went wrong - 3-4 lines)
[WHY IT FAILED]
Looking back, three mistakes:
1. [Mistake 1] - We assumed [wrong assumption]
2. [Mistake 2] - We underestimated [factor]
3. [Mistake 3] - We ignored [warning sign]
[THE PIVOT]
"So we tried [different approach] instead.
That worked because..."
[THE LEARNING]
"Key lesson:
[Non-obvious insight that only came from the failure]"
[CTA]
"Have you failed at [topic] too? What did you learn?"
```
**Why this works for me:**
- [Reason 1]
- [Reason 2]
**Average engagement:** [Metrics]
---
## Template 5: [Name - Your custom template]
**When to use:** [Context]
**Structure:**
[Your proven structure]
**Why this works for me:**
[Analysis]
**Average engagement:** [Metrics]
---
## Template Performance Comparison
| Template | Avg. Likes | Avg. Comments | Avg. Reach | Best Use Case |
|----------|-----------|---------------|------------|---------------|
| Framework Intro | [X] | [Y] | [Z] | [When] |
| Before/After | [X] | [Y] | [Z] | [When] |
| Contrarian | [X] | [Y] | [Z] | [When] |
| Failure Lesson | [X] | [Y] | [Z] | [When] |
**Insights:**
[What these patterns tell you about your audience preferences]
---
## Template Selection Guide
**Use Framework template when:**
- Introducing new model/system
- Teaching actionable process
- Want high saves (reference value)
**Use Before/After template when:**
- Have strong results to share
- Building credibility
- Want case study authority
**Use Contrarian template when:**
- Challenging assumptions
- Positioning unique POV
- Want engagement/debate
**Use Failure template when:**
- Building trust/authenticity
- Sharing hard-won lessons
- Want vulnerable connection
---
## Update Log
- [Date]: Created template 1 based on [successful posts]
- [Date]: Refined template 2 after [pattern observation]
- [Date]: Added template 3 for [new content type]

59
docs/m0/log.md Normal file
View file

@ -0,0 +1,59 @@
# M0 — Implementation Log
Running record of decisions, deviations, and out-of-scope follow-ups discovered
during M0 execution. Plan: `docs/m0/plan.md` (18 steps). History → git; this file
captures only what the commit messages cannot.
## Session 3 — Steps 1113 (2026-06-18)
### Environment reality vs. plan assumptions
The plan was authored assuming the operator's **real `.local.md` runtime data**
sat in the plugin tree (227-line voice profile, analytics exports, draft queue).
On this machine that data is **absent** — it is a clean clone:
- `assets/voice-samples/`: only the PII-free placeholder `authentic-voice-samples.md`
(+ `.template.md`). No `.local.md` source.
- `assets/drafts/`: only `.gitkeep`. `assets/analytics/`: only `README.md` + empty `ab-tests/`.
- The 4 tracked D2 scaffold instances DO exist (`high-engagement-posts.md`,
`demographics.md`, `engagement-patterns.md`, `my-post-templates.md`).
**Consequence for Step 12 (live migration):** every `MOVE_FILES` / `MOVE_DIRS`
entry resolved to an absent source → clean no-op. Only the 4 `COPY_FILES`
scaffolds were relocated. Result: `migrated — moved 0, copied 4, skipped 0`;
`.migrated` marker written; idempotent re-run confirmed `already-migrated`.
**Step 12 verify adapted:** the plan's literal check
(`test -f .../voice-samples/authentic-voice-samples.md`) cannot pass without a
`.local.md` source to move, so it was replaced with the achievable post-condition:
`.migrated` marker present + 4 scaffolds external + `migrateData` wired into
`session-start.mjs` + idempotency. The voice MOVE correctly no-op'd. (Operator
pre-approved this adaptation before the run.)
### OUT OF M0 SCOPE — git-history scrub of the leaked post (FOLLOW-UP)
`assets/examples/high-engagement-posts.md` held the operator's **real** LinkedIn
post at HEAD (the "Ralph Wiggum / vibe-coding" post — real names, real engagement
metrics, real personal narrative). Step 13 scrubbed the **working-tree** content
to a generic placeholder (0 `## Post N` sections → personalization score 0, no
PII). **This does not remove the post from git history.** A history rewrite
(`git filter-repo` / BFG) on `assets/examples/high-engagement-posts.md` is a
separate, explicit operation — **deferred, not done here** (brief §13: out of M0
scope). Track until the repo is published.
### Note — external instance retains pre-scrub content (by design)
The Step-12 migration copied `high-engagement-posts.md` to
`~/.claude/linkedin-studio/examples/high-engagement-posts.md` **before** Step 13
scrubbed the in-plugin file (B3 ordering). The external copy therefore still holds
the migrated content. That is the operator's private data dir (outside any repo) —
the operator may curate it; not an M0 concern.
### D2 scaffolds completed
All 6 scaffolds now have a read-only `*-template.*` seed: `case-study-template.md`
and `framework-template.md` already shipped; Step 13 added the 4 missing ones
(`high-engagement-posts-template.md`, `demographics-template.md`,
`engagement-patterns-template.md`, `my-post-templates-template.md`). The 3
already-generic instances seeded their templates verbatim; the high-engagement
template is a freshly-authored generic seed (the old instance was the leak).

View file

@ -83,3 +83,53 @@ describe('calculateScore — reads external instance data (M0-7)', () => {
assert.equal(score, 0);
});
});
describe('calculateScore — scaffold categories read the external instance (M0-13)', () => {
let dataDir, pluginRoot;
const saved = { LINKEDIN_STUDIO_DATA: process.env.LINKEDIN_STUDIO_DATA };
afterEach(() => {
for (const d of [dataDir, pluginRoot]) {
if (d && existsSync(d)) rmSync(d, { recursive: true, force: true });
}
dataDir = pluginRoot = undefined;
if (saved.LINKEDIN_STUDIO_DATA === undefined) delete process.env.LINKEDIN_STUDIO_DATA;
else process.env.LINKEDIN_STUDIO_DATA = saved.LINKEDIN_STUDIO_DATA;
});
test('a populated external high-engagement-posts instance earns the 10 points', () => {
({ dataDir, pluginRoot } = makeRoots());
process.env.LINKEDIN_STUDIO_DATA = dataDir;
mkdirSync(join(dataDir, 'examples'), { recursive: true });
const posts = ['## Post 1', '## Post 2', '## Post 3'].join('\n\n');
writeFileSync(join(dataDir, 'examples', 'high-engagement-posts.md'), `# Posts\n\n${posts}\n`, 'utf-8');
const { score, personalized } = calculateScore(pluginRoot);
assert.equal(score, 10, '3+ saved posts in the external instance earn the 10 points');
assert.equal(personalized, 1);
});
test('the generic placeholder seed (no line-leading ## Post N) scores 0 — no crash', () => {
({ dataDir, pluginRoot } = makeRoots());
process.env.LINKEDIN_STUDIO_DATA = dataDir;
mkdirSync(join(dataDir, 'examples'), { recursive: true });
writeFileSync(join(dataDir, 'examples', 'high-engagement-posts.md'), `# Posts\n\nPlaceholder — add a ## Post N section per saved post.\n`, 'utf-8');
const { score, personalized } = calculateScore(pluginRoot);
assert.equal(score, 0, 'a placeholder with no ## Post [0-9] section scores 0');
assert.equal(personalized, 0);
});
test('scaffold absent at the external root → 0, no crash (graceful degradation)', () => {
({ dataDir, pluginRoot } = makeRoots());
process.env.LINKEDIN_STUDIO_DATA = dataDir;
// examples/ dir never created — the category is simply skipped, never throws
const { score, personalized } = calculateScore(pluginRoot);
assert.equal(score, 0);
assert.equal(personalized, 0);
});
});