Goal
Make the inbox manageable: cluster related content, flag quality/risk issues, propose specific actions, and optionally create improved variants.
V2 Changes
- Reviewer agent context — this is the primary skill for
reviewer agent type
- State machine updated —
inbox (replaces "pending_review"), approved, scheduled, published
- Agent memory integration — recalls review patterns, common issues, voice alignment rules
- Client tag filtering — agencies can triage by client
- @mention context — if called via @mention on inbox page, scopes to visible items
When This Skill Is Called
- Manual trigger — User clicks "Triage Inbox" button in Bolta web
- Scheduled job — Reviewer agent runs daily/weekly triage
- @mention — User @mentions reviewer agent: "@QABot review the inbox"
- Event trigger — When inbox count > threshold (future enhancement)
Policy Rules
- Viewers can only produce a read-only report (no updates, no variants, no comments)
- Creators can create variants and add comments but cannot approve/schedule/publish
- Editor/Admin can add comments and create variants (approval is separate skill)
- Never approve or schedule posts — this skill is purely advisory (use
bolta.review.approve_and_route for that)
Steps
Check policy & capabilities:
bolta.get_workspace_policy(workspace_id) → extract safe_mode (informational)
bolta.get_my_capabilities(workspace_id) → verify what agent can do
- If role is Viewer:
create_variants = false (force read-only)
Load agent memory for context:
- If
agent_id provided:
bolta.recall(agent_id, "common_quality_issues") → prioritize known problems
bolta.recall(agent_id, "voice_alignment_rules") → check consistency
bolta.recall(agent_id, "approval_patterns") → learn what gets approved
bolta.recall(agent_id, "rejection_patterns") → learn what gets rejected
Fetch inbox items:
bolta.list_inbox_items({workspace_id, status: status_filter, limit})
- If
client_tag provided: filter results by client_tag (agency feature)
- For each item, also fetch full details:
bolta.get_inbox_item(inbox_item_id) → post content, metadata, creator agent, etc.
Cluster items by similarity:
Group by:
- Topic similarity — same product/feature/theme
- CTA type — engagement (like/comment), conversion (click link), educational (no CTA)
- Format — thread starter, single post, carousel, poll
- Creator agent — group by which agent created them (for pattern detection)
- Client tag — agency users see clusters per client
Output clusters as:
{
"cluster_id": "topic-product-launch",
"label": "Product Launch Posts",
"item_count": 5,
"inbox_item_ids": ["uuid1", "uuid2", ...],
"common_theme": "New feature announcement"
}
Flag risks and quality issues:
For each inbox item, check against voice profile + brand rules:
Risk categories:
- Tone mismatch — doesn't match voice profile tone (check against
bolta.get_voice_profile)
- Overly salesy — too promotional, not enough value (check CTA density)
- Unverified claims — mentions stats/numbers without source
- Too long — exceeds platform best practices (>280 chars for Twitter, >3000 for LinkedIn)
- Unclear CTA — has CTA but it's vague or weak
- No CTA — missing CTA when one is expected (based on post goal)
- Banned phrases — uses words from voice profile banned list
- Repetition — very similar to recently published post
- Platform mismatch — content doesn't fit platform norms (thread on Instagram, carousel on Twitter, etc.)
Risk severity: low | medium | high
Output risk flags as:
{
"inbox_item_id": "uuid",
"risks": [
{
"category": "tone_mismatch",
"severity": "medium",
"detail": "Post feels corporate; voice profile specifies 'conversational and punchy'"
},
{
"category": "overly_salesy",
"severity": "high",
"detail": "3 CTAs in 280 characters — too aggressive"
}
]
}
Propose specific actions:
For each inbox item, recommend ONE of:
- Approve as-is — if quality high, voice aligned, no risks
- Edit [specific issue] — e.g., "Edit: shorten hook from 2 sentences to 1"
- Rewrite [section] — e.g., "Rewrite: make CTA more specific"
- Create variant — if fixable, suggest improved version
- Reject [reason] — if unfixable or off-brand
- Split into thread — if too long, better as multi-part
- Combine with [item_id] — if two items cover same topic
- Schedule for later — if time-sensitive and too early
Output suggested actions as:
{
"inbox_item_id": "uuid",
"suggested_action": "edit",
"action_detail": "Shorten hook from 2 sentences to 1. Remove second CTA. Change 'Check it out' to 'Try it free for 14 days'",
"reasoning": "Post is 90% there — minor edits will make it great",
"confidence": "high"
}
Create improved variants (if enabled):
If create_variants == true AND agent has Creator+ role:
- For items flagged with
medium or high risks BUT are salvageable:
- Load voice profile:
bolta.get_voice_profile(voice_profile_id)
- Generate improved version that fixes identified issues:
- Fix tone mismatch
- Remove banned phrases
- Clarify CTA
- Adjust length
- Maintain original message/value prop
- Create new draft:
bolta.draft_post({...original metadata, content: improved_version, status: "draft"})
- Link to original via metadata:
{original_inbox_item_id: "uuid"}
- Add comment on original:
bolta.add_comment(original_post_id, "I created an improved variant that fixes [issues]. See draft [variant_post_id].")
- Collect
variant_post_id
Variants stay in draft state (don't auto-submit to inbox)
Human can compare original vs variant and choose
Generate triage summary:
- High-level overview for human reviewer:
Inbox Triage Summary:
- 20 items reviewed
- 3 clusters identified (Product Launch, Weekly Tips, Engagement Posts)
- 5 items flagged high-risk (tone mismatch, overly salesy)
- 8 items ready to approve
- 4 items need minor edits
- 3 items should be rejected
- 2 improved variants created
Recommended priority order:
1. Review high-risk items first (ids: uuid1, uuid2, ...)
2. Batch-approve the 8 ready items
3. Compare variants for the 2 flagged posts
Update agent memory:
- If
agent_id provided:
bolta.remember(agent_id, "last_triage_run", ISO_timestamp)
bolta.remember(agent_id, "common_quality_issues", issue_frequency_map) → learn patterns
bolta.remember(agent_id, "variant_success_rate", success_count / total_count) → track if variants get approved
Output
{
"clusters": [
{
"cluster_id": "topic-product-launch",
"label": "Product Launch Posts",
"item_count": 5,
"inbox_item_ids": ["uuid1", "uuid2", "uuid3", "uuid4", "uuid5"]
},
...
],
"risk_flags": [
{
"inbox_item_id": "uuid1",
"risks": [
{
"category": "tone_mismatch",
"severity": "medium",
"detail": "..."
}
]
},
...
],
"suggested_actions": [
{
"inbox_item_id": "uuid1",
"suggested_action": "edit",
"action_detail": "Shorten hook...",
"reasoning": "...",
"confidence": "high"
},
...
],
"created_variant_post_ids": ["variant-uuid1", "variant-uuid2"],
"triage_summary": "Inbox Triage Summary:\n- 20 items reviewed\n..."
}
Failure Handling
- If inbox empty: return empty arrays + summary "Inbox is empty"
- If voice profile missing for an item: flag as risk, suggest re-linking voice
- If variant creation fails: add to warnings, continue with others
- If agent lacks permissions for variants: skip variant creation, return advisory-only output
Agent Types That Use This Skill
- reviewer — Primary use case (inbox quality control)
- custom — User-defined agents with review capabilities
Example Use Cases
Scenario 1: Daily Inbox Triage Job
- Reviewer agent runs daily at 8am
- Triages overnight content from creator agents
- Flags issues, proposes actions
- Human reviews summary over coffee, takes bulk actions
Scenario 2: @Mention on Inbox Page
- User opens inbox, sees 30 items, feels overwhelmed
- Types "@QABot review the inbox"
- QABot triages, returns summary with priority order
- User follows recommendations, clears inbox in 10 minutes
Scenario 3: Agency Client Review
- Agency has 15 clients, each with active content agents
- Reviewer agent runs triage filtered by
client_tag: "Acme Corp"
- Returns Acme-specific triage summary
- Agency team member reviews only Acme content, approves/edits
Scenario 4: Variant Creation Workflow
- Creator agent generates 5 posts, 2 are flagged high-risk
- Reviewer agent creates improved variants for the 2
- Human sees: Original (flagged) vs Variant (improved)
- Approves variant, rejects original
- Reviewer agent learns: "This type of improvement works"
1---2name: bolta-inbox-triage3description: V2 Reviewer agent skill - Cluster inbox items, flag risks, propose edits, optionally create improved variants. Makes the inbox manageable.4---56## Goal7Make the inbox manageable: cluster related content, flag quality/risk issues, propose specific actions, and optionally create improved variants.89## V2 Changes10- **Reviewer agent context** — this is the primary skill for `reviewer` agent type11- **State machine updated** — `inbox` (replaces "pending_review"), `approved`, `scheduled`, `published`12- **Agent memory integration** — recalls review patterns, common issues, voice alignment rules13- **Client tag filtering** — agencies can triage by client14- **@mention context** — if called via @mention on inbox page, scopes to visible items1516## When This Skill Is Called17- **Manual trigger** — User clicks "Triage Inbox" button in Bolta web18- **Scheduled job** — Reviewer agent runs daily/weekly triage19- **@mention** — User @mentions reviewer agent: "@QABot review the inbox"20- **Event trigger** — When inbox count > threshold (future enhancement)2122## Policy Rules231. **Viewers can only produce a read-only report** (no updates, no variants, no comments)242. **Creators can create variants and add comments** but cannot approve/schedule/publish253. **Editor/Admin can add comments and create variants** (approval is separate skill)264. **Never approve or schedule posts** — this skill is purely advisory (use `bolta.review.approve_and_route` for that)2728## Steps29301. **Check policy & capabilities:**31 - `bolta.get_workspace_policy(workspace_id)` → extract `safe_mode` (informational)32 - `bolta.get_my_capabilities(workspace_id)` → verify what agent can do33 - If role is Viewer: `create_variants = false` (force read-only)34352. **Load agent memory for context:**36 - If `agent_id` provided:37 - `bolta.recall(agent_id, "common_quality_issues")` → prioritize known problems38 - `bolta.recall(agent_id, "voice_alignment_rules")` → check consistency39 - `bolta.recall(agent_id, "approval_patterns")` → learn what gets approved40 - `bolta.recall(agent_id, "rejection_patterns")` → learn what gets rejected41423. **Fetch inbox items:**43 - `bolta.list_inbox_items({workspace_id, status: status_filter, limit})`44 - If `client_tag` provided: filter results by client_tag (agency feature)45 - For each item, also fetch full details:46 - `bolta.get_inbox_item(inbox_item_id)` → post content, metadata, creator agent, etc.47484. **Cluster items by similarity:**49 - Group by:50 - **Topic similarity** — same product/feature/theme51 - **CTA type** — engagement (like/comment), conversion (click link), educational (no CTA)52 - **Format** — thread starter, single post, carousel, poll53 - **Creator agent** — group by which agent created them (for pattern detection)54 - **Client tag** — agency users see clusters per client55 56 - Output clusters as:57 ```json58 {59 "cluster_id": "topic-product-launch",60 "label": "Product Launch Posts",61 "item_count": 5,62 "inbox_item_ids": ["uuid1", "uuid2", ...],63 "common_theme": "New feature announcement"64 }65 ```66675. **Flag risks and quality issues:**68 - For each inbox item, check against voice profile + brand rules:69 70 **Risk categories:**71 - **Tone mismatch** — doesn't match voice profile tone (check against `bolta.get_voice_profile`)72 - **Overly salesy** — too promotional, not enough value (check CTA density)73 - **Unverified claims** — mentions stats/numbers without source74 - **Too long** — exceeds platform best practices (>280 chars for Twitter, >3000 for LinkedIn)75 - **Unclear CTA** — has CTA but it's vague or weak76 - **No CTA** — missing CTA when one is expected (based on post goal)77 - **Banned phrases** — uses words from voice profile banned list78 - **Repetition** — very similar to recently published post79 - **Platform mismatch** — content doesn't fit platform norms (thread on Instagram, carousel on Twitter, etc.)80 81 - Risk severity: `low | medium | high`82 - Output risk flags as:83 ```json84 {85 "inbox_item_id": "uuid",86 "risks": [87 {88 "category": "tone_mismatch",89 "severity": "medium",90 "detail": "Post feels corporate; voice profile specifies 'conversational and punchy'"91 },92 {93 "category": "overly_salesy",94 "severity": "high",95 "detail": "3 CTAs in 280 characters — too aggressive"96 }97 ]98 }99 ```1001016. **Propose specific actions:**102 - For each inbox item, recommend ONE of:103 104 - **Approve as-is** — if quality high, voice aligned, no risks105 - **Edit [specific issue]** — e.g., "Edit: shorten hook from 2 sentences to 1"106 - **Rewrite [section]** — e.g., "Rewrite: make CTA more specific"107 - **Create variant** — if fixable, suggest improved version108 - **Reject [reason]** — if unfixable or off-brand109 - **Split into thread** — if too long, better as multi-part110 - **Combine with [item_id]** — if two items cover same topic111 - **Schedule for later** — if time-sensitive and too early112 113 - Output suggested actions as:114 ```json115 {116 "inbox_item_id": "uuid",117 "suggested_action": "edit",118 "action_detail": "Shorten hook from 2 sentences to 1. Remove second CTA. Change 'Check it out' to 'Try it free for 14 days'",119 "reasoning": "Post is 90% there — minor edits will make it great",120 "confidence": "high"121 }122 ```1231247. **Create improved variants (if enabled):**125 - If `create_variants == true` AND agent has Creator+ role:126 - For items flagged with `medium` or `high` risks BUT are salvageable:127 - Load voice profile: `bolta.get_voice_profile(voice_profile_id)`128 - Generate improved version that fixes identified issues:129 - Fix tone mismatch130 - Remove banned phrases131 - Clarify CTA132 - Adjust length133 - Maintain original message/value prop134 - Create new draft: `bolta.draft_post({...original metadata, content: improved_version, status: "draft"})`135 - Link to original via metadata: `{original_inbox_item_id: "uuid"}`136 - Add comment on original: `bolta.add_comment(original_post_id, "I created an improved variant that fixes [issues]. See draft [variant_post_id].")`137 - Collect `variant_post_id`138 139 - Variants stay in `draft` state (don't auto-submit to inbox)140 - Human can compare original vs variant and choose1411428. **Generate triage summary:**143 - High-level overview for human reviewer:144 ```145 Inbox Triage Summary:146 - 20 items reviewed147 - 3 clusters identified (Product Launch, Weekly Tips, Engagement Posts)148 - 5 items flagged high-risk (tone mismatch, overly salesy)149 - 8 items ready to approve150 - 4 items need minor edits151 - 3 items should be rejected152 - 2 improved variants created153 154 Recommended priority order:155 1. Review high-risk items first (ids: uuid1, uuid2, ...)156 2. Batch-approve the 8 ready items157 3. Compare variants for the 2 flagged posts158 ```1591609. **Update agent memory:**161 - If `agent_id` provided:162 - `bolta.remember(agent_id, "last_triage_run", ISO_timestamp)`163 - `bolta.remember(agent_id, "common_quality_issues", issue_frequency_map)` → learn patterns164 - `bolta.remember(agent_id, "variant_success_rate", success_count / total_count)` → track if variants get approved165166## Output167```json168{169 "clusters": [170 {171 "cluster_id": "topic-product-launch",172 "label": "Product Launch Posts",173 "item_count": 5,174 "inbox_item_ids": ["uuid1", "uuid2", "uuid3", "uuid4", "uuid5"]175 },176 ...177 ],178 "risk_flags": [179 {180 "inbox_item_id": "uuid1",181 "risks": [182 {183 "category": "tone_mismatch",184 "severity": "medium",185 "detail": "..."186 }187 ]188 },189 ...190 ],191 "suggested_actions": [192 {193 "inbox_item_id": "uuid1",194 "suggested_action": "edit",195 "action_detail": "Shorten hook...",196 "reasoning": "...",197 "confidence": "high"198 },199 ...200 ],201 "created_variant_post_ids": ["variant-uuid1", "variant-uuid2"],202 "triage_summary": "Inbox Triage Summary:\n- 20 items reviewed\n..."203}204```205206## Failure Handling207- If inbox empty: return empty arrays + summary "Inbox is empty"208- If voice profile missing for an item: flag as risk, suggest re-linking voice209- If variant creation fails: add to warnings, continue with others210- If agent lacks permissions for variants: skip variant creation, return advisory-only output211212## Agent Types That Use This Skill213- **reviewer** — Primary use case (inbox quality control)214- **custom** — User-defined agents with review capabilities215216## Example Use Cases217218**Scenario 1: Daily Inbox Triage Job**219- Reviewer agent runs daily at 8am220- Triages overnight content from creator agents221- Flags issues, proposes actions222- Human reviews summary over coffee, takes bulk actions223224**Scenario 2: @Mention on Inbox Page**225- User opens inbox, sees 30 items, feels overwhelmed226- Types "@QABot review the inbox"227- QABot triages, returns summary with priority order228- User follows recommendations, clears inbox in 10 minutes229230**Scenario 3: Agency Client Review**231- Agency has 15 clients, each with active content agents232- Reviewer agent runs triage filtered by `client_tag: "Acme Corp"`233- Returns Acme-specific triage summary234- Agency team member reviews only Acme content, approves/edits235236**Scenario 4: Variant Creation Workflow**237- Creator agent generates 5 posts, 2 are flagged high-risk238- Reviewer agent creates improved variants for the 2239- Human sees: Original (flagged) vs Variant (improved)240- Approves variant, rejects original241- Reviewer agent learns: "This type of improvement works"