From 1e8892fdec3aaaac716c42b19a593de5093b24f6 Mon Sep 17 00:00:00 2001 From: Doug Hatcher Date: Mon, 18 May 2026 21:49:54 -0400 Subject: [PATCH] feat(linkedin-copy): keep cross-post above the LinkedIn mobile fold MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 250-400 word linkedin_copy generated by idea-generator was producing ~1500-char posts that micro.blog truncated when syndicating to LinkedIn, leaving a "...see more" link to the micro.blog note alongside our intended "Full post:" link. Two competing CTAs, body cut mid-sentence. Target: ≤280 chars total including the URL line. 1-3 short lines, lifted from the strongest sentences in the post itself. - idea-generator.js: schema description + prompt rewritten for the tease format; new posts will be generated this way going forward. - microblog-poster.js fallback prompt: same constraints. - 2026-04-25-devops post: hand-tightened to opener + closer + URL (~259 chars). Verified above-the-fold against LinkedIn mobile width. --- apps/editorial-loop/lib/idea-generator.js | 17 +++++++------- apps/editorial-loop/lib/microblog-poster.js | 22 ++++++++++--------- ...devops-matters-more-when-ai-writes-code.md | 10 --------- 3 files changed, 20 insertions(+), 29 deletions(-) diff --git a/apps/editorial-loop/lib/idea-generator.js b/apps/editorial-loop/lib/idea-generator.js index 16dafbb..4cbf599 100644 --- a/apps/editorial-loop/lib/idea-generator.js +++ b/apps/editorial-loop/lib/idea-generator.js @@ -38,7 +38,7 @@ const IDEA_TOOL = { source_material: { type: 'string', description: 'Vault files or patterns that informed this idea' }, slug: { type: 'string', description: 'URL-friendly slug, e.g. "optimism-cascade-replatform"' }, draft_content: { type: 'string', description: 'Full markdown draft including frontmatter, 800-1200 words' }, - linkedin_copy: { type: 'string', description: '250-400 word LinkedIn post. Opens with a specific claim or observation — not "excited to share." Written for two audiences at once: executive leaders (organizational judgment, strategic outcomes, what broke and why) and technical leaders (specific tradeoffs, architectural reasoning, the thing practitioners actually wrestle with). No motivational language. No buzzwords. Ends with exactly: "Full post: {{url}}" — nothing else.' }, + linkedin_copy: { type: 'string', description: 'Short LinkedIn tease, ≤280 characters TOTAL including the URL. 1–3 short lines max. Opens with a specific claim or observation — not "excited to share." Above-the-fold on LinkedIn mobile: no truncation, no "...see more" link. Lift the strongest sentence(s) from the post itself rather than paraphrasing. No motivational language. No buzzwords. Ends with exactly: "Full post: {{url}}" — nothing else.' }, }, }, }, @@ -151,17 +151,16 @@ tags: [] Body format: short punchy paragraphs, no headers needed for shorter posts, use plain markdown. **For linkedin_copy:** -Write as a senior technical practitioner who leads engineering orgs and ships real product. The post should speak to two audiences simultaneously: -- Executive and business leaders: organizational awareness, strategic judgment, what the decision costs and why it matters, the failure mode nobody talks about -- Technical leaders and architects: specific tradeoffs, concrete failure modes, the implementation detail that changes everything +This is a TEASE, not the post. It must stay above the LinkedIn mobile fold — no "...see more" link, no truncation. Hard ceiling: 280 characters TOTAL including the "Full post: {{url}}" line. -Open with a single specific observation or claim — the kind of sentence that makes a VP of Engineering stop scrolling because they've lived it. Not a question. Not an announcement. A statement of something true and underappreciated. +Structure (1–3 short lines, blank line between): +1. The strongest single sentence from the post — the claim that makes a VP of Engineering stop scrolling because they have lived it. +2. (Optional) One more sentence that delivers the counterintuitive punchline. +3. \`Full post: {{url}}\` — exactly this, nothing else. -Middle: show the thinking. What the obvious answer gets wrong. What the counterintuitive principle is. Be specific enough that a technical reader recognizes real experience. +Prefer lifting verbatim sentences from the draft over paraphrasing. The point is to make the reader click through, not to summarize the argument. -End with exactly: "Full post: {{url}}" — no call-to-action fluff, no "let me know your thoughts." - -No em-dashes. No hedging. No "I'm thrilled to share." Sound like someone who has already solved this problem twice.`; +No em-dashes. No hedging. No "I'm thrilled to share." No call-to-action fluff. Sound like someone who has already solved this problem twice.`; const response = await client.messages.create({ model: 'claude-opus-4-6', diff --git a/apps/editorial-loop/lib/microblog-poster.js b/apps/editorial-loop/lib/microblog-poster.js index 7f3a802..9188dfc 100644 --- a/apps/editorial-loop/lib/microblog-poster.js +++ b/apps/editorial-loop/lib/microblog-poster.js @@ -32,26 +32,28 @@ export async function generateMicroblogPost(postContent, postUrl) { const response = await client.messages.create({ model: 'claude-opus-4-6', - max_tokens: 1024, + max_tokens: 512, messages: [{ role: 'user', - content: `You are writing a LinkedIn post for Doug Hatcher, a Director of Engineering with deep roots in commerce architecture and platform engineering. + content: `You are writing a short LinkedIn tease for Doug Hatcher, a Director of Engineering with deep roots in commerce architecture and platform engineering. -Write for two audiences at once: executive leaders (what broke, why it matters to the org, the strategic judgment call) and technical leaders (the specific tradeoff, the implementation detail that changes everything, the failure mode practitioners live with). +This is a TEASE, not the post. Stay above the LinkedIn mobile fold — no "...see more" link, no truncation. Hard ceiling: 280 characters TOTAL including the final URL line. -Voice rules: -- Open with a specific claim or observation — not a question, not an announcement, not "I'm excited to share" -- 300-500 words -- No em-dashes. No hedging. No buzzwords. -- Sound like someone who has already solved this problem twice and is talking to a peer, not performing on LinkedIn -- End with exactly: "Full post: ${postUrl}" +Structure (1–3 short lines, blank line between): +1. The strongest single sentence from the post — the claim that makes a VP of Engineering stop scrolling because they have lived it. +2. (Optional) One more sentence with the counterintuitive punchline. +3. "Full post: ${postUrl}" — exactly this, nothing else. + +Prefer lifting verbatim sentences from the post over paraphrasing. + +No em-dashes. No hedging. No buzzwords. No "I'm thrilled to share." No call-to-action fluff. The full blog post: --- ${postContent} --- -Write only the LinkedIn post text. No commentary, no alternatives.`, +Write only the LinkedIn text. No commentary, no alternatives. Count characters before responding — if over 280, cut.`, }], }); diff --git a/content/blog/2026-04-25-devops-matters-more-when-ai-writes-code.md b/content/blog/2026-04-25-devops-matters-more-when-ai-writes-code.md index 9f046ce..f44abb5 100644 --- a/content/blog/2026-04-25-devops-matters-more-when-ai-writes-code.md +++ b/content/blog/2026-04-25-devops-matters-more-when-ai-writes-code.md @@ -7,16 +7,6 @@ tags: [] linkedin_copy: | AI code generation made your developers faster. It did not make your deployment pipeline wider. - Every team I have talked to that adopted AI tooling early has the same story. Output is up. Pull requests are up. Merge frequency is up. And incidents are up too. Not because the AI code is bad. Because the pipeline, the regression suite, and the release confidence mechanisms were sized for the old throughput. Nobody resized them. - - This is the part of the AI-in-engineering conversation that keeps getting skipped. The bottleneck moved. It used to be code generation. Now it is deployment reliability. Regression coverage. Rollback speed. The infrastructure that absorbs velocity. - - Regression suites are the sharpest problem. They were built over years by developers who knew where things break. AI-generated code does not share that mental model. It introduces patterns that are correct in isolation and surprising in combination. The existing test suite was not written for this. - - The teams handling this well share a pattern. They treat deployment infrastructure as a first-class investment alongside AI adoption. They use AI to generate test cases, not just production code. They monitor every release automatically and roll back without a human in the loop. - - The KPIs that matter in an AI-accelerated org are not tokens consumed or lines generated. They are deployment success rate, mean time to recovery, change failure rate, and regression pass rate over time. Input metrics tell you the engine runs. Deployment metrics tell you the brakes work. - DevOps is not a supporting function in this world. It is the binding constraint. Full post: {{url}}