---
name: social-post-writer
platforms: [cowork, claude-code]
description: "Plan social media campaigns and draft individual posts for LinkedIn and X (Twitter), including repurposing existing content into platform-native social posts. Use this skill when the user asks to create a social media calendar, plan a LinkedIn content series, write social posts, draft a tweet or X thread, repurpose a blog post for social, turn an article into LinkedIn posts, create a social campaign, or plan social content cadence. Also trigger when they mention social media strategy, content calendar, post series, LinkedIn carousel outline, X thread, hashtag strategy, or ask 'what should we post about [topic]?' For voice and tone guidance, this skill defers to brand-voice-writer. For social posts within an event campaign, use event-brief-planner instead."
references:
  - product-marketing-context
  - brand-voice-guide
---

# Social Post Writer

Plan social media campaigns and draft individual posts for LinkedIn and X. Handles three modes: campaign planning (multi-post calendar with topic mix and cadence), single-post drafting, and content repurposing (turning blog posts, articles, or other content into platform-native social posts). For voice and tone, this skill defers to brand-voice-writer and the brand voice guide.

## When to use this skill

- Planning a social media content calendar or post series
- Drafting individual LinkedIn posts or X posts/threads
- Repurposing a blog post, article, or Tiger Den content item into social posts
- Planning topic cadence and content mix across platforms
- When someone asks "what should we post about [topic]?" or "turn this blog post into social"

## When NOT to use this skill

- Writing social posts as part of an event campaign brief (use event-brief-planner)
- Writing other content types like blog posts or emails (use brand-voice-writer)
- Evaluating post quality (social posts are too short for rubric evaluation)

## Step 0: Pre-flight check

Invoke the `marketing-preflight` skill via the Skill tool, passing this skill's `name:` field value (`social-post-writer`) as the args. Do not proceed until it completes successfully. If it stops with an error, follow its instructions and stop.

If `marketing-preflight` returned a stale-connector footer note, append it verbatim at the end of your final response to the user.

Also fetch the No Fly List before doing any work:

```
get_marketing_reference(slug: "no-fly-list")
```

This is a list of customers who cannot be publicly referenced. Load these names as a hard constraint: **never include any No Fly List customer in any output** — not as named examples, proof points, customer quotes, case study references, or any other mention. If the user requests content featuring or referencing a No Fly List customer, stop and inform them that this customer cannot be publicly referenced. If a No Fly List name appears in source material you are working from, omit it from all outputs.

## Instructions

### 1. Load brand and audience context

This skill requires the Tiger Den MCP server. If Tiger Den tools are not available, tell the user: "This skill needs the Tiger Den MCP server to load brand context and find content. Please connect Tiger Den and try again." Do not proceed without it.

Fetch reference docs before planning or drafting:

- **Always fetch:** `product-marketing-context` and `brand-voice-guide` using `get_marketing_context(slugs: ["product-marketing-context", "brand-voice-guide"])`. This loads audience personas, positioning, terminology, and proof points alongside the brand voice and structural guidance.
- **Read the social section of the brand voice guide.** Find the "Trade Show Assets / Ads / Social Copy" section and internalize its two goals: (1) Inspire, grabbing attention instantly with punchy, direct language, and (2) Drive action, telling the reader exactly what to do next. One main message driving one clear action. The message should be graspable in under five seconds.
- **Scan proof points.** Review the proof points section of product-marketing-context. Note customer performance metrics, compression ratios, migration stories, and pull quotes that are relevant to the topic. Specific numbers (e.g., "6.4s to 30ms" or "95% compression") outperform generic claims in social posts.
- **Freshness check:** After fetching, check the "Last updated" date on product-marketing-context. If it is more than 6 months old, flag it: "The product-marketing-context doc was last updated [date]. Some metrics or proof points may be outdated. Want me to proceed or verify first?"

Voice profiles (a specific person's writing voice) are loaded conditionally in Step 2 based on which accounts the user is posting from. The default is brand voice — a personal voice profile is only loaded when an individual's account is selected.

### 2. Confirm target accounts

Ask which account(s) will post this content. The answer determines platforms, voice, and register — so ask this before anything else and before mode selection. **Do not default — always ask.**

Before asking, call `list_voice_profiles` once to see who has a configured voice profile. Use this list to inform both the options you present and the matching below.

Present as a multi-select question:

- **Tiger Data LinkedIn (company page)** — brand voice, "we" register
- **Tiger Data X (company)** — brand voice, "we" register
- **My personal LinkedIn** — personal voice profile, first-person register
- **My personal X** — personal voice profile, first-person register
- **Another employee's account** — ask whose, and which platform

Multi-select is expected. A single request often spans multiple accounts.

**Resolving voice per selected account:**

- **Company accounts:** use the brand voice already loaded in Step 1. No extra fetch needed.
- **Personal accounts ("my" or a named employee):** match the person against the `list_voice_profiles` results.
  - If an unambiguous match is found, fetch the profile with `get_voice_profile`.
  - If no match, or if the user said "my" and you cannot confidently determine who they are from context (no Asana connector, no session-level user info, etc.), ask directly: "I'm not sure which voice profile is yours — here are the ones we have: [list]. Which should I use?"
  - If the named employee has no voice profile, tell the user: "[Name] doesn't have a voice profile set up. Want to proceed with brand voice and a personal register, or pause so a profile can be created first?"

**Do not assume the Asana MCP or any other connector is available to identify the user.** Asana is only used later in Step 9 (optional Asana submission), and not every user of this skill will have it connected. Voice profile resolution must work without it.

**If scope is getting too complex** (multiple accounts across multiple voices AND multiple platforms in a single request), suggest running the skill in sequence instead of all at once:

> "This is a lot to handle in one pass — the drafts can get muddled when voices and accounts are mixed. Want to start with the Tiger Data company posts, and once those are locked in we'll run through this again for [other account]?"

**Derived from this step (used downstream):**

- **Platforms:** union of platforms across selected accounts. If X is not covered by any selected account, don't draft X posts. Same for LinkedIn.
- **Voice per account:** tracked separately when multiple accounts are selected.
- **Register:** company accounts = "we", polished; personal accounts = first-person, conversational.

### 3. Determine the mode

**First, check if this is actually a long-form LinkedIn article request.** If the user is asking for a 900-1100 word LinkedIn article (not a short social post), this skill is the wrong tool — hand off to the **linkedin-article-writer** skill. That skill handles the full article conversion workflow: voice profile matching, four structured outputs (SEO title, SEO description, 900-1100 word article body, matching social post), and quality checks. It works with both Tiger Den content and raw blog drafts. Tell the user: "Long-form LinkedIn articles have their own dedicated workflow. Let me switch to the LinkedIn article writer." Then invoke `/linkedin-article-writer`. **Stop this skill — do not continue to the modes below.**

Otherwise, ask the user (or infer from their request) which mode they need:

- **Campaign mode:** Planning a series of posts over time (content calendar, topic cadence, multi-post series). Go to Step 4.
- **Single-post mode:** Drafting one post or a small batch on a topic. Go to Step 6.
- **Multi-angle mode:** User has one piece of source content (blog post, article, URL, Tiger Den content item) and wants 3-5 social posts from it, each with a different angle. Go to Step 7.

If ambiguous, ask. A request like "write LinkedIn posts about continuous aggregates" could mean a single post or a planned series. A request like "turn this blog post into some LinkedIn posts" is multi-angle mode.

### 4. Campaign planning: gather the brief

Collect these inputs from the user. Ask for anything not provided. Do not silently assume defaults.

- **Goal:** What outcome does the campaign drive? (awareness, traffic, event registration, product adoption, thought leadership)
- **Duration:** How many weeks? (Suggest 4 weeks if unspecified, but confirm)
- **Post frequency:** How many posts per week per platform? Base suggestions on the platforms actually in scope from Step 2 — suggest 3/week for LinkedIn and 4-5/week for X *only* for the platforms that were selected. Do not suggest cadence for a platform that isn't in scope. Confirm before locking in.
- **Topic pillars:** 2-4 recurring themes. If not provided, propose pillars based on product-marketing-context and confirm.
- **Content mix:** Ratio of post types per week. Default suggestion: ~40% educational/how-to, ~30% proof points and customer stories, ~20% product and feature highlights, ~10% industry commentary and engagement. Confirm with user.
- **Hashtag strategy:** Does the team use standard hashtags? Ask, or propose 3-5 based on the topic pillars.

Platforms, voice, and register are already determined in Step 2 — do not ask about them again.

### 5. Plan the content calendar

Build a week-by-week calendar. For each post, include:

- **Week and day:** Placement in the calendar
- **Account:** Which of the selected accounts will post it (only relevant if more than one was selected in Step 2)
- **Platform / Account:** Which account on which platform (e.g., "Tiger Data LinkedIn", "Personal LinkedIn", "Tiger Data X"). If the same platform appears under multiple accounts, list each as its own row.
- **Topic pillar:** Which theme this post falls under
- **Post type:** Educational, proof point, product highlight, engagement/question, repurposed content, thread (X only)
- **Hook direction:** One sentence describing the opening angle
- **CTA:** What the reader should do (click, comment, share, try something)
- **Source content:** If repurposing, reference the original piece

**Calendar design principles:**
- Alternate topic pillars so the feed does not feel repetitive
- Front-load the week with higher-value posts (Tuesday through Thursday performs best on LinkedIn)
- Plan at least one engagement post per week (question, poll, or hot take) to drive comments
- If multiple platforms are selected, do not post identical content across platforms. If multiple accounts on the same platform are selected (e.g., Tiger Data LinkedIn + a personal LinkedIn), also do not post identical content — adapt the angle, voice, and framing for each account/platform combination. A feed that looks like copy-paste across accounts is worse than fewer posts.
- For X, plan threads (3-5 posts) for topics that need more depth. Budget one thread per week maximum.

Use `search_content` to find existing Tiger Data content for each topic pillar to populate the "Source content" field. Apply an 18-month freshness filter using `published_after`. If no recent content exists for a topic, note the gap.

Present the calendar as a table grouped by week, then offer to adjust before drafting any posts.

### 6. Draft individual posts

**Before drafting (single-post mode only):** Gather these inputs if they aren't already clear from the user's request. Ask for anything missing — don't silently guess:

- **Topic or angle** — what is this post about, specifically?
- **Link to include?** — if yes, what URL (this becomes a `[LINK: ...]` placeholder resolved in Step 8.5)
- **Hook direction** — how should it open? Any specific framing the user has in mind?
- **CTA** — what should the reader do (click, comment, share, try something)?
- **Number of posts** — one, or a small batch? If a batch, confirm topics for each.

This brief-gathering only applies to single-post mode. Campaign mode uses inputs from Steps 4 and 5; multi-angle mode uses Step 7's source content directly and only references this step for the formatting guidance below.

For each post (whether from the calendar, a standalone single-post request, or a multi-angle batch), produce platform- and account-specific copy.

**LinkedIn posts:**
- **Length:** 150-300 words for thought-leadership posts. 50-100 words for quick announcements or shares.
- **Structure:** Hook (first 1-2 lines visible before "see more"), body (the substance), CTA (what to do next). The hook must earn the click to expand.
- **Formatting:** Short paragraphs (1-3 sentences). Line breaks between paragraphs for readability in the feed. Sparing use of bold for one key phrase maximum.
- **Hashtags:** 3-5 relevant hashtags at the end of the post, not inline.
- **Carousel outlines:** If the post is a carousel (slide-by-slide breakdown), provide a numbered slide outline with the headline and key point per slide. The skill does not generate carousel images, only the text outline.

**X posts:**
- **Length:** Under 280 characters for single posts. Threads: 3-8 posts, each under 280 characters.
- **Structure (single):** One clear thought per post. No filler. End with a CTA or a question when appropriate.
- **Structure (thread):** Post 1 is the hook (must stand alone and earn the click to expand). Subsequent posts build the argument. Final post has the CTA. Number threads as "1/" or use natural transitions.
- **Tone:** More conversational and direct than LinkedIn. Write as native X content, not compressed LinkedIn posts.
- **Hashtags:** 1-2 maximum. Hashtags on X feel spammy when overused.
- **Character enforcement:** After drafting each X post, count the characters. If over 280, rewrite to fit. If the message cannot be compressed to 280 characters without losing substance, recommend converting to a thread and draft it as one.

**Both platforms:**
- Lead with the problem or insight, not with the product
- One message per post. If the post tries to say two things, split it into two posts.
- Include a link only when there is a genuine destination. Not every post needs a URL.
- When a URL needs to be included, insert a placeholder `[LINK: <brief description>]` in the post copy (e.g., `[LINK: blog post]`). Do not generate UTM links or shortlinks during drafting — all links are confirmed and shortened in Step 8.5.
- Use proof points from product-marketing-context where relevant: customer performance metrics, compression ratios, migration stories, pull quotes. Specific numbers outperform generic claims.
- Match the voice and register set in Step 2. Company-account posts: "we," polished. Personal-account posts: first-person, more conversational, informed by the loaded voice profile.

**Multiple accounts:**

If more than one account was selected in Step 2, produce a separate draft per account — not just per platform. Two LinkedIn posts (one for Tiger Data's company page and one for a personal profile) should read as genuinely different posts: different voice, different register, often a different angle. Do not draft one version and lightly edit it into the other — that defeats the point of posting from multiple accounts.

### 7. Multi-angle from source content

When the user provides source content and wants multiple social posts generated from it:

1. **Fetch the source material.** Resolve the source in this order:
   - **Tiger Den content ID provided:** fetch with `get_content_text`.
   - **Tiger Data URL provided (e.g., a tigerdata.com blog post):** call `search_content` first with terms from the URL or topic to see if the content is indexed in Tiger Den. It almost always is for Tiger Data blog posts and case studies. If found, fetch with `get_content_text`.
   - **External URL or Tiger Den returns no match:** WebFetch the URL to retrieve the content directly.
   - **Pasted text:** work from the pasted content.
   - **Topic mentioned but no source provided:** use `search_content` with an 18-month `published_after` filter to find recent Tiger Data content on the topic. Present 3-5 options and ask the user to pick.

   Once the source is loaded, identify the core insight, key data points, memorable quotes, and the target audience.
2. **Extract 3-5 post angles.** Each angle is a different entry point into the same material. Not every post should summarize the article. Good angles: a surprising data point, a contrarian take from the piece, a "how to" distilled from a tutorial, a question the article answers, a quote worth highlighting.
3. **Draft posts per angle.** For each angle, draft platform-specific posts following the formatting guidance in Step 6. If multiple accounts or both platforms are selected, produce a separate draft per account/platform combination as described in Step 6.
4. **Link back to the source.** In at least one post per angle, insert a `[LINK: source article]` placeholder where the link should go. Other posts in the batch can stand alone without a link. All placeholders are resolved into shortlinks in Step 8.5.

**Angle patterns by source type:**
- **Blog post or article:** Extract the thesis as a LinkedIn hook. Pull a surprising stat for X. Turn a how-to section into a thread.
- **Case study or customer story:** Lead with the outcome. Use the customer's challenge as the hook.
- **Product announcement:** Lead with the user problem it solves, not the feature name.
- **Tiger Den content item:** Fetch with `get_content_text` and treat like any other source.

### 8. Brand voice cross-check

After drafting, review all output against the brand voice guide:

1. **No em dashes.** Replace every em dash with a comma, period, colon, or separate sentence.
2. **Lead with problems, not features.** Posts should open with the audience's pain or curiosity, not product names.
3. **Terminology.** Product names and technical terms must match the glossary in product-marketing-context.
4. **Platform-appropriate tone.** LinkedIn can be more polished and narrative. X should be more direct and conversational. Neither should sound like ad copy.
5. **Character limits.** Re-verify X posts are under 280 characters. This should have been enforced during drafting (Step 6). If any X posts are still over 280, rewrite them now.
6. **No AI slop.** Scan for patterns de-slop catches: forced triples, sycophantic openers, vocabulary clusters, hallmark-card endings.
7. **Voice profile match (personal accounts only).** For any post drafted against a loaded voice profile from Step 2, verify the draft actually reads like that person — not just like generic brand copy wearing their name. Check: sentence rhythm, typical sentence length, characteristic phrases or openers, how they usually end posts. If the profile includes writing samples, compare directly. A draft can pass rules 1-6 and still fail here — if it sounds like Tiger Data marketing written under a personal byline, rewrite until it sounds like the actual person. The whole reason we loaded the profile is to sound like them, not just to caveat the register.

Fix issues inline. If no issues are found, state "No voice issues found."

### 8.5. UTM confirmation and shortlink generation

Before presenting final output, resolve all link placeholders into confirmed shortlinks.

1. **Collect all placeholders.** Scan all drafted posts for `[LINK: ...]` placeholders. If no posts contain any links, skip this step.

2. **Propose UTM parameters.** For each placeholder, present a confirmation table:

   | Post | Platform | URL | Source | Medium | Campaign |
   |------|----------|-----|--------|--------|----------|
   | LinkedIn post 1 | LinkedIn | https://... | `linkedin` | `social` | `suggested-slug` |
   | X post 1 | X | https://... | `twitter` | `social` | `suggested-slug` |

   - `source` and `medium` are fixed — `linkedin` or `twitter` based on platform, `social` for medium. Do not offer to change these.
   - For `campaign`: default to `developer-awareness`. If the same URL appears in both a LinkedIn and X post, list them as separate rows with their respective `source` values.
   - If you cannot determine the destination URL from context (e.g., the user said "include a link to the blog post" but didn't provide a URL), ask for it now before proceeding.

3. **Get user confirmation.** Ask: "I'll use `developer-awareness` as the campaign slug — want to use something different?"

4. **Create shortlinks.** For each confirmed row, run the two-step `manage_tracked_links` flow:

   **Step 4a — create the tracked link.** Call `manage_tracked_links` with `action: "create"`:
   - `description`: a human-readable label (e.g., `"Row Deletes Retention — LinkedIn"`)
   - `original_url`: the destination URL
   - `utm_source`: `linkedin` or `twitter`
   - `utm_medium`: `social`
   - `utm_campaign`: the confirmed campaign slug

   The response includes `id` (use it in step 4b) and `tagged_url` (the fully-assembled UTM URL — keep it as a fallback in case 4b fails).

   **Step 4b — attach the Bl.ink shortlink.** Call `manage_tracked_links` with `action: "attach_shortlink"`:
   - `id`: the `id` returned from 4a
   - `name`: the same human-readable label used as `description` in 4a
   - `custom_slug`: 1-2 words derived from the content title, lowercased and hyphenated, with `-li` appended for LinkedIn or `-x` for X (e.g., `row-retention-li`, `row-retention-x`). Derive the words from the most distinctive part of the title — not generic words like "blog" or "post".

   The response includes `short_url` (e.g., `https://tsdb.co/<slug>`) — this is what replaces the `[LINK: ...]` placeholder.

   **Error handling.** If step 4a or 4b returns an error, surface it clearly and pick the right message:
   - **Permission error on 4a** ("not in the tracked-links-contributor group" or similar): "Tracked link creation failed — your Tiger Den account needs the `tracked-links-contributor` access tier to persist links. Falling back to UTM-tagged URLs without persistence. Here they are: [list]." For each placeholder, call `generate_utm_link(url: <original_url>, source: <utm_source>, medium: <utm_medium>, campaign: <utm_campaign>)` and use the returned URL. `generate_utm_link` is read-only and doesn't require the contributor tier — it just won't create a tracked_link record, so click attribution won't roll up. Surface that loss to the user.
   - **Preset rejection on 4a** (`BAD_REQUEST` mentioning "not in the approved presets"): unlikely for hardcoded `linkedin` / `twitter` / `social`, but if it happens, call `list_utm_presets` and pick a matching value before retrying.
   - **4a succeeded but 4b failed** (Bl.ink resource creation issue): use the `tagged_url` from the 4a response as the link — it's already UTM-tagged and the row will still persist for downstream attribution. Tell the user: "Shortlink minting failed for [post] — using the UTM-tagged URL directly. The tracked link record is saved in Tiger Den."

   Do not drop bare URLs into post copy without flagging this to the user.

5. **Swap placeholders.** Replace every `[LINK: ...]` placeholder in the post copy with its corresponding `short_url` (or `tagged_url` fallback if step 4b failed).

### 9. Optional: Submit Social Promotion Request to Asana

**This step is for Tiger Data company accounts only** (Tiger Data LinkedIn company page, Tiger Data X). The Social Promotion Request flow routes posts to the social media team to publish — personal-account posts are published by the account owner directly and never go through this flow.

Before offering this step, check Step 2's account selections:

- **No Tiger Data company account was selected:** skip this step entirely. Do not offer Asana submission. Personal-account posts are the user's to publish directly — tell them the drafts are ready to copy and paste into their account.
- **Mix of company and personal accounts:** only the company-account posts get submitted to Asana. Before creating the card, tell the user: "I'll submit the Tiger Data company posts to Asana. The personal-account drafts above are yours to post directly." Do not include personal-account drafts in the Asana card.
- **Only company accounts:** proceed normally.

After confirming at least one company-account post exists and drafts are finalized with shortlinks in place, ask:

> "Want me to submit these as a Social Promotion Request in Asana?"

If the user says no, skip this step entirely. If yes, work through these sub-steps:

**9a. Pre-fetch (silent)**

Before showing anything to the user: read `CONFIG.md` from the plugin root to get project and section GIDs, and call `get_me` from the Asana MCP to retrieve the current user's name and email.

**9b. One-shot confirmation**

Auto-derive a suggested title from the content (e.g., the blog post title, campaign topic, or subject of the posts). Then present all fields at once with smart defaults pre-filled:

> Here's what I'll submit — change anything before I create it:
>
> | Field | Value |
> |-------|-------|
> | Title | `Schedule social post — [auto-derived topic title]` |
> | Publish date | Whenever |
> | Urgency | Medium |
> | Image | I'll attach to the card myself |

The user can reply with a correction to any field (e.g., "publish date: May 15", "urgency: high", "create a design request for the image") or just say "looks good" to proceed. **Do not ask follow-up questions for each field — handle all adjustments from this single reply.**

Three image options require additional steps before proceeding to 9e:

- **"Create a design request for me"** — run the inline creation flow (9c) first, then proceed to 9e.
- **"Provide an image URL"** — ask for the URL, wait for the response, then proceed to 9e.
- **"Link an existing design request"** — search Asana for design request tasks matching the topic title, present up to 5 matches, wait for the user to pick one, then proceed to 9e.

**Urgency options** (for reference when the user adjusts):
- **Low** — flexible, no rush (2+ weeks out)
- **Medium** — normal turnaround (1–2 weeks out)
- **High** — needed within the week
- **ASAP / Rush** — needed in 1–3 days

**Image options** (for reference when the user adjusts):
- **I'll attach the image to the Asana card myself** *(default)* — surface thumbnail builder and card links in 9e
- **Provide an image URL** — ask for the URL before proceeding to 9e
- **Link an existing design request** — search Asana by topic title, present up to 5 matches, wait for selection before proceeding to 9e
- **Create a design request for me** — run the inline creation flow (9c) first, then proceed to 9e
- **No image needed** — only when the post genuinely works better without one

**9c. Inline design request creation (only when requested):**

1. Generate a short conceptual image brief based on the post content — aim for one or two sentences describing the visual idea at a high level (e.g., "A developer at a terminal, looking relieved as a slow query suddenly returns in milliseconds" — not a color or spec prescription). Present it to the user: "Here's the brief I'd send to the design team — does this look right?" Wait for confirmation or edits.

2. Determine due date: publish date minus 3 business days. If publish date is within 3 business days or is "whenever", use today and flag it as a rush.

3. Create the design request task using `create_task`:
   - `name`: `Social Post Image - [Topic Title] ([Platform(s)])`  — e.g. `Social Post Image - Query Performance Deep Dive (LinkedIn)` or `Social Post Image - Query Performance Deep Dive (LinkedIn, X)`
   - `project_id`: Marketing Design Requests GID from CONFIG.md
   - `section_id`: Requests section GID from CONFIG.md
   - `due_on`: calculated due date (YYYY-MM-DD)
   - `custom_fields`: set Type field to the `Ads/Social` GID from CONFIG.md
   - `html_notes`:

     ```html
     <body>
     <strong>Request title:</strong>
     Social Post Image - [Topic Title] ([Platform(s)])

     <strong>Name:</strong>
     [User name from get_me]

     <strong>Email address:</strong>
     <a href="mailto:[email]">[email]</a>

     <strong>Due date:</strong>
     [Due date in "Mon DD, YYYY" format]

     <strong>Level of urgency:</strong>
     [Urgency from confirmation table]

     <strong>Request type:</strong>
     Social media post image

     <strong>Platform(s):</strong>
     [Comma-separated list of platforms this image is for, e.g. "LinkedIn" or "LinkedIn, X"]

     <strong>Project description and specs:</strong>
     [Confirmed image brief]

     ———————————————
     This task was submitted through <strong>Marketing Design Requests</strong>
     <a href="[FORM_URL from CONFIG.md]">[FORM_URL]</a>
     </body>
     ```

4. Store the design request `permalink_url` from the created task — it gets linked in the Social Promotion Request description.

**9d. Create the Social Promotion Request task**

Use `create_task` with:

- `name`: `Schedule social post — [TOPIC TITLE]`
- `project_id`: Social Promotion Requests GID from CONFIG.md
- `due_on`: publish date if given; omit if "whenever"
- `html_notes`:

  ```html
  <body>
  <strong>Name:</strong>
  [User name from get_me]

  <strong>Email address:</strong>
  <a href="mailto:[email]">[email]</a>

  <strong>Ideal publish date:</strong>
  [Date in "Mon DD, YYYY" format, or "Whenever"]

  <strong>Urgency:</strong>
  [Urgency from confirmation table]

  <strong>Image:</strong>
  [One of: image URL / "Design request: <a href=\"[permalink]\">[permalink]</a>" / "No image" / "I'll attach to the card myself"]

  <strong>Additional details:</strong>
  (none)

  <strong>Copy for each social post:</strong>

  --- LinkedIn ---
  [Full LinkedIn post copy including hashtags and shortlinks]

  --- X ---
  [Full X post copy including shortlinks]
  </body>
  ```

Only include platform sections for platforms that were selected in Step 2. If only LinkedIn was in scope, omit the `--- X ---` section entirely (and vice versa). For each platform in scope, include exactly one post — if multiple angles or drafts were produced, ask the user which one they want submitted before creating the task.

**9e. Summary**

After the task is created, tell the user:

- Link to the Social Promotion Request task
- Link to the design request task (if one was created in 9c)
- Scheduled date, or "no due date set" if "whenever"

If the image option was **"I'll attach to the card myself"** (the default), also include:

> Need a quick image? You can build one at the [Tiger Data thumbnail builder](https://den.tigerdata.com/assets/thumbnail-builder), then attach it directly to [the Social Promotion Request task]([task permalink]).

## Tiger Den tools used

This skill requires Tiger Den. Here is how it uses specific tools:

- **`get_marketing_context`** -- fetch product-marketing-context and brand-voice-guide (Step 1)
- **`search_content`** -- find existing content for repurposing or linking. Always use `published_after` with an 18-month window. (Steps 5 and 7)
- **`get_content_text`** -- read full content items for repurposing (Step 7)
- **`build_linkedin_prompt`** -- not used directly by this skill. For long-form LinkedIn articles, hand off to **linkedin-article-writer** which manages the full workflow including `build_linkedin_prompt`
- **`list_voice_profiles` / `get_voice_profile`** -- used in Step 2 to resolve voice per selected account. `list_voice_profiles` is always called once at the start of Step 2; `get_voice_profile` is called only for personal/employee accounts after a profile match is confirmed. Voice profiles take precedence for sentence rhythm and personality; the brand voice guide still governs terminology and absolute rules.
- **`manage_tracked_links`** -- two-step shortlink creation in Step 8.5. First call `action: "create"` with `description`, `original_url`, `utm_source`, `utm_medium`, `utm_campaign` to persist the parent tracked link (response includes `tagged_url` as a fallback). Then call `action: "attach_shortlink"` with the returned `id`, plus `name` and `custom_slug`, to mint the Bl.ink shortlink. The resulting `short_url` replaces the `[LINK: ...]` placeholder in post copy. Requires the `tracked-links-contributor` access tier in Tiger Den. `utm_source` and `utm_medium` are validated against `list_utm_presets` server-side.

## Output format

Present everything directly in chat as structured Markdown. Do not create files.

**Campaign mode:**
1. Campaign overview (goal, accounts, platforms, duration, frequency, topic pillars, content mix)
2. Content calendar (week-by-week table)
3. Voice check results (from Step 8)
4. Next steps

**Single-post and multi-angle mode:**
- Each post as a labeled section: account, platform, post copy, hashtags (if any), CTA, link (if any)
- For threads: numbered posts in sequence
- For multi-angle batches: grouped by angle, with the source content noted
- If multiple accounts were selected, group output by account and label each section clearly
- Links appear as `[LINK: ...]` placeholders until Step 8.5 resolves them into shortlinks

Include this note in Next Steps: *"To edit any post, tell me what to change or paste a revised version directly."*

## Hand-off

After the plan or drafts are complete (and after Step 9 if the user ran Asana submission), offer to:
- Refine individual posts with brand-voice-writer for deeper voice alignment
- Run de-slop if any posts read as AI-generated
- Plan an email nurture sequence to complement the social campaign (using email-nurture-planner)
- Adjust the calendar or posts based on feedback

Do not auto-trigger other skills. Wait for the user to confirm the output looks good first.
