---
name: proposal-channel-setup
description: >
Set up `_proposals` Slack channels — private channels paired 1:1 with Salesforce Accounts for
proposal activity, meetings, and deal context. Full provisioning: private channel, team invites,
Salesforce + SharePoint + social bookmarks, Skeptic verification. Triggers on "create proposal
channel", "set up proposals channel", "{company}_proposals channel", "proposal-channel-setup".
---
# Proposal Channel Setup Skill
> One command to fully provision a `{company}_proposals` Slack channel with everything the sales team needs.
## What It Does
Given a **company name**, this skill:
1. **Creates** `{slug}_proposals` as a **private** Slack channel
2. **Sets topic** → `{Company} — Proposal Tracking & Coordination`
3. **Sets purpose** → `{Company} proposal lifecycle — RFP analysis, drafting, review, and submission.`
4. **Invites** the full default team — ForgeBot (U0B9SM7MVB5), Sara (U06DRG2E268), Adam (U0J1D5G87), Mary (U049GDTM069), Greg (U0J1THQEP), Dave (U0JEWS1RB) — plus `@proposals-team`; no exceptions. If the Slack API creator token is ForgeBot, verify ForgeBot via `is_member: true`; if a human or another bot created the channel, explicitly invite ForgeBot.
5. **Adds bookmarks** — project-specific + company info (see Bookmark Structure below)
6. **Runs Skeptic Verification Protocol** — each step is verified before proceeding
7. **Links the channel to the Salesforce Account** (`Slack_Channel__c` lookup field)
## Channel Naming Convention
- Format: `{account_name}_proposals`
- Lowercase, spaces → underscores, no hyphens
- `&` → `and`, strip legal suffixes (Inc, LLC, Corp, etc.)
- Follow the Salesforce Account naming rules in `.claude/skills/salesforce/SKILL.md`
- Examples: `john_deere_proposals`, `university_of_texas_rio_grande_valley_proposals`
**Slug quick reference:**
| Company Name | Slug |
|-------------|------|
| `Blue Origin` | `blue_origin_proposals` |
| `Con Edison` | `con_edison_proposals` |
| `TaskUs` | `taskus_proposals` |
| `H&K Group` | `h_and_k_group_proposals` |
## Default Team to Invite
| Role | Name | Slack ID |
|------|------|----------|
| Automation Participant | ForgeBot | U0B9SM7MVB5 |
| Lead Proposal Specialist | Sara Golling | U06DRG2E268 |
| CSO & Co-Founder | Adam Kane | U0J1D5G87 |
| Exec. Dir. Enterprise Partnerships | Mary Pierce | U049GDTM069 |
| CEO & Co-Founder | Greg Meyers | U0J1THQEP |
| COO | Dave Vaillancourt | U0JEWS1RB |
Always invite `@proposals-team` (user group) in addition to the above.
## Template Channel
- **Reference:** `#template_robotics_proposals` (C0706MYSCH2)
- Mirror its bookmark structure for all new `_proposals` channels.
## Bookmark Structure
### Project-Specific Bookmarks ("Bookmarks" folder)
| Order | Title Format | Emoji | Notes |
|-------|-------------|-------|-------|
| 1 | `Account Salesforce` | (auto from URL) | SF Account link |
| 2 | `Opportunity {Opp Name}` | (auto from URL) | SF Opportunity link |
| 3 | `SharePoint Folder` | `:sharepoint:` | SharePoint Proposals Folder link |
| 4 | `{Proposal File Name}` | `:powerpoint:` | ACTUAL pptx filename — NEVER generic text like "Proposal PPT" |
| 5 | `Fireflies {Account Name}` | (auto from URL) | Fireflies notebook link (use `https://app.fireflies.ai/` placeholder if no meeting yet) |
### Company Info Bookmarks ("Company Info" folder)
| Order | Title | Notes |
|-------|-------|-------|
| 1 | `Website` | Main company/org website |
| 2 | `Facebook` | Company Facebook page |
| 3 | `YouTube` | Company YouTube channel |
| 4 | `LinkedIn` | Company/org LinkedIn page |
| 5 | `Twitter/X` | Company X/Twitter handle |
**Critical — social link sourcing:** Navigate to the company's actual website and extract social links from their header/footer/contact page. Never guess social media URLs from naming patterns. The Maine Drilling incident (2026-03-28) proved guessed URLs produce dead links (the real slug was `/company/mainedandb/`, not the assumed pattern).
### Contact-Specific Bookmarks (optional)
- `SF Contact - {Name}` — Salesforce Contact link
- `{Name} LinkedIn` — personal LinkedIn with `:link:` emoji
- `{Name} Faculty Page` — with `:mortar_board:` for academic contacts
### Bookmark API Notes
- Folder tabs cannot be created via API — Sara creates the folders and organizes links after being invited
- Scope: `bookmarks:write`, `bookmarks:read`
- Bot must be a channel member before calling bookmarks API. Proof required: `conversations.info` returns `creator` and `is_member`; if `creator === U0B9SM7MVB5`, ForgeBot is auto-covered by Slack's channel-create response (`is_member: true`). If not, invite ForgeBot (U0B9SM7MVB5) and verify with `conversations.members` before adding bookmarks.
## Salesforce Pairing
Each `_proposals` channel maps to exactly one Salesforce Account. After channel creation:
1. Create `Slack_Channel__c` record: `{Name: "channel_name", Account__c: "acct_id", Channel_ID__c: "CXXXXXXXX"}`
2. Update Account: `{Slack_Channel__c: "new_record_id"}` — auto-populates `Slack_Channel_URL__c` and `Slack_Channel_ID__c`
See `.claude/skills/ops/subskills/salesforce/` for auth.py connection details.
## Salesforce Account Lookup
SOQL: `SELECT Id, Name FROM Account WHERE Name LIKE '%{company}%' LIMIT 1`
If found → bookmark: `https://forgefx.lightning.force.com/lightning/r/Account/{Id}/view`
If not found → skip bookmark, log warning in setup output
## Setup Checklist
1. Create private channel with correct naming convention
2. Invite the full default team — ForgeBot (U0B9SM7MVB5), Sara (U06DRG2E268), Adam (U0J1D5G87), Mary (U049GDTM069), Greg (U0J1THQEP), Dave (U0JEWS1RB) — plus `@proposals-team`
3. Add SF Account bookmark
4. Add SF Opportunity bookmark (include opportunity name in title)
5. Add SharePoint Proposals Folder bookmark — title: `SharePoint Folder`, emoji: `:sharepoint:`
6. Add Proposal PPT bookmark — title: the ACTUAL proposal filename, emoji: `:powerpoint:`
7. **Add SharePoint PowerPoint link to SF Opportunity** — create a Note on the SF Opportunity with the SharePoint viewer link to the new PowerPoint file. Use `action=view` URL. Title: `Proposal Deck — {Proposal File Name}`. Body: the full `https://forgefx.sharepoint.com/...action=view` link.
8. Add Fireflies bookmark (or placeholder)
9. Add company Website, Facebook, YouTube, LinkedIn, Twitter/X bookmarks (sourced from company website)
10. Pair channel to Salesforce Account (`Slack_Channel__c`)
11. Verify bookmark order matches template channel
## Backfill Existing Channels
Use the repo-local TypeScript backfill when an existing `_proposals` channel may be missing ForgeBot:
```bash
doppler run --project forgeapps --config prd -- pnpm exec tsx channels/scripts/backfill-proposal-channel-members.ts --since=2026-03-01
```
The command is audit-only by default and checks ForgeBot access only. After reviewing the missing-user list, add `--apply` to invite ForgeBot only where missing and verify access after each invite. Use `--full-default-team` only for an explicit broader team audit; add `--include-proposals-team` only when the active Slack token can read `@proposals-team`.
## Skeptic Verification Protocol (MANDATORY)
Every setup MUST run the Skeptic Verification Protocol. No step is complete until verified.
After each step, spawn a **Skeptic sub-agent** that:
1. Challenges the claim that the step was completed correctly
2. Demands verifiable proof — not "I did it"
3. Only passes when evidence confirms correctness; if rejected, fix and re-verify
### Verification Matrix
| Step | What to Verify | How to Prove It |
|------|---------------|-----------------|
| **Channel creation** | Private, name follows convention, creator identified | `conversations.info` → `is_private: true`, name matches `{slug}_proposals`, record `creator`; if creator is `U0B9SM7MVB5`, Slack's `is_member: true` proves ForgeBot is in by creation |
| **Team invites** | ForgeBot + full default team + @proposals-team present | `conversations.members` → confirm U0B9SM7MVB5, U06DRG2E268, U0J1D5G87, U049GDTM069, U0J1THQEP, U0JEWS1RB + all proposals-team IDs |
| **SF Account bookmark** | URL points to real Account | SOQL `SELECT Name FROM Account WHERE Id = '{id}'` → name matches company |
| **SF Opportunity bookmark** | URL points to real Opportunity | SOQL verify; belongs to correct Account |
| **SharePoint folder bookmark** | Folder exists | Hit SharePoint API → confirm 200, not 404 |
| **Proposal PPT bookmark** | File exists, title = actual filename | SharePoint file check + compare bookmark title to filename |
| **SF Opportunity Note (PPT link)** | Note created on Opportunity with SharePoint viewer URL | SOQL `SELECT Id, Title, Body FROM Note WHERE ParentId = '{opp_id}' AND Title LIKE 'Proposal Deck%'` → confirm URL is present |
| **Fireflies bookmark** | Valid URL or placeholder | Confirm format `https://app.fireflies.ai/...` |
| **Social links** | Each URL loads the company's actual page | web_fetch each URL → HTTP 200 + company name in content |
| **Salesforce pairing** | `Slack_Channel__c` record created, Account updated | SOQL verify both records |
| **Bookmark order** | Matches template channel | `bookmarks.list` on new + template channel → compare order |
### Skeptic Sub-Agent Prompt
```
You are the Skeptic. Your job is to challenge whether Step {N} of the proposal channel setup was completed correctly.
Step: {description}
Claimed result: {what the setup agent says it did}
Evidence provided: {URLs, API responses, screenshots}
1. Examine the evidence critically
2. Poke holes — is the URL live? Does it point to the RIGHT company? Is the data fresh?
3. If ANY issue found, reject with clear explanation
4. Only PASS if genuinely satisfied
Respond with either:
- PASS: {brief explanation of why evidence is sufficient}
- FAIL: {what's wrong and what needs to be fixed}
```
Max 3 retries per step before escalating to human. After all steps pass, post a verification report as a thread reply in the new channel.
## Error Handling
| Scenario | Behavior |
|----------|----------|
| Channel name taken | Check if existing channel is the right one; if so, continue setup |
| SF Account not found | Skip SF bookmark, warn in setup output |
| SharePoint folder unknown | Use convention-based URL, note as unverified |
| Social links unreachable | Skeptic FAIL — source from company website, re-verify |
## Dependencies
- **Slack** — `.claude/skills/comms/subskills/slack/SUBSKILL.md`
- **Salesforce** — `.claude/skills/ops/subskills/salesforce/`
- **Salesforce Account naming** — `.claude/skills/salesforce/SKILL.md`
---
_Canonical skill for `_proposals` channel provisioning. Created 2026-03-10; Skeptic protocol + bookmark structure merged in 2026-05-15; SF Opportunity Note (PPT SharePoint link) step added 2026-05-23 per Sara Golling._