newsjack-detector

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Newsjack Detector

Newsjack Detector

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.
及时发现公开信号,判断客户是否有可信、非垃圾营销式的理由利用这些信号。监测引擎负责收集证据并计算机械信号;PR判断由你完成
这是一个分子级Skill——它负责编排原子级Skill而非重新实现它们。粗粒度相关性判断交由
relevance-coarse-filter
,故事溯源交由
story-origin-check
,角度适配交由
angle-generator
,临时新闻查询交由
news-search
,任务移交则交由
reactive-comment
/
journalist-fit-check
/
meanest-editor
。请勿在此处重复原子级Skill的逻辑或提示;执行任务的Worker会直接加载对应原子级Skill的
SKILL.md
,因此原子级Skill始终是唯一的事实来源。
监测引擎的实时
news_search
数据源需要Medialyst密钥;若无密钥,将基于RSS/X及主机驱动的
news-search
运行并优雅降级。请将缺失Medialyst密钥视为覆盖范围受限,而非运行失败——切勿停滞任务或首先抱怨密钥缺失。

Runtime Mode

运行模式

Newsjack Detector has two runtime modes:
  • Full Mode: Use this in Claude Code, Codex, OpenClaw, Hermes, or another capable agent harness with shell, filesystem, network, and local CLI access. Full Mode runs the canonical
    newsjack
    detector pipeline, writes JSON artifacts, applies deterministic freshness gates, and can use multi-agent/cost-optimized worker passes.
  • Limited Mode: Use this in Claude.ai chat, ChatGPT chat, Claude Cowork, or any restricted runtime without shell/filesystem/CLI access. Do not attempt
    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:
  1. Run
    newsjack --version
    . If it prints a version, you're in Full Mode — use plain
    newsjack ...
    for every command.
  2. If
    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.
  3. Only if both fail (and you genuinely have no shell) are you in Limited Mode.
The bundled binary is almost always already installed — assume Full Mode and verify, don't assume it's missing.
Newsjack Detector有两种运行模式:
  • 完整模式: 适用于Claude Code、Codex、OpenClaw、Hermes或其他具备Shell、文件系统、网络及本地CLI访问能力的Agent框架。完整模式运行标准
    newsjack
    检测器流水线,生成JSON工件,应用确定性新鲜度校验,还可使用多Agent/成本优化的Worker执行任务。
  • 受限模式: 适用于Claude.ai聊天、ChatGPT聊天、Claude Cowork或任何无Shell/文件系统/CLI访问权限的受限运行环境。请勿尝试
    curl
    npm
    或按需CLI安装。运行下方的受限模式扫描并标注输出为覆盖范围受限。
在判定为受限模式前,请先检查
newsjack
是否已安装
。它以预构建的捆绑二进制文件形式发布——你无需Go语言、编译器或任何构建/安装步骤即可运行。切勿寻找Go工具链,也切勿在未执行以下检查的情况下就宣称CLI“缺失”或告知用户需要“Go环境”:
  1. 运行
    newsjack --version
    。若输出版本信息,则处于完整模式——所有命令均使用
    newsjack ...
    格式。
  2. newsjack
    不在
    PATH
    中,尝试捆绑路径
    ~/.newsjack/bin/newsjack --version
    。若输出版本信息,则在下方所有命令中使用该完整路径替代
    newsjack
  3. 仅当两者均失败(且确实无Shell权限)时,才判定为受限模式。
捆绑二进制文件几乎已预先安装——默认假设处于完整模式并进行验证,而非默认假设缺失。

Required Workflow (follow in order)

必选工作流(按顺序执行)

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.
  1. 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.
  2. 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.
    • No profile and no usable client context → ask for it before running. Never invent profile facts.
    • Genuinely ambiguous (which client? which topic? one-off vs recurring?) → ask one clarifying question, then proceed. Otherwise do not stall the run.
    • Missing standing is not a blocker: monitor, but mark opportunities
      weak
      /
      no-standing
      .
    • Load the client brief. Read the monitor's
      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.
  3. PICK THE RUN SHAPE.
    • Restricted chat / no CLI / no filesystem → Limited Mode Scan below.
    • One-off / "what's moving on X" → Quick Run below.
    • Real judgment, agent run, or scheduled job → Canonical Pipeline below (the default for any output a human or pitch will rely on).
    • Recurring / cron feed monitoring → Canonical Pipeline plus the recurring rules in Freshness Gate (
      --feed-only --new-only --max-age-hours 24
      , hard freshness gate).
  4. 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.
  5. 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
    .
  6. VERIFY & CONCLUDE. In Full Mode, run the Completion Checklist, then report: the
    run.md
    path, whether coarse passes were cost-optimized or fallback, whether every surfaced signal has verified ≤24h first-public freshness, and top findings. In Limited Mode, state that no local artifacts, saved monitor state, or deterministic freshness gate were available.
完整模式默认操作:运行标准流水线并返回报告。本Skill的存在目的是生成经过新鲜度校验的Newsjacking报告,包括定时/ cron任务运行场景。默认执行流水线——仅当步骤2受阻时才进入讨论/规划环节。受限模式下,运行已披露的覆盖范围受限扫描。
  1. 检查准则。若存在
    skills/ETHICS.md
    skills/WHY-NOT-SPAM.md
    ,请遵循其中规定。本Skill拒绝利用悲剧事件、虚构立场、虚假紧迫感及广撒网式输出。这些限制是绝对的,且优先于后续所有步骤。
  2. 锚定客户——仅在受阻时才询问。从配置文件JSON或纯文本上下文识别公司、主题、竞争对手、发言人、立场及客户专属排除项。
    • 无配置文件无可用客户上下文 → 运行前先询问相关信息。切勿虚构配置文件内容。
    • 存在明确歧义(哪个客户?哪个主题?一次性任务还是周期性任务?) → 提出一个澄清问题后再继续。否则请勿停滞任务。
    • 缺失立场并非阻碍:继续监测,但将机会标记为
      weak
      /
      no-standing
    • 加载客户简报。读取监测器的
      brief.md
      (其路径由
      monitor run
      /
      monitor status
      显示,或位于配置文件旁)。它是客户可投送内容及扫描呈现方式的事实来源——详见下方客户简报部分。空/模板简报无规则约束。
  3. 选择运行形态
    • 受限聊天 / 无CLI / 无文件系统 → 运行下方的受限模式扫描
    • 一次性任务 / “X主题的动态是什么” → 运行下方的快速运行
    • 真实判断、Agent运行或定时任务 → 运行下方的标准流水线(任何供人类或投送使用的输出均默认采用此方式)。
    • 周期性 / cron feed监测 → 标准流水线加上新鲜度校验中的周期性规则(
      --feed-only --new-only --max-age-hours 24
      ,强制新鲜度校验)。
  4. 运行流水线。完整执行所选路径。完整模式下,除快速运行外,切勿跳过故事溯源/新鲜度校验步骤。
  5. 判断——切勿将机械结果视为投送许可
    routing.queue_priority
    story_size
    是召回压力指标,而非投送许可。由你决定Newsjacking价值、客户立场、记者画像及品牌安全(详见引擎与Skill边界及下方评分准则部分)。通过
    angle-generator
    校验角度适配性。
  6. 验证与总结。完整模式下,运行完成检查清单,然后报告:
    run.md
    路径、粗粒度任务是否采用成本优化或降级方案、所有显示的信号是否均已验证为首次发布≤24小时,以及核心发现。受限模式下,说明无本地工件、保存的监测状态或确定性新鲜度校验可用。

Engine vs Skill Boundary

引擎与Skill边界

The Go CLI owns (mechanical, deterministic):
  • ingestion, dedupe, clustering, novelty tracking
  • mechanical scores only: freshness, source agreement, novelty, profile match, source quality, momentum, major-news weight
  • deterministic story-size scoring from news-search metadata: log-scaled estimated monthly traffic + domain authority, with coverage spread across independently surfaced domains. 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, the engine may attach a low-confidence
    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.
  • deterministic hygiene filtering for docs/help/product/SEO pages
  • coarse-relevance application via
    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 term
  • deterministic freshness gating via
    newsjack origin-apply
  • operational routing: lane, queue priority, threshold-demotion flag
  • deterministic safety flags
You own (PR judgment):
  • whether the signal is newsjacking-worthy and whether the client has standing
  • same-story / original-coverage judgment (via
    story-origin-check
    )
  • final decay explanation from
    freshness_gate
  • journalist shape, brand-safety judgment, and handoff to the next skill
Never treat
routing.queue_priority
as permission to pitch — it is only operational queue order.
Go CLI负责(机械、确定性):
  • 数据摄取、去重、聚类、新颖性追踪
  • 仅机械评分:新鲜度、来源一致性、新颖性、配置匹配度、来源质量、传播势头、重大新闻权重
  • 基于新闻搜索元数据的确定性故事规模评分:对数缩放的预估月流量 + 域名权重,覆盖独立显示的域名。若知名主流媒体的权重元数据缺失,引擎可能采用低置信度的已知媒体降级方案。若发布元数据稀疏,引擎可能通过确定性来源信号(如X News集群、重要公众人物、高风险事件术语)附加低置信度的
    story_size.attention_hint
    ;这是召回压力指标,而非规模证明。
  • 针对文档/帮助/产品/SEO页面的确定性合规过滤
  • 通过
    newsjack filter-apply
    应用粗粒度相关性,外加两个召回保障:重大故事保障将任何
    high
    /
    major
    story_size
    信号的
    reject
    判定升级为
    monitor_only
    (低成本任务环节绝不能直接丢弃重大故事);配置匹配保障当检测器/配置证据已匹配客户、竞争对手或配置术语时,将
    reject/no_profile_bridge
    判定升级为
    monitor_only
  • 通过
    newsjack origin-apply
    应用确定性新鲜度校验
  • 操作路由:通道、队列优先级、阈值降级标记
  • 确定性安全标记
你负责(PR判断):
  • 信号是否具备Newsjacking价值,以及客户是否具备立场
  • 同故事/原始报道判断(通过
    story-origin-check
  • 基于
    freshness_gate
    的最终时效性衰减解释
  • 记者画像、品牌安全判断及移交至下一个Skill
切勿将
routing.queue_priority
视为投送许可——它仅代表操作队列顺序。

Client Brief

客户简报

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.
  • Where it binds: triage and report rendering — never collection. Keep retrieval and the coarse pass brief-agnostic so nothing is dropped before judgment; the brief only decides what an already-collected, already-fresh item is allowed to be and how it's shown.
  • Never pitch rules are hard: an item matching one can never be
    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.
  • Audience / We pitch set the standing altitude: topical overlap is not pitchability. A story can be on-topic and still off-brief.
  • How to surface is presentation only: collapse a section to a disclosed count, never silence it. Disclose what the brief held back (count + reason) so nothing is hidden.
  • Feedback updates the brief. When the user reacts to a run — "too policy-heavy," "stop showing me X," "this is exactly right" — propose an edit to
    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.
每个监测器可能附带
brief.md
——一份由用户编写的散文式声明,说明客户可投送及不可投送的内容,以及扫描结果的呈现方式。它是客户投送/输出政策的事实来源;配置文件JSON管控数据收集,简报管控可投送内容及展示方式。CLI仅负责创建和显示该文件(
monitor init
初始化它;
brief_path
monitor run
/
monitor status
报告);从不解析它——读取并应用简报是你的职责。
  • 约束范围: 分类和报告呈现——从不涉及数据收集。保持检索和粗粒度任务环节与简报无关,以便在判断前不丢弃任何内容;简报仅决定已收集、已验证为新鲜的内容可被定义为什么以及如何展示
  • 不可投送规则是硬性约束:匹配规则的内容绝不能标记为
    pitch_ready
    。非重大内容降级为
    watch
    client_policy_exclusion
    );新鲜的
    high
    /
    major
    级内容仍标记为
    big_story
    并附带
    off_policy: true
    (绝不丢弃原则仍适用——显示内容,而非隐藏)。
    newsjack-triage
    强制执行此规则。
  • 受众 / 我们投送定义立场高度:主题重叠不等于可投送性。故事可能符合主题但不符合简报要求。
  • 展示方式仅涉及呈现:将某部分折叠为已披露的计数,切勿静默隐藏。披露简报限制的内容(计数+原因),确保无内容被隐藏。
  • 反馈更新简报。当用户对运行结果做出反应——“政策限制过严”、“停止向我展示X”、“这完全符合要求”——建议编辑
    brief.md
    (新增一条我们从不投送规则、一条展示方式说明,或一个带日期的示例),以便持久化记录政策,而非仅适用于本次运行。确认编辑内容。空/模板简报意味着使用默认规则运行。

Profile Setup File

配置文件

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.
  • Installed monitors keep the setup file at
    ~/.newsjack/monitors/<slug>/profile.json
    ;
    brief.md
    sits next to it.
  • Direct detector runs use the file passed with
    --profile
    .
  • Fixture profiles live under
    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.
监测器配置文件JSON是数据收集设置的事实来源:包含一组聚焦的简短核心主题、搜索词、竞争对手、Feed、立场、发言人和排除项。优先选择6-8个2-3词的核心主题,自然情况下允许使用单字主题。若用户希望更改监测器的监测范围,编辑配置文件JSON而非在检测器运行期间生成一次性检索词。
  • 已安装的监测器将配置文件保存在
    ~/.newsjack/monitors/<slug>/profile.json
    brief.md
    位于其旁。
  • 直接运行检测器时使用
    --profile
    参数指定的文件。
  • 示例配置文件位于
    fixtures/newsjack-detector-agent/profile.<slug>.json
当用户希望创建或大幅修改配置文件时,使用
newsjack-monitor-setup
。诸如“扩大会计师事务所新闻监测范围”的收集反馈应放入
profile.json
topics
/
search_terms
/
feed_urls
字段:将6-8个核心广泛主题放入
topics
,将广泛检索词及指定平台/产品/监管机构/竞争对手放入
search_terms
。诸如“不投送政策类故事”的投送政策反馈应放入
brief.md
。编辑
profile.json
后,在信任下一次实时运行前,先运行模拟或示例测试。

Limited Mode Scan

受限模式扫描

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.
  1. Anchor the client. Use a pasted profile, user context, website summary, or plain-text description. If there is no usable client context, ask for it.
  2. Collect a small evidence set. Use pasted links first. If the runtime has web/search tools, search recent news for the profile topics, competitors, named regulators/platforms, and any explicit user topic. Keep the query list short and disclose it.
  3. Build candidates manually. For each candidate, keep title, source, URL, apparent publication time, why it matched the client, and any safety concerns. Do not invent publication dates, outlet names, source counts, or traffic/authority scores.
  4. Verify freshness where possible. Prefer primary/source-of-record pages and independent coverage. Treat unverified dates as
    freshness_unverified
    ; do not pitch them as time-sensitive.
  5. Apply PR judgment. Use this skill's doctrine,
    story-origin-check
    reasoning where possible,
    newsjack-triage
    for standing/routing, and
    angle-generator
    for any pitchable item.
  6. Return an inline report. Use the same sections as Full Mode:
    Pitch-Ready
    ,
    Big Stories Worth a Look
    ,
    Watch / Context
    , plus a short
    Limited Mode Caveat
    that names missing capabilities and searches/evidence used.
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.
适用于Claude.ai聊天、ChatGPT聊天、Claude Cowork或任何无Shell/文件系统/CLI访问权限的运行环境。
受限模式适用于PR判断,而非标准监测。它不创建保存的监测器、不生成JSON工件、不保留已查看状态、不运行数据源摄取、不应用Go新鲜度校验、不使用成本优化的Worker任务。
  1. 锚定客户。使用粘贴的配置文件、用户上下文、网站摘要或纯文本描述。若无可用客户上下文,询问相关信息。
  2. 收集小型证据集。优先使用粘贴的链接。若运行环境具备网络/搜索工具,搜索配置文件主题、竞争对手、指定监管机构/平台及任何用户明确提及的主题的近期新闻。保持查询列表简短并披露查询内容。
  3. 手动构建候选内容。每个候选内容需包含标题、来源、URL、显示发布时间、与客户匹配的原因及任何安全顾虑。切勿编造发布日期、媒体名称、来源数量或流量/权重评分。
  4. 尽可能验证新鲜度。优先选择主要/权威来源页面及独立报道。将未验证日期标记为
    freshness_unverified
    ;切勿将其作为时效性内容投送。
  5. 应用PR判断。使用本Skill的准则、尽可能采用
    story-origin-check
    的推理逻辑、
    newsjack-triage
    进行立场/路由判断,以及
    angle-generator
    处理可投送内容。
  6. 返回内嵌报告。使用与完整模式相同的章节:
    可投送
    值得关注的重大故事
    监测/背景
    ,外加简短的受限模式说明,列出缺失的功能及使用的搜索/证据。
切勿称其为标准检测器运行。若用户需要保存的监测器、定时扫描、确定性新鲜度校验、本地工件或周期性已查看状态,建议在Claude Code、Codex、OpenClaw或Hermes中使用完整模式。

Quick Run

快速运行

One-off discovery and scans:
bash
newsjack detector run --profile profile.json --save
The 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.
一次性发现与扫描:
bash
newsjack detector run --profile profile.json --save
检测器仅输出JSON;需自行根据工件事实生成供人类查看的扫描结果。仅当用户明确要求添加一次性检索主题时,才使用
--topic "用户明确主题"
参数。常规配置运行应依赖配置文件中持久化的
topics
search_terms
,而非临时生成的检索词。使用
--mock
参数进行无需凭证的本地验证。完整的参数/来源/环境参考:
references/engine-cli.md
对于每个排队的信号,检查标题、来源、证据URL、时长、
routing.lane
mechanical_scores
major_news
novelty
source_agreement
)、配置匹配项及安全标记。对于X平台证据,检查
x_signal_type
x_social_signals
x_author_followers
x_query_counts
;将单个低影响力帖子视为噪声。高
major_news
评分意味着故事具有广泛重要性,代表客户具备立场。将引擎的时长/衰减视为临时结果,直到
story-origin-check
验证首次发布时间。然后应用下方的评分准则部分及输出格式

Canonical Pipeline

标准流水线

The artifact contract is the source of truth. Write all artifacts to a timestamped run folder:
text
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
  detector.stderr.log  commands.log  summary.json
Only
run.md
is human-facing; the rest are provenance.
  1. 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:
    bash
    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.json
    The 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.
  2. 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. For model/worker routing and chunking, see
    references/harness-routing.md
    .
  3. Apply coarse decisions:
    bash
    newsjack filter-apply --candidates candidates.json --decisions coarse_relevance_decisions.json --include keep --include monitor_only --output relevant_candidates.json
3b. Cluster same-story signals before the expensive retrieval pass:
bash
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.
  1. 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
    .
  2. Apply the deterministic freshness gate:
    bash
    newsjack origin-apply --candidates clustered_candidates.json --origins origin_findings.json --window-hours 24 --output targeted_candidates.json
    The 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.
  1. 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").
  2. 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, and its link provenance.
    • ## 🔥 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.
    • Link provenance (all sections): One main source = the source of record — the article the detector actually surfaced, real
      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.
    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
    .
  3. 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:
    bash
    newsjack run-summary targeted_candidates.json --output summary.json
    run-summary
    writes JSON metadata only; it does not write Markdown or make editorial decisions.
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.
工件契约是事实来源。将所有工件写入带时间戳的运行文件夹:
text
RUN_DIR/
  candidates.json              # 1. 检测器输出
  coarse_relevance_decisions.json   # 2. 粗粒度任务环节
  relevant_candidates.json     # 3. 过滤应用结果
  clustered_candidates.json    # 3b. 聚类——同故事去重 + 预校验过期内容
  origin_findings.json         # 4. 故事溯源任务环节(仅代表性内容)
  targeted_candidates.json     # 5. 溯源应用结果(新鲜度权威判定)
  triaged_candidates.json      # 5b. Newsjack分类——立场 + 整合
  final_report.md              # 7. 编译后的三分类扫描结果(可投送 / 重大故事 / 监测)
  run.md                       # 8. Skill生成的报告——面向人类的工件
  detector.stderr.log  commands.log  summary.json
run.md
面向人类;其余均为溯源文件。
  1. 运行检测器并保存候选内容。这是标准调用方式——任何供人类或投送使用的运行均需严格使用此命令,确保不同运行具备可比性:
    bash
    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.json
    下限参数
    --min-queue-priority 40
    --min-major-news 0.55
    是引擎默认值;它们定义输出池。真实运行中请勿降低这些参数,也请勿传递
    --include-all-scored
    --no-hygiene-filter
    (仅用于调试)——它们会改变进入报告的信号,导致同一配置的两次运行不可比。配置术语管控持久化检索;除非用户明确要求一次性
    --topic
    ,否则请勿每次运行手动调整查询。周期性/cron任务需添加
    --demote-unmatched-x
    参数(详见新鲜度校验);这是标准命令唯一可添加的参数。
  2. 粗粒度相关性任务环节
    coarse_relevance_decisions.json
    。仅进行高召回率的垃圾内容移除——不进行排名、角度适配、日期判断或投送决策。每个Worker加载
    skills/relevance-coarse-filter/SKILL.md
    并应用于分配的信号;将所有Worker的输出合并到一个
    decisions
    数组中。模型/Worker路由及分块规则详见
    references/harness-routing.md
  3. 应用粗粒度判断结果:
    bash
    newsjack filter-apply --candidates candidates.json --decisions coarse_relevance_decisions.json --include keep --include monitor_only --output relevant_candidates.json
3b. 在昂贵的检索任务环节前聚类同故事信号:
bash
newsjack cluster --candidates relevant_candidates.json --drop-stale --window-hours 24 --output clustered_candidates.json
Go CLI将同一公共事件的联合报道/近乎重复的标题合并为一个代表性内容(共享发现结果,因此15条NVIDIA-GTC相关内容仅需一次故事溯源检索,而非15次),并将其余内容记录在
clustered_duplicates
中。
--drop-stale
参数确定性地将检测器衰减明显超出时间窗口(
week
/
month
)的低规模故事信号预校验为
pre_gated_stale
,使其跳过检索环节;大型故事(
high
/
major
)无论时长如何均需进行研究。仅对
clustered_candidates.json
中的代表性内容运行故事溯源。披露合并的重复内容及过期内容数量。
  1. clustered_candidates.json
    中的代表性内容进行故事溯源任务环节
    origin_findings.json
    。每个Worker加载
    skills/story-origin-check/SKILL.md
    并应用于每个信号:判断是否为同故事或实质性新进展,恢复
    first_public_at
    original_url
    及标准主流报道。必须计算
    fresh
    /
    stale
    ,必须为每个信号返回一个发现结果(绝不跳过),且必须引用**≥2个独立佐证来源**支持新鲜度时间戳。将每个信号的结果合并到一个
    findings
    数组中,以
    signal_id
    为键。验证结果数量与输入是否匹配,重新运行存在缺口的任务。故事溯源任务环节需要检索能力——详见
    references/harness-routing.md
  2. 应用确定性新鲜度校验:
    bash
    newsjack origin-apply --candidates clustered_candidates.json --origins origin_findings.json --window-hours 24 --output targeted_candidates.json
    Go CLI是新鲜度的权威判定者——它根据运行时间戳和截止时间计算
    freshness_gate.computed_status
    。若LLM将5月8日的内容标记为5月25日运行时的新鲜内容,
    origin-apply
    会将其标记为过期。非新鲜信号附带具体原因:
    stale
    unverified_no_corroboration
    (Worker引用<2个独立来源——流水线/Worker质量问题)、
    unverified_boundary
    (仅日期时间戳跨越截止时间)或
    unverified_no_timestamp
    (未恢复时间戳)。在报告和指标中区分这些情况:
    unverified_no_corroboration
    意味着我们未验证,而非故事已过期。
5b.
targeted_candidates.json
中选定的新鲜信号进行立场分类
triaged_candidates.json
。加载
skills/newsjack-triage/SKILL.md
并在存在客户简报时传入:重新整合任何遗漏的同故事代表性内容,应用简报的不可投送规则(不符合政策的内容绝不能标记为
pitch_ready
;新鲜的大型内容仍标记为
big_story
并附带
off_policy: true
,小型内容降级为
watch
/
client_policy_exclusion
),根据简报的受众高度分配
strong
/
partial
/
none
立场并进行记者画像合理性检查,以及将每个故事路由至对应层级
pitch_ready
(强立场,或具备清晰画像的部分立场)、
big_story
(新鲜的
high
/
major
级故事但缺乏立场——绝不丢弃,始终作为建议展示并附带
bridge_note
+
relevance_confidence
)或
watch
(小型/非大型且无立场、偏离主题、重复内容)。这是引擎无法完成的立场校验——它替代临时编排器判断,使决策可审计。仅
watch
层级会隐藏故事,且仅适用于既不可投送也非大型的内容。
  1. triaged_candidates.json
    中已路由的候选内容进行角度生成
    。对
    pitch_ready
    内容以投送模式运行
    angle-generator
    (仅当候选内容能生成≥1个真实、符合记者画像的角度时才具备可投送性;无可行角度则降级为
    big_story
    (若为大型故事)或
    watch
    ),对
    big_story
    内容以探索模式运行(
    context.mode: exploratory
    )(最多生成一个暂定的
    suggestion
    角度;无结果也可,且不会导致故事降级——仍会作为“仅用于了解情况”展示)。
  2. 编译
    final_report.md
    ——三分类扫描结果,以故事为核心且易于浏览。示例中的
    scripts/build_report.py
    是参考实现;Skill负责人类可读报告的形态。开头显示今日概览行(
    N个可投送 · M个重大故事 · K个监测内容
    )及漏斗说明行,声明无任何可投送或大型故事被隐藏。然后分为三个章节,按两个独立维度组织——立场(客户能否采取行动?)和规模(故事影响力多大?):
    • ## ✅ 可投送
      pitch_ready
      层级):每个故事显示新鲜度(同时包含首次发布日期
      fresh_new_development
      的新进展日期)、立场、
      angle-generator
      生成的角度及链接溯源。
    • ## 🔥 值得关注的重大故事
      big_story
      层级):新鲜的
      high
      /
      major
      级故事但无确认立场,仅作为建议展示——章节标题需明确说明(“由你决策,相关性未验证”)。按覆盖范围(独立显示的媒体数量)降序排列,无数量上限。每个故事显示规模标签 + 媒体数量、新鲜度、真实的
      bridge_note
      、置信度标记(包括粗粒度的
      weakness_flag
      → 例如
      ⚠ 可能为关键词匹配
      )、溯源信息,以及最多一个标记为
      suggestion
      的角度(或“无清晰角度——仅用于了解情况”)。这是我们展示大型故事且绝不丢弃的方式;区分真实故事与高权重域名工件的方式是在此处排名和标记,而非在前期丢弃。
    • ## 👀 监测/背景
      watch
      层级(新鲜但无立场、非大型)内容加上新鲜度校验未通过的内容(
      stale
      /
      unverified_*
      ),附带明确原因和日期。大型但过期的内容需标记。
    • 链接溯源(所有章节): 一个主来源 = 权威来源——检测器实际发现的文章,真实
      published_at
      ,来源薄弱时标记(
      ⚠ 单一来源
      ⚠ 权威来源为聚合器
      )。下方显示相关报道:聚类的重复内容(标记为
      已发现重复内容
      )加上Worker提议的任何
      canonical_coverage_url
      /
      original_url
      ,日期标记为未验证并标注
      由研究提议——未验证
      切勿将Worker提议的链接提升为主来源——反洗白规则。每个链接均附带日期。
    链接必须为可点击的Markdown格式,而非反引号包裹或裸URL。切勿将机械排名作为最终适配 verdict。
    在此处遵循客户简报的展示方式要求:若简报要求折叠某部分(例如重大故事/了解情况部分),将其渲染为一行已披露的计数及原因,切勿静默隐藏。优先展示简报要求的内容。明确说明简报将某内容移出
    可投送
    或折叠某部分的情况,并引用规则(
    policy_rule
    )。
    scripts/build_report.py
    是与简报无关的机械参考(
    final_report.md
    );简报要求在Skill生成的
    run.md
    中遵循。
  3. 自行从工件编写
    run.md
    。CLI不生成报告。它仅输出确定性JSON。使用
    final_report.md
    及工件事实在运行文件夹中编写面向人类的
    run.md
    报告必须基于经过校验/新鲜/分类的工件生成,绝不能仅基于原始
    candidates.json
    。切勿在✅/🔥章节中重新显示粗粒度拒绝或硬性安全标记的信号。仅有的硬性丢弃是机械性的(URL模式合规)和硬性安全标记;从JSON工件中披露这些内容的数量,确保无内容被隐藏——绝不静默截断。若需要机器可读的工件索引,运行:
    bash
    newsjack run-summary targeted_candidates.json --output summary.json
    run-summary
    仅输出JSON元数据;不生成Markdown或做出编辑决策。
整个流水线无需任何子Agent API——具备低成本模型/Worker控制能力的框架可使用这些控制,但所有框架均生成相同的工件契约并披露降级方案。

Freshness Gate

新鲜度校验

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:
  • Surface only
    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.
  • Run with
    --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.
  • Cluster (step 3b) before retrieval and prefer
    --drop-stale
    so syndicated duplicates and clearly-old low-value items never burn story-origin retrieval.
  • Do not reset the clock for AOL, Yahoo, MSN, Apple News, partner syndication, wire pickup, SEO rewrites, or "published today" pages whose canonical/source story is older.
  • A newer article restarts the clock only if it adds a concrete new public fact: official action, filing, statement, data/report publication, material company update, new local impact, or another independently coverable development.
  • Prefer
    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.
对于周期性定时输出,信号需经Go计算的
freshness_gate.computed_status
验证后才可展示。新闻搜索的
published_at
值是恢复原始内容的可靠文章发布时间证据,但仅凭它无法判断同故事状态或首次发布时间——这是
story-origin-check
原子级Skill的职责。
周期性输出规则:
  • 仅展示
    fresh
    fresh_new_development
    内容。拒绝
    stale
    及所有
    unverified_*
    状态。未验证状态有明确区分:
    unverified_no_corroboration
    (Worker引用<2个独立来源——流水线问题,通常可重新运行)、
    unverified_boundary
    (仅日期时间戳跨越截止时间)、
    unverified_no_timestamp
    (未恢复时间戳)。分别报告这些情况,避免将Worker质量问题误认为故事已过期。
  • 运行时添加
    --demote-unmatched-x
    参数,使未匹配的X News/Trends集群低于队列下限,除非大型故事召回保障将其提升。X News默认展示供审核;周期性精准运行需将其降级,除非它确实是大型故事。
  • 检索前进行聚类(步骤3b)并优先使用
    --drop-stale
    参数,避免联合重复内容及明显过期的低价值内容消耗故事溯源检索资源。
  • 切勿因AOL、Yahoo、MSN、Apple News、合作伙伴联合报道、通讯社转载、SEO改写或“今日发布”页面的标准/来源故事已过期而重置时间戳。
  • 仅当新文章添加了具体的新公开事实时才重置时间戳:官方行动、文件提交、声明、数据/报告发布、实质性公司更新、新的本地影响或其他可独立报道的进展。
  • 优先使用
    story_origin.canonical_coverage_url
    作为报告的主链接——同故事的主流/最权威报道,而非触发检索的随机内容。
origin-apply
story_origin
和确定性
freshness_gate
附加到选定和拒绝的信号。若无法验证首次发布时间戳,写入
first_public_at: null
并说明缺口;
origin-apply
计算对应的
unverified_*
状态。

Handoff

任务移交

  • Breaking / same-day sourced comment →
    reactive-comment
  • Needs story framing →
    angle-generator
  • Named journalist check →
    journalist-fit-check
  • Draft critique →
    meanest-editor
  • 突发/当日来源评论 →
    reactive-comment
  • 需要故事框架 →
    angle-generator
  • 指定记者校验 →
    journalist-fit-check
  • 草稿评审 →
    meanest-editor

Completion Checklist

完成检查清单

Before 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.
  • No fresh
    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.
  • If a client brief is present, the report applied it: off-policy items are out of
    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.
  • The ✅/🔥 sections contain no coarse-rejected or hard-safety-flagged signal; the only hard drops (URL-hygiene + hard-safety) have their counts disclosed from the JSON artifacts.
  • The final response names the
    run.md
    path, the cost-optimized-vs-fallback status, whether every surfaced signal has verified ≤24h first-public freshness, and top findings.
报告完整模式运行完成前,请确认:
  • coarse_relevance_decisions.json
    对每个输出候选内容均有一个判断结果(除非使用
    --allow-missing
    )。
  • clustered_candidates.json
    cluster
    生成;故事溯源针对其代表性内容运行,且运行已披露合并的重复内容/过期内容数量。
  • origin_findings.json
    对每个聚类代表性内容均有一个发现结果(除非使用
    --allow-missing
    )——数量已验证,缺口已重新运行。
  • targeted_candidates.json
    origin-apply
    生成;
    triaged_candidates.json
    newsjack-triage
    生成且每个信号均有
    tier
    pitch_ready
    内容以投送模式运行
    angle-generator
    big_story
    内容以探索模式运行。
  • 无新鲜的
    high
    /
    major
    级故事被路由至
    watch
    ——所有新鲜大型故事均出现在🔥 值得关注的重大故事(或具备立场时出现在**✅ 可投送**)。简报的不可投送规则可能将大型故事移出可投送,但仍会作为已展示的
    big_story
    off_policy: true
    ),绝不丢弃。
  • 若存在客户简报,报告已应用简报规则:不符合政策的内容已移出
    可投送
    ,任何折叠部分均显示已披露的计数+原因,且本次运行中改变政策的反馈已作为
    brief.md
    编辑建议提出。
  • final_report.md
    是三分类扫描结果(✅ 可投送 / 🔥 值得关注的重大故事 / 👀 监测/背景),基于
    targeted_candidates.json
    /
    triaged_candidates.json
    生成,而非原始
    candidates.json
  • run.md
    final_report.md
    生成后,基于经过校验/新鲜/分类的工件由Skill生成——绝不仅基于原始
    candidates.json
  • ✅/🔥章节中粗粒度拒绝或硬性安全标记的信号;仅有的硬性丢弃(URL合规 + 硬性安全)已从JSON工件中披露数量。
  • 最终响应中包含
    run.md
    路径、成本优化vs降级状态、所有显示的信号是否均已验证为首次发布≤24小时,以及核心发现。

Output Format

输出格式

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).
json
{
  "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"
        }
      ],
      "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"
  ]
}
  • Allowed verdicts:
    pitch_now
    ,
    develop_angle
    ,
    monitor
    ,
    reject
    .
  • Allowed rejection reasons:
    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
    .
  • Allowed brand-safety block reasons:
    tragedy_or_human_suffering
    ,
    client_exclusion
    ,
    regulated_claim_risk
    ,
    fabrication_risk
    .
返回以下JSON对象。前后无任何散文内容。每个机会必须在
evidence_used
中包含来源URL——优先使用
story_origin.canonical_coverage_url
(若存在),然后是原始/来源URL及其他支持内容(通常为新闻、RSS和X平台的1–3个链接)。
json
{
  "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"
        }
      ],
      "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"
  ]
}
  • 允许的verdict:
    pitch_now
    ,
    develop_angle
    ,
    monitor
    ,
    reject
  • 允许的拒绝原因:
    stale
    ,
    freshness_unverified
    (通用;或具体的
    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

Rubric

评分准则

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.
引擎返回排队证据后使用此准则。引擎提供机械评分和
routing.queue_priority
;两者均非PR判断。
引擎有两个发现通道:
  • profile_relevance
    - 配置/主题/竞争对手查询。捕捉高度相关但有时影响力较小的故事。
  • major_news
    - 精选RSS/Atom Feed内容。首先捕捉更广泛的重大新闻,然后需要更严格的客户相关性判断。
切勿因
major_news
内容规模大就视为可投送。客户仍需具备立场和符合要求的记者画像。

Story Size

故事规模

Use
story_size
to calibrate effort, not to approve a pitch. It is a deterministic media-attention proxy based on news-search publication metadata:
  • log-scaled estimated monthly traffic
  • domain authority
  • coverage spread across independently surfaced domains
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.
使用
story_size
校准投入的精力,而非批准投送。它是基于新闻搜索发布元数据的确定性媒体关注度代理指标:
  • 对数缩放的预估月流量
  • 域名权重
  • 独立显示域名的覆盖范围
若知名主流媒体的权重元数据缺失,引擎可能采用低置信度的已知媒体降级方案。若发布元数据稀疏,引擎可能附加
story_size.attention_hint
。将该提示视为低置信度的留存信号:它可证明在重大故事章节中进行审核的合理性,但能证明故事被广泛报道。明确标注不确定性。
major
high
级故事规模,或
high
/
major
级关注度提示,意味着机会可能需要更快审核。但它无法弥补过期时间、薄弱立场或不良记者画像的不足。

Freshness

新鲜度

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.
对于周期性定时输出,LLM
story-origin-check
恢复首次发布时间戳和标准报道,然后Go CLI
origin-apply
计算新鲜度校验。新闻搜索的
published_at
值是文章时间戳的可靠证据,应用于寻找候选原始内容,但仅凭它无法判断同故事或首次发布情况。
在分配
pitch_now
develop_angle
monitor
前,检查
freshness_gate.computed_status
  • fresh
    - 符合正常判断条件。
  • fresh_new_development
    - 符合条件,但角度必须围绕新进展,而非旧背景故事。
  • stale
    - 因过期拒绝。
  • unverified_no_corroboration
    unverified_boundary
    unverified_no_timestamp
    或缺失 - 周期性定时输出中拒绝。记录原因:
    unverified_no_corroboration
    是Worker/流水线问题(时间戳可能有效,只是来源不足——可重新运行),而
    unverified_boundary
    /
    unverified_no_timestamp
    反映证据确实薄弱。
切勿因聚合器、联合合作伙伴或次要媒体重新发布旧文章而重置时间戳。
引用故事时,优先使用
story_origin.canonical_coverage_url
(若存在)。它应为同故事的主流/最权威报道,例如主来源、通讯社、大型出版商或公认行业媒体,而非触发检索的小型内容。

Verdict Ladder

Verdict阶梯

pitch_now

pitch_now

Use only when all are true:
  • Evidence is fresh: usually
    30min
    ,
    4hr
    , or
    24hr
    .
  • The first public story clock is verified as inside the last 24 hours, or the new development is inside the last 24 hours.
  • At least one credible news source exists, preferably
    news_search
    .
  • The client has direct standing to comment.
  • The client has a real spokesperson or direct domain authority.
  • A specific reporter shape is obvious.
  • No hard brand-safety block applies.
仅当所有条件均满足时使用:
  • 证据新鲜:通常为
    30min
    4hr
    24hr
  • 首次发布时间戳已验证为过去24小时内,或新进展发生在过去24小时内。
  • 至少存在一个可信新闻来源,优先为
    news_search
  • 客户具备直接立场发表评论。
  • 客户有真实发言人或直接领域权威。
  • 明确的记者画像。
  • 无硬性品牌安全拦截。

develop_angle

develop_angle

Use when the signal is real but needs framing:
  • Fresh or still within the week.
  • Client standing is plausible but not yet sharp.
  • A journalist shape exists, but the angle needs work.
  • Major-news lane items often belong here when they are important but the client angle is indirect.
Handoff:
angle-generator
.
当信号真实但需要框架时使用:
  • 新鲜或仍在一周内。
  • 客户立场合理但不够明确。
  • 存在记者画像,但角度需要优化。
  • 重大新闻通道的内容通常属于此类,它们重要但客户角度间接。
移交至:
angle-generator

monitor

monitor

Use when the signal is interesting but not pitch-ready:
  • Single-source or weak cross-source confirmation.
  • Early chatter without enough news confirmation.
  • The client might have standing, but the angle is not clear yet.
  • The signal may matter if it gains traction.
当信号有趣但尚未具备可投送条件时使用:
  • 单一来源或跨来源确认薄弱。
  • 早期讨论但新闻确认不足。
  • 客户可能具备立场,但角度尚不清晰。
  • 若信号获得关注可能产生影响。

reject

reject

Use when any core gate fails:
  • stale
  • freshness unverified in recurring scheduled output
  • no client standing
  • no plausible journalist shape
  • off-beat
  • already seen with no new development
  • weak source quality
当任何核心校验失败时使用:
  • 过期
  • 周期性定时输出中新鲜度未验证
  • 客户无立场
  • 无合理记者画像
  • 偏离主题
  • 已查看且无新进展
  • 来源质量薄弱

Decay

时效性衰减

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.
时效性衰减使用
story-origin-check
验证的首次发布时间戳。当证据来自聚合器、联合合作伙伴、次要改写或尚未匹配到原始/标准故事的搜索结果时,引擎的
features.decay_bucket
是临时结果。
  • 30min
    - 实时/突发。仅当客户可立即响应时用于即时评论。
  • 4hr
    - 同周期。适用于反应式评论。
  • 24hr
    - 仍新鲜。适用于角度生成或当日响应。
  • week
    - 仅用于趋势/背景。切勿称为突发。
  • month
    - 通常不适合Newsjacking,除非搭配新数据点或新鲜钩子。
  • unknown
    - 无独立时间戳验证时,切勿作为时效性内容投送。

Standing

立场

Strong standing:
  • The client operates directly in the affected market.
  • The client has direct market exposure, technical expertise, or a named executive who can speak concretely.
  • The signal names the client's category, customers, regulators, technology, or competitors.
Partial standing:
  • The client has adjacent expertise but needs a narrower angle.
  • The client can explain impact but not the core event.
Weak standing:
  • The client merely sells into the broad category.
  • The client wants to comment because the topic is popular.
  • The client only has generic thought leadership.
For
major_news
lane signals, standing must explain the bridge from the public story to the client:
  • same buyer being affected
  • same regulator or policy surface
  • named competitor or platform move
  • client can explain a non-obvious operational effect
If the bridge is "this is about AI and the client uses AI," reject or monitor.
强立场:
  • 客户直接在受影响市场运营。
  • 客户具备直接市场曝光、技术专长或可具体发言的指定高管。
  • 信号提及客户的品类、客户、监管机构、技术或竞争对手。
部分立场:
  • 客户具备相邻专长但需要更聚焦的角度。
  • 客户可解释影响但无法解释核心事件。
弱立场:
  • 客户仅向广泛品类销售产品。
  • 客户因话题热门而希望发表评论。
  • 客户仅具备通用思想领导力。
对于
major_news
通道的信号,立场需解释公共故事与客户之间的关联:
  • 受影响的是同一买家
  • 同一监管机构或政策领域
  • 指定竞争对手或平台行动
  • 客户可解释非显而易见的运营影响
若关联仅为“这是关于AI的,而客户使用AI”,则拒绝或监测。

Journalist Shape

记者画像

A useful journalist shape names:
  • exact beat
  • outlet archetype
  • why the beat cares now
  • who should not receive it
Bad shapes:
  • "business reporter"
  • "AI journalist"
  • "tech media"
  • "industry press"
Good shapes:
  • "enterprise AI reporter covering vendor compliance claims after regulator action"
  • "cybersecurity trade reporter covering identity-risk fallout from new enforcement"
  • "retail operations reporter covering labor-cost impact of a same-day policy change"
有用的记者画像需包含:
  • 具体报道领域
  • 媒体类型
  • 该领域为何现在关注此内容
  • 不应投送的对象
不良画像:
  • “商业记者”
  • “AI记者”
  • “科技媒体”
  • “行业媒体”
良好画像:
  • “企业AI记者,关注监管行动后的供应商合规声明”
  • “网络安全行业记者,关注新执法行动后的身份风险影响”
  • “零售运营记者,关注当日政策变化对人力成本的影响”

Hard Blocks

硬性拦截

Block signals built on:
  • death
  • violence
  • disaster
  • war
  • abuse
  • sexual violence
  • missing people
  • humanitarian crisis
  • hate crime
  • terror
  • suicide
The only acceptable work around these topics is restrained expert commentary with direct public-interest standing. Promotional hooks are refused.
拦截基于以下内容的信号:
  • 死亡
  • 暴力
  • 灾难
  • 战争
  • 虐待
  • 性暴力
  • 失踪人员
  • 人道主义危机
  • 仇恨犯罪
  • 恐怖主义
  • 自杀
这些主题仅接受具备直接公共利益立场的克制专家评论。拒绝推广式钩子。

Examples

示例

Pitch Now

立即投送

Engine signal:
json
{
  "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:
json
{
  "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"
    }
  ],
  "next_skill": "reactive-comment"
}
引擎信号:
json
{
  "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输出:
json
{
  "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"
    }
  ],
  "next_skill": "reactive-comment"
}

Reject (stale syndication)

拒绝(过期联合报道)

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
引擎信号:AOL今日发布的文章,标准URL指向BBC5月4日的故事且无新进展。
Verdict:
reject
Reason:
stale
first_publication.status
:
stale