prospect-posts — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited prospect-posts (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
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.
You scrape the most recent LinkedIn posts of one or more profiles via Apify and scan them for a specific theme the user cares about (e.g. "AI-first GTM", "hiring pain", "pivoting to enterprise"). Output is a structured report showing which profiles mentioned the theme, with quoted excerpts and post links.
This is research for prospect/account intelligence — read-only, multi-profile.
The user says something like:
Required inputs:
Optional:
If either profile URL or theme is missing, ask the user before running.
APIFY_API_TOKEN in .envrequests and python-dotenv installedAPIFY_API_TOKEN is set. If missing, tell the user to add it.prospects/{slug}/): save thereprospects/_scans/ (default){output_dir}/{date}-{theme-slug}.json{output_dir}/{date}-{theme-slug}.mdprospects/_scans/ if it doesn't exist.Run the scraper. Repeat --profile-url for each profile:
python3 utils/prospect_posts.py \
--profile-url "<url-or-username-1>" \
--profile-url "<url-or-username-2>" \
--count 20 \
--output-path "<json-path>"The script:
apimaestro/linkedin-profile-posts actor (no LinkedIn cookies needed, $0.005/post)https://www.linkedin.com/in/foo/) or a bare username (foo)total_posts input to auto-paginate to the requested count{profiles: [{input, username, profile_url, name, headline, status, posts: [{date, url, type, text, engagement}]}]}[Reshared from X] prefix so theme matching sees itstatus set and an empty posts array - surface this to the userRead the JSON output. For each profile, read every post's text and judge whether it matches the theme semantically - not by keyword. A post about "our GTM team is replacing playbooks with Claude agents" matches "AI-first GTM" even without the exact phrase. Conversely, a post that mentions "AI" in passing while talking about something unrelated should not match.
For each match, capture:
If a post is borderline, include it in a separate "Adjacent signals" section with a note on why it's adjacent rather than a direct match.
Write a markdown report at the report path with this structure:
# Post scan: {theme}
**Scanned:** {date}
**Theme:** {theme exactly as user phrased it}
**Profiles:** {count}
**Posts reviewed:** {total across all profiles}
## {Profile name or URL}
**Profile:** {linkedin url}
**Headline:** {headline if available}
**Posts reviewed:** {n}
**Direct matches:** {m}
### Direct matches
#### {date} - [link]({post_url})
> {quoted excerpt}
**Why it matches:** {one-line interpretation}
{repeat per match}
### Adjacent signals
{only include if any; same format with a "Why it's adjacent" line}
### No-match summary
{if zero matches, one sentence summarizing what they DO post about so the user can judge whether the theme is truly absent or just framed differently}
---
{repeat per profile}
## Cross-profile patterns
{2-4 bullets if multiple profiles: who is loudest on the theme, what angles recur, who's silent. Skip this section for single-profile scans.}Tell the user:
{name}: {n} direct matches, {m} adjacent or {name}: no mentions of {theme}Do not paste the full report into chat. The user will open the file.
prospects/_scans/ — gitignore this path in your project (scan output may contain commercial signals you don't want committed)prospects/{slug}/ folder, save there insteademail-writer or signal-builder).| Issue | Fix |
|---|---|
APIFY_API_TOKEN not found | Add to .env |
| Actor run times out | Increase timeout_secs in utils/prospect_posts.py or reduce --count |
Profile returned 0 posts with status SUCCEEDED | Profile may be private, have no public posts, or the username was wrong. Verify the URL in a browser |
A run shows FAILED / TIMED-OUT | Re-run just that profile. Apify actor can be flaky on specific profiles; a retry usually works |
| Zero matches but you expect some | Widen the theme interpretation, or check the no-match summary - the prospect may frame the topic differently than the user's phrasing |
| Schema changed / missing text | Inspect raw output with --raw-output /tmp/raw.json and update field names in extract_text() / extract_author() in utils/prospect_posts.py |
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.