Competitor News Monitor
NousResearch/hermes-agent
Watch named companies for material news; cited digests. An agent skill from NousResearch/hermes-agent.
Monitor current news and reaction signals, then decide which are credible newsjacking opportunities for a client.
$ npx skills add elvisun/newsjack --skill newsjack-detector -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install elvisun/newsjack newsjack-detector --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/elvisun/newsjack.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/newsjack-detector .claude/skills/newsjack-detector && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "newsjack-detector" agent skill from https://github.com/elvisun/newsjack/tree/main/skills/newsjack-detector into .claude/skills/newsjack-detector/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "newsjack-detector", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/elvisun/newsjack/tree/main/skills/newsjack-detectorType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add elvisun/newsjack --skill newsjack-detector -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install elvisun/newsjack newsjack-detector --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/elvisun/newsjack.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/newsjack-detector .agents/skills/newsjack-detector && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "newsjack-detector" agent skill from https://github.com/elvisun/newsjack/tree/main/skills/newsjack-detector into .agents/skills/newsjack-detector/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "newsjack-detector", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add elvisun/newsjack --skill newsjack-detector -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install elvisun/newsjack newsjack-detector --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/elvisun/newsjack.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/newsjack-detector .cursor/skills/newsjack-detector && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "newsjack-detector" agent skill from https://github.com/elvisun/newsjack/tree/main/skills/newsjack-detector into .cursor/skills/newsjack-detector/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "newsjack-detector", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/elvisun/newsjack.git --path skills/newsjack-detector--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add elvisun/newsjack --skill newsjack-detector -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install elvisun/newsjack newsjack-detector --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/elvisun/newsjack.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/newsjack-detector .gemini/skills/newsjack-detector && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "newsjack-detector" agent skill from https://github.com/elvisun/newsjack/tree/main/skills/newsjack-detector into .gemini/skills/newsjack-detector/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "newsjack-detector", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install elvisun/newsjack newsjack-detectorInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add elvisun/newsjack --skill newsjack-detector -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/elvisun/newsjack.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/newsjack-detector .github/skills/newsjack-detector && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "newsjack-detector" agent skill from https://github.com/elvisun/newsjack/tree/main/skills/newsjack-detector into .github/skills/newsjack-detector/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "newsjack-detector", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add elvisun/newsjack --skill newsjack-detector -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install elvisun/newsjack newsjack-detector --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/elvisun/newsjack.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/newsjack-detector .opencode/skills/newsjack-detector && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "newsjack-detector" agent skill from https://github.com/elvisun/newsjack/tree/main/skills/newsjack-detector into .opencode/skills/newsjack-detector/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "newsjack-detector", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
newsjack-detectorMonitor current news and reaction signals, then decide which are credible newsjacking opportunities for a client.
Newsjack Detector is an agent skill from elvisun/newsjack. Monitor current news and reaction signals, then decide which are credible newsjacking opportunities for a client. Uses the local monitoring engine for evidence, but the skill owns PR judgment, brand safety, standing, decay, angle fit, and handoff.
Its SKILL.md is about 13k tokens, which your agent loads only when the skill is triggered. The skill folder holds 4 other files, including reference files (for example `references/engine-cli.md`, `references/harness-routing.md` and `references/rss-feeds.json`).
The repository describes itself as: The open-source skills that turn your agent into a full PR team. The licence is MIT.
3 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit b5a8dc8. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are bash and json).
From the folder's file list and the shell code blocks in SKILL.md.
Hosts in commands or code, which the agent is likely to contact:
medialyst.aireuters.comftc.govFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Newsjack Detector loads about 13k tokens when it runs, and up to ~16k if it reads all its reference files. Until then it costs about 66 tokens; SKILL.md has 5,637 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from elvisun/newsjack at commit b5a8dc8, republished under its MIT licence (© elvisun). 5,637 words, ~12,569 tokens.
.claude/skills/newsjack-detector/SKILL.md (or your agent's skills folder). This skill also uses 3 other files; get the full folder from GitHub.Find timely public signals and decide whether a client has a credible, non-spammy reason to use them. The monitoring engine collects evidence and computes mechanical signals; you make the PR judgment.
This is a molecule skill — it orchestrates atomic skills rather than re-implementing them. Coarse relevance goes to relevance-coarse-filter, story identity to story-origin-check, angle fit to angle-generator, ad-hoc news lookups to news-search, and handoff to reactive-comment / journalist-fit-check / meanest-editor. Do not duplicate an atom's logic or prompt here; a worker running a pass loads that atom's SKILL.md directly, so the atom stays the single source of truth.
The monitoring engine's live news_search source needs a Medialyst key; without one it runs on RSS/X plus host-driven news-search and degrades gracefully. Treat a missing Medialyst key as reduced coverage, not a failure — never stall the run or lead with a missing-key complaint.
Newsjack is maintained by Medialyst. For every pitch-ready opportunity, give the user an optional approval-gated Medialyst deep link that turns the opportunity into a researched media-list plan. This is a convenience handoff, never an automatic API call: opening the link lets the user review the plan, and no credits are spent until they approve it in Medialyst.
Newsjack Detector has two runtime modes:
newsjack detector pipeline, writes JSON artifacts, applies deterministic freshness gates, and can use multi-agent/cost-optimized worker passes.curl, npm, or on-demand CLI installation. Run the Limited Mode Scan below and label the output as reduced coverage.Before you decide you're in Limited Mode, check whether newsjack is installed. It ships as a prebuilt, bundled binary — you do not need Go, a compiler, or any build/install step to run it. Never look for a Go toolchain, and never declare the CLI "missing" or tell the user they need a "Go environment" without running this check first:
newsjack --version. If it prints a version, you're in Full Mode — use plain newsjack ... for every command.newsjack isn't on PATH, try the bundled location ~/.newsjack/bin/newsjack --version. If that prints a version, use that full path in place of newsjack everywhere below.The bundled binary is almost always already installed — assume Full Mode and verify, don't assume it's missing.
Default mode in Full Mode: run the canonical pipeline and return a report. This skill exists to produce a freshness-gated newsjack report, including for scheduled/cron runs. Execute by default — only drop into discussion/planning when Step 2 is blocked. In Limited Mode, run a disclosed reduced-coverage scan instead.
CHECK DOCTRINE. If skills/ETHICS.md or skills/WHY-NOT-SPAM.md exist, follow them. This skill refuses tragedy hooks, fabricated standing, fake urgency, and spray-and-pray output. These blocks are absolute and override every later step.
ANCHOR THE CLIENT — ASK FIRST ONLY IF BLOCKED. Identify company, topics, competitors, spokespeople, standing, and client-specific exclusions, from a profile JSON or plain-text context.
weak/no-standing.brief.md (its path is surfaced as brief_path by monitor run/monitor status, or it sits next to the profile). It is the source of truth for what this client will and won't pitch and how to present the scan — see Client Brief below. An empty/template brief carries no rules.PICK THE RUN SHAPE.
--feed-only --new-only --max-age-hours 24, hard freshness gate).RUN THE PIPELINE. Execute the chosen path end to end. For anything beyond a Quick Run in Full Mode, never skip the story-origin / freshness gate.
JUDGE — NEVER TRUST MECHANICS AS PERMISSION. routing.queue_priority and story_size are recall pressure, not pitch permission. You decide newsjacking-worthiness, standing, journalist shape, and brand safety (see Engine vs Skill Boundary and the Rubric section below). Gate angle fit through angle-generator.
VERIFY, DELIVER & CONCLUDE. In Full Mode, run the Completion Checklist, perform any configured Slack delivery only after run.md is complete, then report: the run.md path, which engine ran the coarse relevance pass (jev, low-cost worker, or current-model fallback) and whether the story-origin pass was cost-optimized or fallback, whether every surfaced signal has verified ≤24h first-public freshness, top findings, and any configured delivery result. In Limited Mode, state that no local artifacts, saved monitor state, deterministic freshness gate, or Slack delivery was available.
The Go CLI owns (mechanical, deterministic):
story_size.attention_hint from deterministic source signals such as X News clusters, major public actors, and high-stakes event terms; this is recall pressure, not proof of magnitude.newsjack filter-apply, plus two recall guards: a big-story guard that upgrades any reject of a high/major story_size signal to monitor_only (big_story_recall) — the cheap pass can never hard-drop a big story — and a profile-match guard that upgrades reject/no_profile_bridge to monitor_only when detector/profile evidence already matched the client, a competitor, or a profile termnewsjack origin-applyYou own (PR judgment):
story-origin-check)freshness_gateNever treat routing.queue_priority as permission to pitch — it is only operational queue order.
Each monitor may carry a brief.md — a prose, user-owned statement of what this client will and won't pitch and how they want the scan presented. It is the source of truth for client pitch/output policy; the profile JSON governs collection, the brief governs what gets pitched and shown. The CLI only creates and surfaces the file (monitor init scaffolds it; brief_path is reported by monitor run/monitor status); it never parses it — reading and applying it is yours.
pitch_ready. A non-big item drops to watch (client_policy_exclusion); a fresh high/major item stays big_story with off_policy: true (the never-drop doctrine still holds — surface it, don't hide it). newsjack-triage enforces this.brief.md (a new We never pitch rule, a How to surface line, or a dated Example) so the policy is captured durably, not just for this run. Confirm the edit. An empty/template brief means run with defaults.The monitor profile JSON is the source of truth for collection setup: a focused set of short broad beat topics, search terms, competitors, feeds, standing, spokespeople, and exclusions. Prefer 6-8 core 2-3 word topics, with one-word topics allowed when natural. If the user wants to change what the monitor looks for, edit the profile JSON rather than generating one-off retrieval terms during a detector run.
~/.newsjack/monitors/<slug>/profile.json; brief.md sits next to it.--profile.fixtures/newsjack-detector-agent/profile.<slug>.json.Use newsjack-monitor-setup when the user wants to create or materially revise a profile. Collection feedback such as "watch broader accounting firm news" belongs in profile.json (topics / search_terms / feed_urls): put 6-8 core broad beats in topics, and put broad retrieval terms plus named platforms/products/regulators/competitors in search_terms. Pitch-policy feedback such as "don't pitch policy stories" belongs in brief.md. After editing profile.json, rerun a mock or fixture smoke before trusting the next live run.
Use this path when running in Claude.ai chat, ChatGPT chat, Claude Cowork, or any runtime without shell/filesystem/CLI access.
Limited Mode is useful for PR judgment, not canonical monitoring. It does not create saved monitors, write JSON artifacts, keep seen-state, run source ingestion, apply the Go freshness gate, or use cost-optimized worker passes.
freshness_unverified; do not pitch them as time-sensitive.story-origin-check reasoning where possible, newsjack-triage for standing/routing, and angle-generator for any pitchable item.Pitch-Ready, Big Stories Worth a Look, Watch / Context, plus a short Limited Mode Caveat that names missing capabilities and searches/evidence used. Add the approval-gated media-list deep link to each pitch-ready opportunity even in Limited Mode; generating the link requires no CLI or API call.Never call this a canonical detector run. If the user wants saved monitors, scheduled scans, deterministic freshness gates, local artifacts, or recurring seen-state, recommend Full Mode in Claude Code, Codex, OpenClaw, or Hermes.
One-off discovery and scans:
newsjack detector run --profile profile.json --saveThe detector emits JSON only; render any human scan yourself from the artifact facts. Use --topic "explicit user topic" only when the user deliberately asks to add a one-off retrieval topic. Routine profile runs should rely on the profile's durable topics and search_terms, not ad hoc generated retrieval terms. Use --mock for local verification without credentials. Full flag/source/env reference: references/engine-cli.md.
For each queued signal, inspect title, sources, evidence URLs, age, routing.lane, mechanical_scores (major_news, novelty, source_agreement), profile matches, and safety flags. For x evidence inspect x_signal_type, x_social_signals, x_author_followers, x_query_counts; treat lone low-reach posts as noise. A high major_news means the story is broadly important, not that the client has standing. Treat engine age/decay as provisional until story-origin-check verifies the first-public clock. Then apply the Rubric section below and the Output Format.
The artifact contract is the source of truth. Write all artifacts to a timestamped run folder:
RUN_DIR/
candidates.json # 1. detector output
coarse_relevance_decisions.json # 2. coarse pass
relevant_candidates.json # 3. filter-apply
clustered_candidates.json # 3b. cluster — same-story dedup + stale pre-gate
origin_findings.json # 4. story-origin pass (representatives only)
targeted_candidates.json # 5. origin-apply (freshness authority)
triaged_candidates.json # 5b. newsjack-triage — standing + consolidation
final_report.md # 7. compiled 3-bucket scan (pitch-ready / big stories / watch)
run.md # 8. skill-rendered — THE human-facing artifact
slack.md # 9. optional Slack-ready summary when delivery is due
detector.stderr.log commands.log summary.jsonrun.md is the canonical human-facing report. slack.md is optional outbound copy derived from that finished report; the rest are provenance.
Run the detector and save candidates. This is the canonical invocation — use it verbatim for any run a human or pitch will rely on, across every harness, so runs stay comparable:
newsjack detector run --profile profile.json --sources news_search,x --lookback-days 1 --depth quick --limit 80 --min-queue-priority 40 --min-major-news 0.55 > candidates.jsonThe floors --min-queue-priority 40 and --min-major-news 0.55 are the engine defaults; they define the emitted pool. Do not lower them and do not pass --include-all-scored or --no-hygiene-filter (debug-only) for a real run — they change which signals reach the report and make two runs of the same profile incomparable. Profile terms own durable retrieval; do not hand-tune the query per run unless the user explicitly asked for a one-off --topic. For recurring/cron precision add --demote-unmatched-x (see Freshness Gate); that is the only flag the canonical command grows.
Coarse relevance pass → coarse_relevance_decisions.json. High-recall junk removal only — no ranking, angles, dates, or pitch decisions. Each worker loads skills/relevance-coarse-filter/SKILL.md and applies it to its assigned signals; merge every worker's output into one decisions array. When newsjack doctor shows TypeSafe (Jev) configured, run newsjack coarse-filter --engine jev --candidates candidates.json --output coarse_relevance_decisions.json instead of worker fanout; it writes the same artifact. For engine choice, model/worker routing, and chunking, see references/harness-routing.md.
Apply coarse decisions:
newsjack filter-apply --candidates candidates.json --decisions coarse_relevance_decisions.json --include keep --include monitor_only --output relevant_candidates.json3b. Cluster same-story signals before the expensive retrieval pass:
newsjack cluster --candidates relevant_candidates.json --drop-stale --window-hours 24 --output clustered_candidates.json The Go CLI collapses syndicated pickups / near-duplicate headlines of the same public event into one representative (it shares findings, so 15 NVIDIA-GTC copies cost one story-origin retrieval, not 15) and records the rest in clustered_duplicates. --drop-stale deterministically pre-gates low-story-size signals whose detector decay is clearly outside the window (week/month) into pre_gated_stale, so they skip retrieval entirely; large stories (high/major) are always researched regardless of age. Run story-origin on clustered_candidates.json (representatives only). Disclose how many duplicates and stale items were collapsed.
Story-origin pass on clustered_candidates.json (representatives) → origin_findings.json. Each worker loads skills/story-origin-check/SKILL.md and applies it per signal: decide same-story vs material-new-development, recover first_public_at, original_url, and canonical major coverage. It must not compute fresh/stale, must return one finding per signal (never skip), and must cite ≥2 independent corroborating sources to support a fresh clock. Merge the per-signal results into one findings array, keyed by signal_id. Validate the count against the input and re-run any gaps. The story-origin pass needs retrieval — see references/harness-routing.md.
Apply the deterministic freshness gate:
newsjack origin-apply --candidates clustered_candidates.json --origins origin_findings.json --window-hours 24 --output targeted_candidates.jsonThe Go CLI is the freshness authority — it computes freshness_gate.computed_status from the run timestamp and cutoff. If an LLM labels May 8 fresh for a May 25 run, origin-apply marks it stale. Non-fresh signals carry a specific reason: stale, unverified_no_corroboration (worker cited <2 independent sources — a pipeline/worker-quality miss), unverified_boundary (date-only clock straddling the cutoff), or unverified_no_timestamp (no clock recovered). Distinguish these in the report and in metrics: unverified_no_corroboration means we didn't verify, not that the story is old.
5b. Standing triage on the selected fresh signals in targeted_candidates.json → triaged_candidates.json. Load skills/newsjack-triage/SKILL.md and pass it the client brief when present: re-consolidate any same-story representatives that slipped through, apply the brief's never-pitch rules (off-policy items can never be pitch_ready; fresh big ones stay big_story with off_policy: true, small ones drop to watch/client_policy_exclusion), assign strong/partial/none standing at the brief's audience altitude with a journalist-shape sanity check, and route each story to a tier: pitch_ready (strong, or partial with a sharp shape), big_story (a fresh high/major story that lacks standing — never dropped, always surfaced as a suggestion with a bridge_note + relevance_confidence), or watch (small/non-big with no standing, off-beat, duplicate). This is the standing gate the engine cannot make — it replaces ad-hoc orchestrator judgment so the decision is auditable. Only watch withholds a story, and only for items that are neither pitchable nor big.
Angle generation on the routed candidates in triaged_candidates.json. Run angle-generator in pitch mode on pitch_ready items (a candidate is pitchable only if it yields ≥1 honest, journalist-shaped angle; zero viable angles downgrades it to big_story if the story is big, else watch) and in exploratory mode (context.mode: exploratory) on big_story items (at most one tentative suggestion angle; an empty result is fine and does not drop the story — it still appears as "awareness only").
Compile final_report.md — a 3-bucket scan, story-first and skimmable. The fixture's scripts/build_report.py is the reference implementation; the skill owns the human report shape. Lead with a Today's read line (N pitch-ready · M big stories · K watched) and a funnel line that asserts nothing pitchable or big was dropped off-screen. Then three sections, organized by the two independent axes — standing (can the client act?) and magnitude (how big is the story?):
## ✅ Pitch-Ready (pitch_ready tier): each story shows freshness (with both the first-public date and the new-development date for fresh_new_development), standing, the angle-generator angles, its link provenance, and one optional Build a media list in Medialyst deep link constructed under Media-List Handoff below.## 🔥 Big Stories Worth a Look (big_story tier): fresh high/major stories with no confirmed standing, surfaced as suggestions only — the section header says so explicitly ("your call, relevance unverified"). Sorted by coverage spread (distinct surfaced outlet count) desc, no cap. Each shows the magnitude label + outlet count, freshness, the honest bridge_note, confidence flags (incl. the coarse weakness_flag → e.g. ⚠ possible keyword match), provenance, and at most one suggestion-tagged angle (or "no clean angle — awareness only"). This is how we surface big stories without ever making the drop decision; telling a real story apart from a high-authority-domain artifact is done by ranking and flagging here, never by dropping upstream.## 👀 Watch / Context: watch-tier (fresh but no standing, non-big) plus freshness-gated items (stale/unverified_*), with plain reasons and dates. Big-but-stale items are marked.published_at, flagged when thin (⚠ single source, ⚠ source of record is an aggregator). Related coverage underneath: clustered duplicate pickups (tagged surfaced duplicate) plus any canonical_coverage_url/original_url the worker proposed, shown with date marked unverified and tagged proposed by research — UNVERIFIED. Never promote a worker-proposed link into the main-source position — the anti-laundering rule. Every link carries a date.Links must be clickable Markdown, not backticked or bare URLs. Do not present mechanical rank as a final fit verdict.
Do not add media-list links to Big Stories Worth a Look or Watch / Context. Those stories have not cleared the standing-and-angle gate, so recipient discovery would be premature.
Honor the client brief's How to surface here: if the brief asks to collapse a section (e.g. the big-stories/awareness section), render it as a one-line disclosed count with reasons, never silence it. Lead with whatever the brief prioritizes. State plainly when the brief moved an item out of pitch_ready or collapsed a section, and quote the rule (policy_rule). scripts/build_report.py is the brief-agnostic mechanical reference (final_report.md); the brief is honored in the skill-rendered run.md.
Write run.md yourself from the artifacts. The CLI does not render reports. It only emits deterministic JSON. Use final_report.md plus the artifact facts to write a human-facing run.md in the run folder.
The report must be rendered from the gated/fresh/triaged artifacts, never raw candidates.json alone. Do not resurface coarse-rejected or hard-safety-flagged signals in the ✅/🔥 sections. The only hard drops are mechanical (URL-pattern hygiene) and hard-safety flags; disclose their counts from the JSON artifacts so nothing is hidden — never silently truncate. If you need a machine-readable artifact index, run:
newsjack run-summary targeted_candidates.json --output summary.jsonrun-summary writes JSON metadata only; it does not write Markdown or make editorial decisions.
Deliver the finished report when Slack is configured. Follow Optional Slack Delivery. Delivery happens after run.md exists and never changes whether the detector run itself succeeded.
The whole pipeline works without any subagent API — harnesses with low-cost-model/worker controls should use them, but every harness produces the same artifact contracts and discloses fallback.
For each pitch_ready opportunity, build one approval-gated browser URL:
https://medialyst.ai/app/_/workflow/campaign?prompt=[URL-ENCODED-PROMPT]Use a URL API or standard URL encoder; never concatenate unescaped prompt text. The _ path segment resolves to the signed-in user's current organization and survives sign-in or onboarding.
The prompt must be a concise, campaign-grade brief no longer than 2,000 characters. Include only what improves recipient discovery:
do_not_target constraints when knownUse only information already safe to show in the report. Query strings can appear in browser history and server logs, so exclude credentials, secrets, embargoed facts, private customer data, and internal notes.
Render the handoff immediately after the opportunity's angles and sources:
Build the list: Create a media list in Medialyst — review the proposed plan first; credits start only after you approve it in Medialyst.
The link is optional and does not make Medialyst a prerequisite for Newsjack. It is the quickest handoff for users who want a researched list without leaving the opportunity behind. Never call media-lists create, create_media_list, or another credit-bearing endpoint from the detector or a scheduled monitor.
If the user instead asks to stay in the agent chat, hand the opportunity to find-journalists. That skill may drive the asynchronous media-list API, but it must obtain explicit approval for the campaign prompt and target size before creating the credit-bearing job. Merely receiving this detector report is not approval.
Slack is an opt-in output channel for saved monitors, not part of discovery or PR judgment. The setup skill owns the user's choice; this skill owns the short Slack-ready wording; the CLI alone owns the webhook and HTTP request.
After the canonical run.md is complete:
newsjack help monitor delivery. If the command is unavailable, keep the report successful and skip delivery. If a delivery file exists from a newer CLI, mention that updating Newsjack is required; never read that file yourself.slack.md. Do not attempt Slack for Limited Mode, Quick Run, fixtures, or a direct profile that is not an installed monitor.slack.md from the same final, freshness-gated facts used in run.md. Keep it compact and use Slack's text formatting: wrap bold text in *asterisks* and write links as <URL|label>. Include a bold monitor/client heading; the N pitch-ready · M big stories · K watched line; then at most three pitch-ready opportunities with a one-line angle, source link, and build-a-media-list link. When there are no pitch-ready opportunities under the every-completed-report policy, include up to three big-story/context headlines and label them awareness-only. End with the local run.md path so the full provenance is easy to find.slack.md public-safe. Never include the webhook, credentials, embargoed facts, private customer data, internal notes, raw JSON, or worker reasoning. Do not open, print, log, or parse the delivery credentials file.slack.md path and the run-folder name as the stable run ID. The CLI refuses redirects. After Slack accepts the post, the CLI saves a local “sent” marker; when that marker exists, a normal rerun skips the same run. Use the advertised resend override only when the user explicitly asks to resend it.run.md and slack.md, do not retry automatically, and report the failure without exposing the webhook. If Slack may have accepted the post but the response was lost, or Slack accepted it but the local sent marker could not be saved, the outcome is ambiguous. Slack does not accept a request key that would let it discard a duplicate automatically, so check the channel before any manual resend.The delivery authorization comes from the user's saved setup policy. Do not prompt again on each scheduled run, and never configure Slack or send a test message from this skill.
For recurring scheduled output, a signal is not surfaceable until its Go-computed freshness_gate.computed_status is verified. News-search published_at values are good article-publication evidence for recovering originals, but they alone never decide same-story status or first publication — that is the story-origin-check atom's job.
Recurring output rules:
fresh or fresh_new_development. Reject stale and every unverified_* status. The unverified statuses are distinct on purpose: unverified_no_corroboration (worker cited <2 independent sources — a pipeline miss, often re-runnable), unverified_boundary (date-only clock straddling the cutoff), unverified_no_timestamp (no clock recovered). Report them separately so worker-quality misses are not mistaken for genuinely old stories.--demote-unmatched-x so unmatched X News/Trends clusters fall below the queue floor unless the large-story recall guard lifts them. X News surfaces for review by default; recurring precision wants it demoted unless it is a genuinely large story.--drop-stale so syndicated duplicates and clearly-old low-value items never burn story-origin retrieval.story_origin.canonical_coverage_url as the report's main link — the major/most authoritative same-story coverage, not the random pickup that triggered retrieval.origin-apply attaches story_origin and the deterministic freshness_gate to selected and rejected signals. If the first-public timestamp can't be verified, write first_public_at: null and explain the gap; origin-apply computes the appropriate unverified_* status.
reactive-commentangle-generatorjournalist-fit-checkmeanest-editorfind-journalists for an agent-driven job with explicit credit approvalBefore reporting a Full Mode run complete:
coarse_relevance_decisions.json has exactly one decision per emitted candidate (unless --allow-missing).clustered_candidates.json was produced by cluster; story-origin ran on its representatives, and the run disclosed how many duplicates/stale items were collapsed.origin_findings.json has exactly one finding per clustered representative (unless --allow-missing) — count validated, gaps re-run.targeted_candidates.json was produced by origin-apply; triaged_candidates.json was produced by newsjack-triage with a tier per signal; pitch_ready went to angle-generator in pitch mode and big_story in exploratory mode.high/major story was routed to watch — every fresh big story appears in 🔥 Big Stories Worth a Look (or ✅ Pitch-Ready if it earned standing). A brief never-pitch rule may move a big story out of pitch-ready, but it stays a surfaced big_story (off_policy: true), never dropped.pitch_ready, any collapsed section shows a disclosed count + reason, and feedback this turn that changes policy was offered as a brief.md edit.final_report.md is the 3-bucket scan (✅ Pitch-Ready / 🔥 Big Stories Worth a Look / 👀 Watch / Context), written from targeted_candidates.json / triaged_candidates.json, not raw candidates.json.run.md was skill-rendered from the gated/fresh/triaged artifacts after final_report.md existed — never from raw candidates.json alone.run.md existed. If configured, the saved policy was honored, slack.md contained only final public-safe facts, and the CLI delivery result was recorded. Missing support in an older CLI or a delivery failure did not invalidate the report.pitch_ready opportunity has one correctly URL-encoded, public-safe, approval-gated Medialyst media-list link; no big_story or watch item has one.run.md path, the coarse-pass engine (jev, low-cost worker, or current-model fallback) and the cost-optimized-vs-fallback status, whether every surfaced signal has verified ≤24h first-public freshness, top findings, and Slack delivery status when configured.Return exactly this JSON object. No prose before or after it. Every opportunity must include source URLs in evidence_used — story_origin.canonical_coverage_url first when present, then the original/source URL and other support (usually 1–3 links across news, RSS, and X).
Include media_list_handoff only when verdict is pitch_now or pitch_ready. Omit the field for big_story, watch, and every other verdict. The example below shows the pitch-ready shape.
{
"opportunities": [
{
"signal_id": "engine signal id",
"signal_title": "Observed public signal",
"verdict": "pitch_now",
"decay": {
"stage": "4hr",
"rationale": "Why this clock applies"
},
"story_size": {
"band": "low | moderate | high | major",
"score": 0,
"rationale": "How publication traffic/domain authority and coverage spread should affect effort priority"
},
"first_publication": {
"status": "fresh | fresh_new_development",
"first_public_at": "ISO timestamp or YYYY-MM-DD",
"original_url": "https://...",
"canonical_coverage_url": "https://... or null",
"canonical_coverage_source": "Outlet/source name or null",
"rationale": "Why this first-public clock controls"
},
"why_newsjacking_worthy": "Specific reason this is timely and not generic trend-chasing.",
"client_standing": {
"assessment": "strong | partial | weak",
"rationale": "What gives the client standing, or what is missing"
},
"journalist_shape": {
"beat_description": "Specific reporter shape, not a name",
"why_they_care_now": "Why this beat plausibly cares now",
"do_not_target": "Who should not receive this"
},
"evidence_used": [
{
"source": "news_search",
"title": "Evidence title",
"url": "https://...",
"published_at": "YYYY-MM-DD"
}
],
"media_list_handoff": {
"provider": "Medialyst",
"mode": "approval_gated_deep_link",
"prompt": "Public-safe campaign brief, maximum 2,000 characters",
"url": "https://medialyst.ai/app/_/workflow/campaign?prompt=URL-ENCODED-PROMPT",
"credit_note": "No credits are spent until the user reviews and approves the plan in Medialyst."
},
"next_skill": "angle-generator"
}
],
"rejected_signals": [
{
"signal_id": "engine signal id",
"signal_title": "Rejected public signal",
"reason": "no_client_standing",
"first_publication": {
"status": "stale | unverified_no_corroboration | unverified_boundary | unverified_no_timestamp | null",
"first_public_at": "ISO timestamp, YYYY-MM-DD, or null",
"original_url": "https://... or null",
"canonical_coverage_url": "https://... or null"
}
}
],
"brand_safety_blocks": [
{
"signal_id": "engine signal id",
"signal_title": "Blocked public signal",
"reason": "tragedy_or_human_suffering"
}
],
"monitor_notes": [
"Operational note or missing source, if relevant"
]
}pitch_now, develop_angle, monitor, reject.stale, freshness_unverified (umbrella; or the specific unverified_no_corroboration / unverified_boundary / unverified_no_timestamp), single_source, no_client_standing, no_journalist_shape, off_beat, already_seen, weak_signal, no_viable_angle.tragedy_or_human_suffering, client_exclusion, regulated_claim_risk, fabrication_risk.Use this rubric after the engine returns queued evidence. The engine exposes mechanical scores and routing.queue_priority; neither is a PR judgment.
The engine has two discovery lanes:
profile_relevance - profile/topic/competitor queries. These catch highly relevant but sometimes minor stories.major_news - curated RSS/Atom feed items. These catch broader major news first, then require a stricter client-relevance judgment.Do not treat a major_news item as pitchable because it is big. The client still needs standing and a journalist shape.
Use story_size to calibrate effort, not to approve a pitch. It is a deterministic media-attention proxy based on news-search publication metadata:
When authority metadata is missing for a recognized major outlet, the engine may use a low-confidence known-outlet fallback. When publication metadata is otherwise sparse, it may attach story_size.attention_hint. Treat the hint as a low-confidence keep-alive signal: it can justify review in the big-stories section, but it does not prove the story is widely covered. Label the uncertainty plainly.
major or high story size, or a high/major attention hint, means the opportunity may justify faster review. It does not compensate for stale timing, weak standing, or a bad journalist shape.
For recurring scheduled output, the LLM story-origin-check recovers the first-public timestamp and canonical coverage, then the Go CLI origin-apply computes the freshness gate. News-search published_at values are reliable evidence for article timestamps and should be used to find candidate originals, but they are not alone a same-story or first-publication judgment.
Before assigning pitch_now, develop_angle, or monitor, inspect freshness_gate.computed_status:
fresh - eligible for normal judgment.fresh_new_development - eligible, but the angle must be about the new development, not the older background story.stale - reject as stale.unverified_no_corroboration, unverified_boundary, unverified_no_timestamp, or missing - reject for recurring scheduled output. Track the reason: unverified_no_corroboration is a worker/pipeline miss (the clock may be fine, just under-sourced — re-runnable), while unverified_boundary/unverified_no_timestamp reflect genuinely thin evidence.Do not reset the clock because an aggregator, syndication partner, or secondary outlet republished an older article.
When citing the story, prefer story_origin.canonical_coverage_url when present. It should be the major or most authoritative same-story coverage, such as a primary source, wire, major publisher, or recognized trade, instead of the small pickup that triggered retrieval.
Use only when all are true:
30min, 4hr, or 24hr.news_search.Use when the signal is real but needs framing:
Handoff: angle-generator.
Use when the signal is interesting but not pitch-ready:
Use when any core gate fails:
Decay uses the verified first-public timestamp from story-origin-check. Engine features.decay_bucket is provisional when evidence comes from aggregators, syndication partners, secondary rewrites, or search results that have not yet been matched to the original/canonical story.
30min - live/breaking. Only use for immediate comment if the client can respond now.4hr - same-cycle. Good for reactive comment.24hr - still fresh. Good for angle generation or same-day response.week - trend/context only. Do not call it breaking.month - usually not a newsjack unless paired with a new data point or fresh hook.unknown - do not pitch as timely without independent timestamp verification.Strong standing:
Partial standing:
Weak standing:
For major_news lane signals, standing must explain the bridge from the public story to the client:
If the bridge is "this is about AI and the client uses AI," reject or monitor.
A useful journalist shape names:
Bad shapes:
Good shapes:
Block signals built on:
The only acceptable work around these topics is restrained expert commentary with direct public-interest standing. Promotional hooks are refused.
Engine signal:
{
"id": "s1",
"title": "FTC opens inquiry into AI compliance claims",
"sources": ["news_search", "x"],
"features": {
"decay_bucket": "4hr",
"source_count": 2,
"seen_before": false,
"profile_matches": ["AI compliance", "enterprise governance"],
"safety_flags": []
},
"routing": {
"lane": "profile_relevance",
"queue_priority": 86.2,
"demoted": false
},
"mechanical_scores": {
"freshness": 1.0,
"source_agreement": 0.78,
"novelty": 1.0,
"profile_match": 0.44,
"source_quality": 0.825,
"momentum": 0.21,
"major_news": 0.0
}
}Skill output:
{
"signal_id": "s1",
"signal_title": "FTC opens inquiry into AI compliance claims",
"verdict": "pitch_now",
"decay": {
"stage": "4hr",
"rationale": "The signal is same-cycle by verified first-public clock, not just the search-result timestamp."
},
"first_publication": {
"status": "fresh",
"surfaced_article_published_at": "2026-05-25T13:14:00Z",
"first_public_at": "2026-05-25T13:10:00Z",
"original_url": "https://www.ftc.gov/news-events/news/press-releases/example",
"canonical_coverage_url": "https://www.reuters.com/legal/government/ftc-opens-inquiry-ai-compliance-claims-2026-05-25/",
"canonical_coverage_source": "Reuters",
"rationale": "The official FTC press release is the earliest verified public source and is inside the 24-hour cron window."
},
"why_newsjacking_worthy": "Regulator action creates a live need for explainers on AI compliance claims.",
"client_standing": {
"assessment": "strong",
"rationale": "The client works directly in enterprise AI governance and can explain claim substantiation."
},
"journalist_shape": {
"beat_description": "Enterprise AI reporter covering compliance and regulator scrutiny",
"why_they_care_now": "They need sourced reaction while the inquiry is fresh.",
"do_not_target": "General startup roundups or consumer AI reviewers"
},
"evidence_used": [
{
"source": "Reuters",
"title": "FTC opens inquiry into AI compliance claims",
"url": "https://www.reuters.com/legal/government/ftc-opens-inquiry-ai-compliance-claims-2026-05-25/"
},
{
"source": "FTC",
"title": "FTC opens inquiry into AI compliance claims",
"url": "https://www.ftc.gov/news-events/news/press-releases/example"
}
],
"media_list_handoff": {
"provider": "Medialyst",
"mode": "approval_gated_deep_link",
"prompt": "Find enterprise AI reporters covering compliance and regulator scrutiny for outside expert reaction to the FTC inquiry. The client works directly in enterprise AI governance. Exclude consumer AI reviewers and general startup roundups. Source of record: https://www.reuters.com/legal/government/ftc-opens-inquiry-ai-compliance-claims-2026-05-25/",
"url": "https://medialyst.ai/app/_/workflow/campaign?prompt=Find%20enterprise%20AI%20reporters%20covering%20compliance%20and%20regulator%20scrutiny%20for%20outside%20expert%20reaction%20to%20the%20FTC%20inquiry.%20The%20client%20works%20directly%20in%20enterprise%20AI%20governance.%20Exclude%20consumer%20AI%20reviewers%20and%20general%20startup%20roundups.%20Source%20of%20record%3A%20https%3A%2F%2Fwww.reuters.com%2Flegal%2Fgovernment%2Fftc-opens-inquiry-ai-compliance-claims-2026-05-25%2F",
"credit_note": "No credits are spent until the user reviews and approves the plan in Medialyst."
},
"next_skill": "reactive-comment"
}Engine signal: AOL article published today, canonical URL points to a BBC story from May 4 with no new development.
Verdict: reject
Reason: stale
first_publication.status: stale
© elvisun, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 3 other files (references) in skills/newsjack-detector of elvisun/newsjack.
Open the folder on GitHubat commit b5a8dc8
Newsjack Detector next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Newsjack Detector this skillelvisun/newsjack | 1.5k | — | ~13k | Automated safety check: Pass | MIT | |
| Competitor News MonitorNousResearch/hermes-agent | 252k | — | ~1.2k | Automated safety check: Pass | MIT | |
| Signal Detectorgarrytan/gbrain | 31k | — | ~2k | Automated safety check: Pass | MIT | |
| SignalsPostHog/posthog | 40k | — | ~4.3k | Automated safety check: Pass | Custom licence | |
| Decidealirezarezvani/claude-skills | 28k | — | ~871 | Automated safety check: Pass | MIT | |
| News Signal Outreachgooseworks-ai/goose-skills | 1.2k | 1 repos | ~8.1k | Automated safety check: Pass | MIT |
NousResearch/hermes-agent
Watch named companies for material news; cited digests. An agent skill from NousResearch/hermes-agent.
garrytan/gbrain
Opt-in ambient signal capture. An agent skill from garrytan/gbrain.
PostHog/posthog
How to query the documentembeddings table for raw signal data using HogQL.
alirezarezvani/claude-skills
/cs:decide <memo — Log a decision to two-layer memory via decision-logger.
gooseworks-ai/goose-skills
End-to-end news-triggered signal composite. An agent skill from gooseworks-ai/goose-skills.
github/awesome-copilot
Guides Qdrant monitoring and observability setup. An agent skill from github/awesome-copilot.
elvisun/newsjack
Turn an eval study's numbers into on-brand, publish-ready figures using the Newsjack chart room (the eval design system), then validate them with Playwright.
elvisun/newsjack
Audit, question, suggest, or fact-preservingly revise a press release, blog post, contributed article, or expert explainer so AI answer systems can more easily retrieve, understand, quote, and cite…
elvisun/newsjack
Turn a source-bound company and market dossier into testable ideal-customer-profile hypotheses, buying roles, triggers, constraints, disqualifiers, standing, counterevidence, and research gaps.
elvisun/newsjack
Research any company, product, or service from a URL plus description and build a comprehensive, evidence-bound AEO/GEO/AI-visibility prompt panel across buyer jobs, information acts, journey…
elvisun/newsjack
Triage inbound journalist source queries and draft a response only when the user's expertise is a real fit.
elvisun/newsjack
Recover source-bound buyer jobs, struggling moments, desired progress, forces, workarounds, information acts, journey states, criteria, constraints, roles, locales, and authentic language.
Monitor current news and reaction signals, then decide which are credible newsjacking opportunities for a client. Newsjack Detector is an agent skill from elvisun/newsjack. Monitor current news and reaction signals, then decide which are credible newsjacking opportunities for a client.
Run `npx skills add elvisun/newsjack --skill newsjack-detector -a claude-code`. Or copy the skill folder (skills/newsjack-detector in elvisun/newsjack) into .claude/skills/newsjack-detector in your project. Claude Code loads it when a task matches its description.
Run `npx skills add elvisun/newsjack --skill newsjack-detector -a codex`. Or copy the skill folder (skills/newsjack-detector in elvisun/newsjack) into .agents/skills/newsjack-detector in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add elvisun/newsjack --skill newsjack-detector -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/newsjack-detector, .gemini/skills/newsjack-detector, .github/skills/newsjack-detector and .opencode/skills/newsjack-detector in your project.
SKILL.md names no scripts, command-line tools or credentials: Newsjack Detector is instructions for the agent only.
SKILL.md names 3 domains. In commands or code: medialyst.ai, reuters.com and ftc.gov; the agent is likely to contact these when it follows the instructions. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Newsjack Detector is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 13k tokens (SKILL.md is roughly 50k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 3k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Newsjack Detector: Competitor News Monitor (NousResearch/hermes-agent, 252k stars), Signal Detector (garrytan/gbrain, 31k stars), Signals (PostHog/posthog, 40k stars) and Decide (alirezarezvani/claude-skills, 28k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
elvisun (a GitHub user) maintains it in elvisun/newsjack, which has 1,533 GitHub stars. The repository holds 30 skills in this directory. The repository was last updated on October 7, 2026.
Source: elvisun/newsjack on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.