Goal
Create one post in the user's Brand Voice (or Founder Voice), optionally using a template, and route it safely through the V2 state machine.
Voice Profile Modes
Brand Voice
- Company/brand speaking
- Focus on tone, style rules, vocabulary
- Professional and consistent across content
Founder Voice (Advanced)
- Founder speaking personally
- Includes founder_signals: beliefs, lessons, contrarian opinions, scars, backstory moments
- More authentic, personal, thought-leadership focused
- founder_signals are injected as constraints in content generation
Which Agent Types Use This
- content_creator — Primary use case (generates posts as part of jobs)
- custom — User-defined agents with content creation enabled
Hard Rules
- Always call
bolta.get_workspace_policy + bolta.get_my_capabilities first.
- Safe Mode enforcement (workspace-level):
- If Safe Mode ON: ALL content goes to Inbox for approval, regardless of role
- If Safe Mode OFF: Creator/Viewer still route to Inbox; Editor/Admin can schedule directly
- If actor role does not include the required capability for an action (schedule/publish), MUST NOT attempt it.
- If
requested_action is omitted: default to send_to_inbox (if Safe Mode ON or role is Creator/Viewer), otherwise draft_only.
- Never publish directly without explicit approval.
- Never schedule unless capability includes
posts:schedule.
How Voice Profiles Constrain Generation
Tone Constraints (all modes)
Content generation respects tone scores (playful, professional, direct, thoughtful):
- Tone scores guide sentence structure, vocabulary choice, emoji usage
- Direct tone (9/10) = fewer hedges, more imperatives
- Thoughtful tone (7/10) = more context, nuance, depth
Style Rules (all modes)
dos: Patterns to follow (lead with pain points, use short sentences)
donts: Patterns to avoid (no corporate jargon, avoid hedging)
styleKeywords: Vocabulary bias (emphasize direct, confident, specific)
Founder Signals (founder mode only)
When speakerMode: "founder" and founderSignals provided:
- Beliefs: Constraints that shape main arguments
- Example: If belief is "Ship fast beats planning," posts favor speed over perfection
- Lessons: Constraints that shape advice given
- Example: If lesson is "Users teach more than docs," content leads with user validation
- Contrarian Opinions: Constraints that enable pushback
- Example: If contrarian is "Engagement metrics are vanity," posts optimize for substance over reach
- Scars: Constraints that enable vulnerability
- Example: If scar is "Built feature no one asked for," posts emphasize user research
- Backstory Moments: Constraints that enable narrative coherence
- Example: If backstory is "Spent years ghostwriting," posts demonstrate writing from real experience
Founder Signal Injection Example:
Prompt: "Write about validating product ideas"
Voice Profile:
- speakerMode: "founder"
- beliefs: ["Ship fast", "Users teach more than docs"]
- lesson: "Build what users ask for"
- scar: "Built feature no one wanted"
Generated Content Characteristics:
- Opens with user validation (belief: users teach)
- Mentions framework for speed (belief: ship fast)
- Includes personal example of failure (scar: built wrong feature)
- Gives specific, actionable advice (lesson learned)
- Tone: Direct + thoughtful (8/10 and 7/10)
Generated: "Most founders waste months on features no one asked for—here's my 3-question filter..."
(This naturally demonstrates the beliefs/lessons/scars without being forced)
Steps
1. Check policy & capabilities
bolta.get_workspace_policy(workspace_id) → extract safe_mode (boolean)
bolta.get_my_capabilities(workspace_id) → check role capabilities
2. Load context for consistency
bolta.get_voice_profile(voice_profile_id) → tone, style rules, banned phrases
- If founder mode: Extract
founder_signals for generation constraints
bolta.list_recent_posts(account_ids, limit=5) → avoid repetition, maintain consistency
- If
agent_id provided: bolta.recall(agent_id, "content_preferences") → retrieve agent memory
3. Generate content
- If template_id provided:
bolta.list_templates(workspace_id) (if needed for validation)
bolta.render_template(template_id, {prompt, voice_profile_id, context})
- Use rendered text as the post body
- Else:
- Generate body using voice profile constraints:
- Tone scores (all modes)
- Style rules (all modes)
- Founder signals (if founder mode)
- Custom rules and keywords
- Check recent posts to avoid repetition
4. Create the draft
bolta.draft_post({workspace_id, voice_profile_id, account_ids, content: body, status: "draft"})
- Returns
post_id
5. Route based on governance
6. Store learnings (if agent context)
- If successful and
agent_id provided:
bolta.remember(agent_id, "last_successful_hook_style", hook_type_used)
- Update agent memory with what worked
Output
Return:
{
"post_id": "uuid",
"final_state": "inbox",
"inbox_item_id": "uuid",
"notes_for_reviewer": "AI draft ready for review",
"warnings": []
}
Failure Handling
- If any tool call returns unauthorized/forbidden: downgrade to
inbox (if possible) or leave in draft.
- Never retry publish/schedule more than once.
- On failure, create inbox item with error context for human review.
- Log to Run record if executed as part of a Job.
V2 Agent Context
When agents use this skill:
Content Creator reasoning:
"I need to draft a post about our new feature. First, let me check the voice profile to match tone. Then I'll review recent posts to avoid repetition. I see we posted about pricing yesterday, so I'll focus on product benefits instead."
Key differences from V1:
- V1: Template fill → post
- V2: Agent reasons about context → chooses tools → drafts content → learns from feedback
Example execution trace:
Turn 1: get_voice_profile() → "Direct, specific, no jargon"
Turn 2: list_recent_posts() → 2 about pricing (avoid)
Turn 3: recall() → "Educational > promotional 3:1"
Turn 4: draft_post() → Created with educational angle
Turn 5: remember() → Store "educational_format_used"
Example Usage
Scenario 1: Job Execution (Safe Mode ON)
{
"workspace_id": "uuid",
"agent_id": "uuid",
"job_id": "uuid",
"voice_profile_id": "uuid",
"account_ids": ["twitter-uuid"],
"prompt": "Write a post about our new feature launch",
"requested_action": "send_to_inbox"
}
Result: Post created → routed to Inbox → awaits approval → then scheduled/published
Scenario 2: Manual Draft (Safe Mode OFF, Editor role)
{
"workspace_id": "uuid",
"voice_profile_id": "uuid",
"account_ids": ["linkedin-uuid"],
"prompt": "Share our hiring announcement",
"requested_action": "schedule",
"suggested_time": "2026-02-21T09:00:00Z"
}
Result: Post created → immediately scheduled for 9am tomorrow (bypasses inbox)
1---2name: bolta-draft-post-23description: Create a single draft post using a workspace voice profile and optional template. Routes to Inbox or schedules based on workspace policy and actor role.4---56## Goal7Create one post in the user's Brand Voice (or Founder Voice), optionally using a template, and route it safely through the V2 state machine.89## Voice Profile Modes1011### Brand Voice12- Company/brand speaking13- Focus on tone, style rules, vocabulary14- Professional and consistent across content1516### Founder Voice (Advanced)17- Founder speaking personally18- Includes founder_signals: beliefs, lessons, contrarian opinions, scars, backstory moments19- More authentic, personal, thought-leadership focused20- founder_signals are injected as constraints in content generation2122## Which Agent Types Use This23- **content_creator** — Primary use case (generates posts as part of jobs)24- **custom** — User-defined agents with content creation enabled2526## Hard Rules271. Always call `bolta.get_workspace_policy` + `bolta.get_my_capabilities` first.282. **Safe Mode enforcement (workspace-level):**29 - If Safe Mode ON: ALL content goes to Inbox for approval, regardless of role30 - If Safe Mode OFF: Creator/Viewer still route to Inbox; Editor/Admin can schedule directly313. If actor role does not include the required capability for an action (schedule/publish), MUST NOT attempt it.324. If `requested_action` is omitted: default to `send_to_inbox` (if Safe Mode ON or role is Creator/Viewer), otherwise `draft_only`.335. Never publish directly without explicit approval.346. Never schedule unless capability includes `posts:schedule`.3536## How Voice Profiles Constrain Generation3738### Tone Constraints (all modes)39Content generation respects tone scores (playful, professional, direct, thoughtful):40- Tone scores guide sentence structure, vocabulary choice, emoji usage41- Direct tone (9/10) = fewer hedges, more imperatives42- Thoughtful tone (7/10) = more context, nuance, depth4344### Style Rules (all modes)45- `dos`: Patterns to follow (lead with pain points, use short sentences)46- `donts`: Patterns to avoid (no corporate jargon, avoid hedging)47- `styleKeywords`: Vocabulary bias (emphasize direct, confident, specific)4849### Founder Signals (founder mode only)50When `speakerMode: "founder"` and `founderSignals` provided:51- **Beliefs**: Constraints that shape main arguments52 - Example: If belief is "Ship fast beats planning," posts favor speed over perfection53- **Lessons**: Constraints that shape advice given54 - Example: If lesson is "Users teach more than docs," content leads with user validation55- **Contrarian Opinions**: Constraints that enable pushback56 - Example: If contrarian is "Engagement metrics are vanity," posts optimize for substance over reach57- **Scars**: Constraints that enable vulnerability58 - Example: If scar is "Built feature no one asked for," posts emphasize user research59- **Backstory Moments**: Constraints that enable narrative coherence60 - Example: If backstory is "Spent years ghostwriting," posts demonstrate writing from real experience6162**Founder Signal Injection Example:**63```64Prompt: "Write about validating product ideas"65Voice Profile:66 - speakerMode: "founder"67 - beliefs: ["Ship fast", "Users teach more than docs"]68 - lesson: "Build what users ask for"69 - scar: "Built feature no one wanted"7071Generated Content Characteristics:72- Opens with user validation (belief: users teach)73- Mentions framework for speed (belief: ship fast)74- Includes personal example of failure (scar: built wrong feature)75- Gives specific, actionable advice (lesson learned)76- Tone: Direct + thoughtful (8/10 and 7/10)7778Generated: "Most founders waste months on features no one asked for—here's my 3-question filter..."79(This naturally demonstrates the beliefs/lessons/scars without being forced)80```8182## Steps8384### 1. Check policy & capabilities85- `bolta.get_workspace_policy(workspace_id)` → extract `safe_mode` (boolean)86- `bolta.get_my_capabilities(workspace_id)` → check role capabilities8788### 2. Load context for consistency89- `bolta.get_voice_profile(voice_profile_id)` → tone, style rules, banned phrases90 - If founder mode: Extract `founder_signals` for generation constraints91- `bolta.list_recent_posts(account_ids, limit=5)` → avoid repetition, maintain consistency92- If `agent_id` provided: `bolta.recall(agent_id, "content_preferences")` → retrieve agent memory9394### 3. Generate content95- **If template_id provided:**96 - `bolta.list_templates(workspace_id)` (if needed for validation)97 - `bolta.render_template(template_id, {prompt, voice_profile_id, context})`98 - Use rendered text as the post body99- **Else:**100 - Generate body using voice profile constraints:101 - Tone scores (all modes)102 - Style rules (all modes)103 - Founder signals (if founder mode)104 - Custom rules and keywords105 - Check recent posts to avoid repetition106107### 4. Create the draft108- `bolta.draft_post({workspace_id, voice_profile_id, account_ids, content: body, status: "draft"})`109- Returns `post_id`110111### 5. Route based on governance112- **If Safe Mode ON OR role is Creator/Viewer:**113 - Route to Inbox: post transitions to `inbox` state114 - `inbox_item_id` created automatically by system115 - `final_state = inbox`116117- **If Safe Mode OFF AND role is Editor/Admin:**118 - `requested_action == draft_only` → leave in `draft`119 - `requested_action == send_to_inbox` → route to `inbox`120 - `requested_action == schedule` → `bolta.schedule_post(post_id, suggested_time)` → `final_state = scheduled`121 - `requested_action == publish` → `bolta.publish_post(post_id)` → `final_state = published`122123### 6. Store learnings (if agent context)124- If successful and `agent_id` provided:125 - `bolta.remember(agent_id, "last_successful_hook_style", hook_type_used)`126 - Update agent memory with what worked127128## Output129Return:130```json131{132 "post_id": "uuid",133 "final_state": "inbox",134 "inbox_item_id": "uuid",135 "notes_for_reviewer": "AI draft ready for review",136 "warnings": []137}138```139140## Failure Handling141- If any tool call returns unauthorized/forbidden: downgrade to `inbox` (if possible) or leave in `draft`.142- Never retry publish/schedule more than once.143- On failure, create inbox item with error context for human review.144- Log to Run record if executed as part of a Job.145146## V2 Agent Context147148**When agents use this skill:**149150**Content Creator reasoning:**151> "I need to draft a post about our new feature. First, let me check the voice profile to match tone. Then I'll review recent posts to avoid repetition. I see we posted about pricing yesterday, so I'll focus on product benefits instead."152153**Key differences from V1:**154- V1: Template fill → post155- V2: Agent reasons about context → chooses tools → drafts content → learns from feedback156157**Example execution trace:**158```159Turn 1: get_voice_profile() → "Direct, specific, no jargon"160Turn 2: list_recent_posts() → 2 about pricing (avoid)161Turn 3: recall() → "Educational > promotional 3:1"162Turn 4: draft_post() → Created with educational angle163Turn 5: remember() → Store "educational_format_used"164```165166## Example Usage167168### Scenario 1: Job Execution (Safe Mode ON)169```json170{171 "workspace_id": "uuid",172 "agent_id": "uuid",173 "job_id": "uuid",174 "voice_profile_id": "uuid",175 "account_ids": ["twitter-uuid"],176 "prompt": "Write a post about our new feature launch",177 "requested_action": "send_to_inbox"178}179```180**Result:** Post created → routed to Inbox → awaits approval → then scheduled/published181182### Scenario 2: Manual Draft (Safe Mode OFF, Editor role)183```json184{185 "workspace_id": "uuid",186 "voice_profile_id": "uuid",187 "account_ids": ["linkedin-uuid"],188 "prompt": "Share our hiring announcement",189 "requested_action": "schedule",190 "suggested_time": "2026-02-21T09:00:00Z"191}192```193**Result:** Post created → immediately scheduled for 9am tomorrow (bypasses inbox)