leadbay_work_campaign — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited leadbay_work_campaign (Agent Skill) and scored it 96/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 1 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 1 flagged
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Work my <the user-supplied value if any; otherwise a sensible default. Source: Campaign name (fuzzy match against your own campaigns) or campaign UUID. Omit to list and pick interactively.> campaign as an outreach session<if the user supplied this argument, render the short parenthetical or inline clause derived from it; otherwise empty. Source: Optional: skip the readiness-assessment proposal and jump directly into 'call_sheet' / 'email_sheet' / 'map' / 'enrich_first'. Omit (recommended) and let the prompt propose based on the data.>.
GATE — DEFER TO TOOL RENDERING. When you call a Leadbay composite that ships its own RENDERING block (every composite in 0.9.0+ does), render the response using that block's recipe verbatim — score bars, glyph palette, column order, hide-list, link priorities, all of it. Do NOT substitute prose, a numbered list, or a different column structure even when an orchestrating prompt's body suggests alternate framing. Prompt-specific commentary (motivational nudges, summaries, next-action recommendations) belongs ABOVE or BELOW the canonical table, never in place of it.
If the prompt's body and the tool's RENDERING appear to conflict, the tool's RENDERING wins for the structural layout; the prompt's voice wins for the commentary that surrounds it.
If I gave you a name or id, resolve it. Otherwise call leadbay_list_campaigns() and surface the active campaigns as a single_select via your host's choice widget (ask_user_input_v0 or AskUserQuestion) (cap at 4 — sort by updated_at desc, archived hidden):
Which campaign do you want to work? - <Name 1> · <N leads> · last touched <date> - <Name 2> · <N leads> · last touched <date> - …
When the user picks, capture the campaign_id. If <Campaign name (fuzzy match against your own campaigns) or campaign UUID. Omit to list and pick interactively. Optional.> is a name, fuzzy-match against campaigns[].campaign.name. On ambiguous matches, surface a single_select instead of guessing.
Call leadbay_campaign_call_sheet({campaign_id}). The response carries summary + readiness — use them to figure out what the user CAN actually do today, then PROPOSE the right session mode rather than auto-rendering.
Read the summary numbers:
total_leads, total_contactsleads_with_phone — can call from this many leadsleads_with_email — can email this manyleads_with_coords — can map this manyleads_without_contacts — these need enrichment before any outreach is possibleleads_already_contacted — these have prior touches; the rep may want to skip them for cold workRead the `readiness` booleans (pre-computed thresholds):
ready_for_calling (phone coverage ≥60%) — call session viableready_for_emailing (email coverage ≥60%) — email session viableneeds_enrichment (≥30% no-contacts OR both phone+email coverage <40%) — enrichment recommended firsttravel_friendly (≥5 geocoded leads AND coord coverage ≥60%) — map mode worth proposingOne-line situation report (always emit BEFORE the proposal):
📋 <total_leads> leads · 📞 <leads_with_phone> with a phone · ✉ <leads_with_email> with an email · 🗺 <leads_with_coords> with coords · 🔴 <leads_without_contacts> need enrichment · ✅ <leads_already_contacted> already touchedThen PROPOSE the right modes via your host's choice widget (`ask_user_input_v0` or `AskUserQuestion`) (2-4 options, sorted by what makes the most sense for THIS campaign's data):
ready_for_calling. Top option when phones are there.ready_for_emailing AND email_ratio > phone_ratio. Don't surface this when calling is more obvious.needs_enrichment. Top option when most leads have no contacts. Phrase as "<N> leads have no reachable contact yet — enrich titles before we start?" so the user understands the cost.travel_friendly AND the user hasn't previously signaled disinterest in maps (check your conversation memory; if you've seen the user dismiss map renders before in this session or saved a "no maps" preference, drop this option).If the MCP prompt argument mode was actually supplied, skip the proposal and jump to the matching mode below. If mode was omitted, do not treat call_sheet as implicit user consent — propose first.
Render per the leadbay_campaign_call_sheet RENDERING block — one CARD per lead with the 4-col contact table (Contact / Phone / Role / Recent). The phone in column 2 MUST be [bare](tel:URL) (use contact.phone_tel_url verbatim — the composite has already canonicalized it). The contact name in column 1 MUST be [Name](linkedin_url). Email stacks under the name when present (✉ [email](mailto_url)). Recent stacks 📝 last note + 📞 last_action_headline.
End the turn with the standby line:
Ready to start calling. Tell me what happened after each call — I'll record the note + outcome.
Same data, slightly different render emphasis: drop the Phone column, put ✉ [email](mailto_url) as column 2. Below each lead's table, generate a SUGGESTED short email draft per the next-step — but DON'T send. Drafts are for the user to copy-paste / send themselves.
Extract leadIds from sheet.leads[].lead_id, then call leadbay_enrich_titles({leadIds, …}) (consult its description for titles / email / phone selection; do not pass campaign_id, because that is not part of the tool schema). Surface progress to the user. When complete, automatically loop back to Phase 1 (re-fetch the call sheet, re-assess readiness, re-propose).
Pass response.map_locations directly to places_map_display_v0 — the composite has already built the per-pin notes string with the top contact's phone inline. After the widget, emit the standard 4-col card list anyway so the rich detail is still scannable.
When the user says something like "Called Bree, voicemail, trying again Tuesday" or "Talked to John, wants pricing sent next week", parse:
STILL_CHASING — pursuing, no decision yet ("trying again", "they'll get back to me")COULD_NOT_REACH_STILL_TRYING — voicemail, no answer, wrong number, gatekeeper blockedINTEREST_VALIDATED_OR_MEETING_PLANED — meeting booked, quote requested, "send me more info"NOT_INTERESTED_LOST — declined, "not now", "not a fit", "remove from list"Call leadbay_report_outreach({lead_id, note: <user's words>, epilogue_status: <picked>, verification: {source: "user_confirmed", ref: <user's exact words verbatim>}}). Confirm in ONE line: "✅ Logged: <Company> → <epilogue>. Next?"
Then wait for the next dictation. Don't ask "anything else?" — just acknowledge and wait.
When the user says "done" / "that's it" / "wrapping up" / similar, surface a session summary chip:
Session complete — N calls logged: X meetings booked · Y still chasing · Z couldn't reach · W declined.
Optional: offer to review the leadbay_campaign_progression for the same campaign to see the updated counts.
verification field on leadbay_report_outreach is REQUIRED. For calls (no message id), always use {source: "user_confirmed", ref: <user's verbatim words>}. Skipping it is forbidden; fabricating a gmail_message_id for a call is forbidden.leadbay_report_outreach invocation. Don't batch; each call has its own note + outcome.mode=map.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.