diff --git a/docs/projects/2605-tech-for-non-technical-founders/TASK-TRACKER.md b/docs/projects/2605-tech-for-non-technical-founders/TASK-TRACKER.md index 284026d76..488ae6976 100644 --- a/docs/projects/2605-tech-for-non-technical-founders/TASK-TRACKER.md +++ b/docs/projects/2605-tech-for-non-technical-founders/TASK-TRACKER.md @@ -10,7 +10,7 @@ ## Open queue (in execution order) -0. **Sprint "Prove ICP Arrival" (validation) — ACTIVE, set 2026-08-13.** Manager panel (growth + learning + lean lenses, `/brainstorm`+vote) UNANIMOUS: with no traffic lift (84→75 sessions/14d, ~93% Direct, course absent from GSC) AND a dead funnel (start_course=1, mechanics=0), the constraint is **arrival/reach, not polish**. **Audit correction (premise was stale):** the campaign for this is ALREADY BUILT and READY — `linkedin-posts/icp-validation/POSTING-PACKET.md`, 10 posts drafted, zero posted, UTM scheme defined (`utm_campaign=icp_validation_`), **▶ POST #1 SCHEDULED 2026-08-13** on Paul's LinkedIn for Thu Aug 13 3:30 PM CEST (9:30am ET peak) via claude-in-chrome, verified in Scheduled posts — 2-week kill-clock starts on publish today. Post #1 is a **reply-CTA** post (validates ICP *presence*/language on LinkedIn, H1-H5), which is the correct **cheapest FIRST test** — upstream of course *arrival*. **Step 2 (backlog, manager-prepped): UTM'd course-link posts** to test click-through/arrival, drafted only if step-1 engagement appears (contradicts H5's no-link-CTA design, so gated on step-1 signal). **Manager autonomous work while Paul-gated:** verify packet still valid post-Aug-14 (✅ story post evergreen, passed 5 critic passes), prep step-2 arrival posts + the 5-day measurement/kill-criteria read. **Panel parked, data-justified:** rest of W4 (item 13) dead-mechanic removal → opportunistic; 36-image SVG migration → opportunistic; item 7 → BLOCKED by gate #1. +0. **Sprint "Prove ICP Arrival" (validation) — ACTIVE, set 2026-08-13.** Manager panel (growth + learning + lean lenses, `/brainstorm`+vote) UNANIMOUS: with no traffic lift (84→75 sessions/14d, ~93% Direct, course absent from GSC) AND a dead funnel (start_course=1, mechanics=0), the constraint is **arrival/reach, not polish**. **Audit correction (premise was stale):** the campaign for this is ALREADY BUILT and READY — `linkedin-posts/icp-validation/POSTING-PACKET.md`, 10 posts drafted, zero posted, UTM scheme defined (`utm_campaign=icp_validation_`), **▶ 2026-08-13 UPDATE:** the rescue-lane jira post was scheduled then PULLED (Paul: AI slop). It exposed the pipeline's broken "story, not advice" doctrine → corrected to **idea-first, deliver the point** (`linkedin-post-pipeline.md` + new `linkedin-posts/README.md` LI operating system: 2 lanes course/rescue, 2-3 posts/wk, frontmatter v2, `metrics-ledger.md`, `reference-examples.md` from Cutler/Rossi/Holub/Paolino). First idea-first post SHIPPED: course-lane `course-promo/week1-thu-validate-before-build.md`, scheduled 3:30pm CEST (text-only; image = manual gap). **Next wave: revise the ~10 existing lane drafts to the new doctrine, 2-3/wk, Paul-gated.** Post #1 is a **reply-CTA** post (validates ICP *presence*/language on LinkedIn, H1-H5), which is the correct **cheapest FIRST test** — upstream of course *arrival*. **Step 2 (backlog, manager-prepped): UTM'd course-link posts** to test click-through/arrival, drafted only if step-1 engagement appears (contradicts H5's no-link-CTA design, so gated on step-1 signal). **Manager autonomous work while Paul-gated:** verify packet still valid post-Aug-14 (✅ story post evergreen, passed 5 critic passes), prep step-2 arrival posts + the 5-day measurement/kill-criteria read. **Panel parked, data-justified:** rest of W4 (item 13) dead-mechanic removal → opportunistic; 36-image SVG migration → opportunistic; item 7 → BLOCKED by gate #1. 1. **Item 16 — Landing full-migration to the shuffle2 reference. ✅ DONE, MERGED (PR #444, squash `902686f3`, 2026-08-12).** Paul approved the render + flagged `bin/check-landing-parity` as redundant → removed (YAGNI). Design panel (conversion/taste/UX) decided Fork A = Option 2 + embedded CTA (dark NOT-cover, endcap merged into the dark base, no light sliver), Fork B = relocate all 4 off-reference sections, section reorder to reference order. Shipped T1-T6 (relocate 4 sections + 5 anchor repoints, reorder, gradient H1, 3-col mistakes, hero stat cells, dark band + merged endcap + 4 dead-selector cleanup, de-farmed chapter links). Linux baselines re-recorded via CI `update-baselines` (40-file env-drift re-sync incl. the intended `desktop/course/landing`) and rode the merge. Result render: `40-49-review/40.32-item16-result-full.jpeg`. Both reviewer agents failed on Fable quota → all blocking checks self-run with grep evidence. **Landing is live.** diff --git a/docs/workflows/linkedin-post-pipeline.md b/docs/workflows/linkedin-post-pipeline.md index 94fa24c67..76b2b08a2 100644 --- a/docs/workflows/linkedin-post-pipeline.md +++ b/docs/workflows/linkedin-post-pipeline.md @@ -107,41 +107,52 @@ Every line of every LinkedIn post must pass: --- -## Post shape: story, not advice (BLOCKING) - -The single biggest tell that a post is sales/marketing is its **shape**, not its words. Marketing posts follow a predictable arc: hook → anecdote → generalization → solution → objection-handling → empowerment → CTA. That shape itself reads as marketing even when every individual word is fine. - -Paul's posts must be **story-shaped**, not advice-shaped: - -| ❌ Advice shape (marketing) | ✅ Story shape (conversation) | +## Post shape: idea-first, deliver the point (BLOCKING) + +> **Doctrine corrected 2026-08-13.** The prior rule ("story, not advice" - force +> every post into a single-encounter parable) *generated* the AI slop Paul rejected: +> staged "a founder pinged me last Tuesday" openers, the tactic buried as the +> founder's future action (zero takeaway), and "So... So..." connectors. It is +> replaced below. Reference writers Paul rates: **John Cutler** (`johnpcutler`) and +> **Luca Rossi** (`lucaronin`, refactoring.fm) - study their recent activity. + +The marketing tell is the **arc**, not advice itself. Sales posts run hook → anecdote → generalization → solution → objection-handling → empowerment → CTA. Drop the arc - do NOT hide the point inside a parable. + +**Write idea-first, like Cutler and Rossi:** +- **Open with the idea, flat.** A belief, observation, or claim - not a staged encounter. Rossi: *"One of the dominant narratives in software today is that AI is making junior engineers redundant."* Cutler: *"'We want visibility' is stated as a universal need. But..."* +- **Argue it plainly, then take a position.** Rossi: *"It goes like this... I believe this is a mistake."* +- **Deliver the tactic in full.** Advice IS the value - give the actual move away. (Opposite of the old "hide the tactic inside what the founder will do next" rule.) +- **Plain, short sentences.** No stacked sub-clauses. Paul: "I write simpler." +- **Paragraph breaks are fine.** Cutler and Rossi use clear one-idea paragraphs. The old "don't separate the beats, add So-connectors" rule is **REVOKED** - it manufactured the beat-marking Paul flags as slop. +- **Close with a real peer question.** + +| ❌ Old parable shape (now banned) | ✅ Idea-first shape | |---|---| -| Open with a tagline ("Jira is not progress.") | Open with a specific recent encounter ("Founder showed me her sprint board last week.") | -| Generalize the pattern in the middle ("This shows up in almost every team I look at...") | Stay inside the encounter, let the reader generalize | -| Lift the tactical advice into a how-to section ("What works is asking for a URL...") | Embed the tactical move inside what the founder is going to do next ("She's going to try something this Friday: ...") | -| Add an objection-handling bullet list ("- We're refactoring → ...") | Skip the objection list. If the post must address objections, fold them into one sentence inside the story | -| Close with empowerment + question ("Any non-technical founder can do this. What's your story?") | Close with a single peer question ("Anyone else been in this version of it?") | +| Staged encounter opener ("A founder pinged me last Tuesday...") | The idea, flat ("A lot of non-technical founders read a full board as proof of progress.") | +| Bloat the encounter into a 4-paragraph screenplay with "So... So..." connectors | Argue the pattern in plain sentences | +| Bury the tactic as the founder's future action; deliver no advice | Deliver the tactic directly - reader can use it today | +| Manufactured specificity (14 tickets, since January, this Friday, ten minutes) | One real detail if you have it, else none - don't fabricate a tidy composite | -**The shape test:** Read the post in your head. If it could appear unchanged in a "5 ways to spot a stalled dev team" newsletter, the shape is wrong. Rewrite as a recounted encounter, not as advice with a story decorating it. - -### Story-shape skeleton +### Idea-first skeleton ``` -Beat 1 (1-2 lines): Specific recent encounter - concrete detail (number, day, role) -Beat 2 (1-2 lines): The reveal moment in the encounter -Beat 3 (1-2 lines): One line of opinion as observation, not slogan -Beat 4 (1-2 lines): What the person in the story is going to do next -Close (1 line): Peer question - "anyone else been in this version of it?" +Beat 1 (1 line): The idea / belief / observation, flat - no staged encounter, no credential +Beat 2 (1-2 lines): Restate it plainly, or show why it looks reasonable +Beat 3 (1-2 lines): Your position, flat +Beat 4 (3-5 lines): The tactic, delivered in full - the actual move the reader can make +Beat 5 (1 line): Why it matters +Close (1 line): Real peer question ``` -Length target: **120-180 words**. Story shape needs less transition scaffolding than the marketing arc, so posts run shorter. - -### First-draft warning: don't separate the beats into paragraphs - -The skeleton names 5 beats. The first-draft trap is to render each beat as its own paragraph with no connector to the prior beat. That produces a list-of-points shape that reads as outline, not story — the post will fail the read-aloud fluency test even if every individual sentence is clean. +Length target: **120-160 words**. Plain sentences, one idea per paragraph. -**Fix at the writing stage:** drop in connectors at the seams as you draft. "So we hopped on a quick call." "And the thing is..." "Anyway, we agreed she'd try..." Real spoken stories don't pause for breath at every clean beat. Two paragraphs of flowing prose almost always beat 5 paragraphs of separated beats. +### New slop tells (2026-08-13 - caught on the jira-not-progress + validate-before-build drafts) -**The Tuesday post lesson:** an initial 6-paragraph draft (one paragraph per beat, no connectors) was rewritten to 3 paragraphs by adding `so we hopped on a quick call`, `So we agreed she'd try a different one`, and `Beats three more sprints of...` — connectors that carry the listener forward. This is a writing-stage rule, not just an editing-stage fix. +- **Manufactured single-encounter parable** - a too-clean composite founder story built to illustrate a lesson. +- **"So... So... So..." beat-marking** / cinematic connectors ("So we hopped on a call") - screenplay reconstruction. (The old doctrine *mandated* these.) +- **Cost-stacked time-cut** - "six months and a big invoice later, you still..." - manufactured drama. +- **Stacked-clause long sentences** - one 30-word sentence with 3 sub-clauses. Break it up. +- **Engagement-bait close as the only payload** ("Anyone else been in this version of it?") when the body delivered no value. The question is fine *after* real value; not as a substitute for it. ### Hook archetype rotation (Beat 1) diff --git a/layouts/partials/seo/enhanced-meta-tags.html b/layouts/partials/seo/enhanced-meta-tags.html index c4e1792f3..e938aeee7 100644 --- a/layouts/partials/seo/enhanced-meta-tags.html +++ b/layouts/partials/seo/enhanced-meta-tags.html @@ -111,7 +111,8 @@ {{- $resource := $page.Resources.Get . -}} {{- if $resource -}} {{- if site.Params.cdn.enabled -}} - {{- $image = partial "cdn/url" (dict "page" $page "resource" $resource "params" "w=1200&h=630&fit=cover&output=webp&q=85") -}} + {{/* og:image must be jpg/png - LinkedIn's crawler won't render WebP (Telegram/most do). Keep jpg for reliable social unfurl. */}} + {{- $image = partial "cdn/url" (dict "page" $page "resource" $resource "params" "w=1200&h=630&fit=cover&output=jpg&q=85") -}} {{- else -}} {{- $optimized := $resource.Resize "1200x630 jpg q90" -}} {{- $image = $optimized.Permalink -}} diff --git a/linkedin-posts/README.md b/linkedin-posts/README.md new file mode 100644 index 000000000..2737cee4f --- /dev/null +++ b/linkedin-posts/README.md @@ -0,0 +1,135 @@ +# LinkedIn Operating System — Paul Keen / JetThoughts + +How we run Paul's LinkedIn: two lanes, a slow cadence, one voice doctrine, and +per-post analytics tracking. Nothing publishes without Paul. + +## Voice + shape (the engine) + +**Canonical:** `docs/workflows/linkedin-post-pipeline.md` → "Post shape: idea-first, +deliver the point (BLOCKING)". Corrected 2026-08-13 away from the old "story, not +advice" parable doctrine that produced AI slop. In one line: **open with the idea +flat, argue it plainly, deliver the tactic in full, plain short sentences, close +with a real peer question.** Study the writers Paul rates: John Cutler +(`johnpcutler`), Luca Rossi (`lucaronin`/refactoring.fm). Good examples transcribed +in [`reference-examples.md`](reference-examples.md). + +## The two lanes + +| Lane | Folder | Stage | ICP | Plan | +|---|---|---|---|---| +| **Course** (pre-validation) | `course-promo/` | idea-stage / about-to-build | validate demand *before* building | `docs/workflows/linkedin-course-promo-plan.md` | +| **Rescue** (control-loss) | `icp-validation/` | already building, can't verify | founder stuck with a dev shop | `docs/workflows/linkedin-icp-validation-plan.md` | + +Both post from Paul's personal account. **Rotate between lanes** so the feed isn't +all one stage. Assets (images) live in each lane's `assets/` folder. + +## Cadence (2026-08-13, Paul) + +**2-3 posts per week, max** — the best-for-ICP volume (non-technical founders don't +want a daily firehose). Post at the ICP's peak read time: **Tue-Thu, US-morning +(9-11am ET = ~15:00-17:00 CEST)**. Schedule via LinkedIn's native scheduler. One +lane per post, alternating. + +## Every post carries a visual (Paul: "missed images") + +Each post gets one image in its lane's `assets/`. Reuse course exhibits (the +refactoring.fm-style SVGs) exported to PNG via `rsvg-convert -w 1080 -o ` +— they're on-brand and seed the course bridge without a link. Frontmatter records +the path. + +> **Known tooling gap:** claude-in-chrome can schedule text but cannot drive +> LinkedIn's native file-upload dialog. Until solved, the image is attached +> manually by Paul (or dropped in a fresh composer). Track the fix in the backlog. + +## Frontmatter schema v2 + +Lifecycle + pointers in frontmatter; **performance data lives in the ledger, not +the frontmatter** (single source, no double-authoring — see below). + +```yaml +--- +lane: course | rescue +week: 1 +day: thursday +author: paul-keen +pillar: +hypothesis: +opener_archetype: idea-led | observation-led | question-led | stat-led | conflict-led +icp_test: +visual: assets/.png # required - the image that ships with the post +status: draft | scheduled | posted +scheduled_for: +posted_url: +first_comment: | # posted as the FIRST COMMENT right after publish (not the body) + +notes: | +--- +``` + +## Link policy per lane (BLOCKING) + +- **Never a link in the post body** - LinkedIn throttles reach on external links, and JT voice bans in-body CTAs. +- **Course lane** → one UTM'd course link in the **first comment** (`first_comment` in frontmatter). Link the specific lesson that delivers on the post's promise. This is the arrival signal the metrics-ledger tracks. +- **Rescue lane** → no link. Reply-CTA only (test ICP presence via replies, not clicks). +- Hashtags: 2-3 max, relevant, at the end of the body. 0 is acceptable and on-trend. Never a wall of tags. + +**Posting the first comment:** claude-in-chrome CAN do this (typing a comment needs no file dialog) - after the post publishes, add the `first_comment` text via the assistant. Only the image attach is a manual gap. + +## Analytics tracking — the ledger (proposed "better way") + +Instead of scattering metrics across 20 frontmatter blocks, **one reviewable table**: +[`metrics-ledger.md`](metrics-ledger.md). One row per posted post, filled from +LinkedIn analytics. This is the weekly review surface (same pattern as the outreach +`pipeline.md`). Frontmatter only carries `posted_url` + `status`; the ledger owns +the numbers. + +**Review workflow (per post):** +1. **~48-72h after posting**, open the post's LinkedIn analytics ("View analytics"). +2. Log the row: impressions, reactions, comments, reposts, profile views, and the + real signal — **ICP replies** (comments/DMs in ICP symptom-language). +3. **Weekly (Fri):** scan the ledger. Which opener archetype / lane / topic pulled + ICP replies? Reuse the winners; retire the flat ones. Note it in the ledger's + "what to reuse" column. +4. The `icp_replies` count, not impressions, decides whether the campaign is + validating (per each lane's plan kill-criteria). + +## Posting workflow + +1. Draft against the idea-first skeleton; self-score ≤2/10 (pipeline rubric) + the + shape-tell critic. +2. Export the visual to `assets/.png`. **Attach the image at compose time, + BEFORE scheduling** - you cannot add an image to an already-published post + (LinkedIn allows text edits only). Scheduling text-first to "add the image + later" is how the 2026-08-13 post shipped imageless. (Until claude-in-chrome can + drive the native upload dialog, Paul attaches the PNG in the composer.) +3. Stage the `first_comment` (course lane: UTM'd course link). +4. **Schedule at least 24 HOURS ahead** (Paul rule 2026-08-13) - never same-day or + imminent. The 24h gap is Paul's **pre-verify window**: he reviews the queued post + (text, image, shape) before it goes live and can tweak or pull it. Pick the next + Tue-Thu US-morning slot that is ≥24h out. +5. **Paul pre-verifies** within the window. Only then does it publish. +6. **After it publishes, the assistant posts the `first_comment`** via claude-in-chrome + (typing a comment needs no file dialog - this IS automatable). Course link lives + here, not the body. +7. Reply to ICP comments within ~2h; route real conversations to DM. +8. Log analytics 48-72h later in the ledger. + +### Link unfurl (why the course link shows no preview card) + +- **Comment links never unfurl on LinkedIn** - only body links generate a preview + card. A first-comment link is a bare clickable link by design (the cost of keeping + the link out of the reach-throttled body). +- Separately, our `og:image` is **WebP**. **Telegram unfurls it fine** (confirmed by + Paul 2026-08-13) - WebP-friendly crawlers are OK. **LinkedIn is the holdout**: its + crawler won't render WebP, so a LinkedIn *body* link shows no preview card. The fix + is LinkedIn-targeted: emit a jpg/png og:image in + `themes/beaver/layouts/partials/seo/enhanced-meta-tags.html` (or the root override). + Not a sitewide emergency (Telegram/most work); worth doing since LinkedIn is a key + channel. Tracked as an engineering task. + +## Files + +- `content-plan.md` — rolling 2-3/wk calendar, lane rotation, revision-wave queue. +- `reference-examples.md` — transcribed good posts to emulate (add more over time). +- `metrics-ledger.md` — per-post performance, the weekly review surface. +- `course-promo/` , `icp-validation/` — the two lanes, each with `README.md`, drafts, `assets/`. diff --git a/linkedin-posts/content-plan.md b/linkedin-posts/content-plan.md new file mode 100644 index 000000000..bcd4af639 --- /dev/null +++ b/linkedin-posts/content-plan.md @@ -0,0 +1,45 @@ +# LinkedIn content plan — rolling calendar + +**Cadence:** 2-3 posts/week, Tue-Thu, US-morning (9-11am ET = ~15-17 CEST). +**Rotate lanes** so the feed alternates course (pre-validation) and rescue (control-loss). +Every post: revised to idea-first → visual in `assets/` → scheduled → first comment +(course lane = UTM'd course link) → metrics logged 48-72h later in `metrics-ledger.md`. + +Status legend: `draft` (old parable, needs revision) · `revised` (idea-first, ready) · +`scheduled` · `posted`. + +## Schedule + +| Week of | Slot | Lane | Post | Status | +|---|---|---|---|---| +| 2026-08-11 | Thu | course | `course-promo/week1-thu-validate-before-build` | **scheduled** (text; image added manually; first comment pending) | +| 2026-08-18 | Tue | rescue | `icp-validation/week1-mon-jira-not-progress` → revise to idea-first | draft | +| 2026-08-18 | Thu | course | `course-promo/week1-mon-built-before-testing` → revise (or merge w/ validate-before-build) | draft | +| 2026-08-25 | Tue | rescue | `icp-validation/week1-tue-staging-question` → revise | draft | +| 2026-08-25 | Thu | course | `course-promo/week1-tue-founding-hypothesis` → revise | draft | +| 2026-09-01 | Tue | rescue | `icp-validation/week1-wed-trust-signals-poll` → revise | draft | +| 2026-09-01 | Thu | course | `course-promo/week1-thu-price-before-product` → revise | draft | + +Remaining course-promo drafts (first-move-poll, why-i-wrote-it, friends-politely-lying, +mom-test-past-questions, interview-count-poll, ten-interviews-recap) queue after, same +2-3/wk rotation. Poll-format posts count toward cadence too. + +## Revision wave (next execution) + +All `draft` posts above were written under the OLD "story, not advice" parable doctrine +and MUST be revised to idea-first (`docs/workflows/linkedin-post-pipeline.md`) before +scheduling. Run in **batches of 2-3 (one week's slots), Paul-gated per batch** - voice +work at volume is where slop returns. Batch 1 = the 2026-08-18 pair (jira rescue + +built-before-testing course). + +## Per-post checklist + +- [ ] Revised to idea-first, self-score ≤2/10 + shape-tell critic +- [ ] Visual exported to lane `assets/` +- [ ] `first_comment` staged (course lane: UTM'd course link) +- [ ] **Image attached in the composer BEFORE scheduling** (can't add to a live post) +- [ ] **Scheduled ≥24h ahead** for a Tue-Thu US-morning slot +- [ ] **Paul pre-verified** in the 24h window +- [ ] Published +- [ ] First comment posted right after publish (assistant, via claude-in-chrome) +- [ ] Metrics logged 48-72h later diff --git a/linkedin-posts/course-promo/assets/week1-thu-validate-before-build.png b/linkedin-posts/course-promo/assets/week1-thu-validate-before-build.png new file mode 100644 index 000000000..41b14a907 Binary files /dev/null and b/linkedin-posts/course-promo/assets/week1-thu-validate-before-build.png differ diff --git a/linkedin-posts/course-promo/week1-thu-validate-before-build.md b/linkedin-posts/course-promo/week1-thu-validate-before-build.md new file mode 100644 index 000000000..3f7716e20 --- /dev/null +++ b/linkedin-posts/course-promo/week1-thu-validate-before-build.md @@ -0,0 +1,39 @@ +--- +week: 1 +day: thursday +author: paul-keen +voice: personal-first-person +lane: course +pillar: pre-validation +hypothesis: course-thesis (validate demand before building) +icp_test: does the idea-stage / about-to-hire founder engage with "test demand before you build"? +cta: open question - how did you test demand before building? +campaign: course-promo +utm_campaign: course_promo_pre_validation +utm_content: validate-before-build +status: scheduled +scheduled_for: 2026-08-13 +visual: assets/week1-thu-validate-before-build.png (from dollar-presale-flow.svg, rsvg -w 1080) +first_comment: | + If it helps, the $1 pre-sale version of this - the exact button and the refund promise - is a free lesson in the course, no signup: + https://jetthoughts.com/course/tech-for-non-technical-founders-2026/fake-stripe-pre-sale-pieter-levels/?utm_source=linkedin&utm_medium=social&utm_campaign=course_promo_pre_validation&utm_content=validate_before_build +tags: "#startups #founders #buildinpublic" +dedup_note: overlaps course-promo/week1-mon-built-before-testing.md (demand-before-build) - keep this idea-first version as the model, revise/retire the older parable. +notes: | + Idea-first structure (Cutler/Rossi), NOT the old story-parable. Plain short + sentences (Paul: "I write simpler"). Course lane = pre-validation (2605), the + counterpart to the rescue-lane jira-not-progress post. No em dashes, no + cost-stacked time-cut, no "So...So..." beat-marking. AI self-score ~1/10. +--- + +A lot of non-technical founders hire a dev shop before they know if anyone wants the product. + +It feels like progress. You have a team, a timeline, a Figma, a plan. + +But building is expensive, and finishing it doesn't prove anyone will pay. + +The cheaper move: before you hire anyone, put up a one-page pitch for the thing and a way to say yes - a pre-order, a deposit, even an email from someone who matches your customer. If the people you're building for won't do that, more code won't change their mind. + +The build should come after someone has already tried to give you money, not before. + +If you're non-technical, how did you test demand before you started building? diff --git a/linkedin-posts/icp-validation/POSTING-PACKET.md b/linkedin-posts/icp-validation/POSTING-PACKET.md index 38f0e626e..404142d4d 100644 --- a/linkedin-posts/icp-validation/POSTING-PACKET.md +++ b/linkedin-posts/icp-validation/POSTING-PACKET.md @@ -1,6 +1,6 @@ -# Posting Packet — ICP post #1 (SCHEDULED) +# Posting Packet — ICP post #1 (PULLED, being reworked) -> **STATUS: SCHEDULED on Paul's LinkedIn for Thu 2026-08-13, 3:30 PM CEST (9:30am ET, US-morning B2B peak)** — done via claude-in-chrome, verified in LinkedIn "Scheduled posts". The 2-week kill-criteria clock starts on publish (2026-08-13). Next: monitor replies/DMs for ICP symptom-language; agent drafts responses, Paul sends. `week1-tue`/`week1-wed` drafts already written for the 3-4/wk Stream 0 cadence. +> **STATUS 2026-08-13: this jira-not-progress post was scheduled, then DELETED before publish** — Paul judged it AI slop (staged parable, no tactic, "So..." beat-marking). It exposed a broken doctrine in the pipeline ("story, not advice"), now corrected to **idea-first, deliver the point** (see `docs/workflows/linkedin-post-pipeline.md` + `linkedin-posts/README.md`). This post is a **rescue-lane** draft to be REVISED to the new shape, not reposted as-is. The first idea-first post that DID ship is the course-lane `course-promo/week1-thu-validate-before-build.md` (scheduled 3:30pm CEST 2026-08-13, text-only; image is the manual gap). The rescue-lane 2-week clock has NOT started. **For Paul. Total effort: copy the text block below, paste into LinkedIn, post.** Nothing else. This activates the campaign and starts the kill-criteria clock (register C1 addendum, 2026-08-08). diff --git a/linkedin-posts/metrics-ledger.md b/linkedin-posts/metrics-ledger.md new file mode 100644 index 000000000..085dc4e5e --- /dev/null +++ b/linkedin-posts/metrics-ledger.md @@ -0,0 +1,28 @@ +# LinkedIn metrics ledger — source of truth for post performance + +One row per **posted** post. Fill from LinkedIn analytics ~48-72h after posting, +then update at 7 days. This is the weekly review surface (Fri). Frontmatter carries +`status`/`posted_url` only; the numbers live here (no double-authoring). + +**The signal that matters is `icp_replies`** — comments or DMs in ICP symptom +language, not impressions. Impressions are reach; icp_replies are validation. + +| posted | slug | lane | opener | impressions | reactions | comments | reposts | profile views | icp_replies | what to reuse | +|---|---|---|---|---|---|---|---|---|---|---| +| 2026-08-13 | validate-before-build | course | idea-led | | | | | | | *(first idea-first post; log after 48-72h)* | + +## How to read a post's analytics + +1. Open the post → "View analytics" (or the impressions count under it). +2. Log impressions, reactions, comments, reposts, and profile-view delta. +3. **icp_replies:** read every comment/DM. Count the ones using ICP language + (e.g. "I can't tell if they're making progress", "the repo is under their name", + "I built the wrong thing first"). Those are the qualified signal. +4. Weekly: which opener archetype / lane / topic produced icp_replies? Reuse the + winners in the next 2-3 drafts; retire the shapes that only got impressions. + +## Kill-criteria tie-in + +Each lane's plan has a 2-week kill criterion. Evaluate it against the `icp_replies` +column here, not impressions. Near-zero icp_replies across a lane's posts = the +message/segment isn't landing (revisit before spending more reach). diff --git a/linkedin-posts/reference-examples.md b/linkedin-posts/reference-examples.md new file mode 100644 index 000000000..b80faf9a3 --- /dev/null +++ b/linkedin-posts/reference-examples.md @@ -0,0 +1,69 @@ +# Reference examples — good LinkedIn posts to emulate + +Writers Paul rates. They all share one shape: **idea-first, plain sentences, +deliver the point, no staged parable.** Study these before drafting. Add more as +you find them (paste the text + name the move). + +Captured 2026-08-13 from recent activity. + +--- + +## John Cutler (`johnpcutler`) — think-out-loud on a pattern + +Opens with a belief, complicates it, stays conversational. One idea per paragraph. + +> "We want visibility" (or transparency) is stated as a universal, forever need. But visibility without an operating habit for responding to reality, it is worse than having nothing. +> +> What people are saying, in many cases, is, "We want the sense of visibility... but we want it with equal or less effort/investment and we don't want too much of it, especially the kind that makes us uncomfortable." +> +> A leader will go weeks without actively investing time in managing their group, and then suddenly want visibility. [...] +> +> The idea of "making work visible," that visibility alone will solve the problem, is flawed. It is what you do once it is made visible. + +**The move:** name a thing everyone says → show the uncomfortable reality underneath → no CTA, ends on the real point. Uses hand-drawn diagrams. + +--- + +## Luca Rossi (`lucaronin`, refactoring.fm) — name the narrative, then counter it + +> One of the dominant narratives in software today is that AI is making junior engineers redundant. +> +> It goes like this: AI can approximate what a junior engineer produces, while only senior engineers can steer these tools. So many companies freeze junior hiring [...] +> +> I believe this is a mistake, and I mean from a practical, business perspective. +> +> In my experience, the junior vs senior frontier is jagged. Senior engineers gain experience, but they can also become biased and more resistant to change. Juniors often adapt faster because they have less to unlearn. +> +> Also, production is only the first-order output of a team. You also need to think about process, hiring, retention, and growth: [then a short labeled list] + +**The move:** "One of the dominant narratives is X." → "It goes like this…" → "I believe this is a mistake." → plain argument → scannable list. His diagrams ARE our course-exhibit style (refactoring.fm). + +--- + +## Allen Holub (`allenholub`) — flat contrarian conviction + +> Product work is not a distraction from the work; it is the work. There are many programmers who don't seem to get that. We are building products, not (just) writing code. A pile of code that doesn't [ship value] [...] + +Also plain first-person experience: *"I've found that using TDD as part of my process, when I specify the tests and then tell the AI to get them to pass, works pretty well. However..."* + +**The move:** state the conviction flat and a little against-the-grain, back it in plain sentences. Short. Opinionated. No hedging, no parable. + +--- + +## Carmine Paolino (`carminepaolino`) — plain build-in-public + +Short, humble, concrete product updates in the first person. *"My Rails backup solution, kamal-backup, hit 1.0.0.rc1."* / *"We're cooking something good."* Often with a demo image. + +**The move:** say the real thing you did, plainly, with a concrete artifact. No hype arc. + +--- + +## What they all avoid (our banned shapes) + +- No "a founder pinged me last Tuesday" staged encounter. +- No "So… So… So…" cinematic connectors. +- No cost-stacked drama ("six months and a big invoice later…"). +- No engagement-bait question standing in for a real point. +- No stacked-clause 30-word sentences. + +See `docs/workflows/linkedin-post-pipeline.md` → "Post shape: idea-first, deliver the point".