newsjack 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.mcp.json +9 -0
- package/.newsjack-npm +1 -0
- package/COMMIT +1 -0
- package/LICENSE +21 -0
- package/README.md +133 -0
- package/VERSION +1 -0
- package/bin/newsjack +74 -0
- package/package.json +37 -0
- package/skills/.gitkeep +0 -0
- package/skills/ETHICS.md +265 -0
- package/skills/WHY-NOT-SPAM.md +257 -0
- package/skills/angle-generator/SKILL.md +224 -0
- package/skills/angle-generator/examples.md +517 -0
- package/skills/angle-generator/rubric.md +219 -0
- package/skills/coverage-tracker/SKILL.md +124 -0
- package/skills/coverage-tracker-setup/SKILL.md +84 -0
- package/skills/crisis-holding/SKILL.md +336 -0
- package/skills/crisis-holding/examples.md +302 -0
- package/skills/crisis-holding/rubric.md +218 -0
- package/skills/fact-check/SKILL.md +212 -0
- package/skills/fact-check/examples.md +195 -0
- package/skills/fact-check/rubric.md +228 -0
- package/skills/journalist-fit-check/SKILL.md +199 -0
- package/skills/journalist-fit-check/examples.md +271 -0
- package/skills/journalist-fit-check/rubric.md +251 -0
- package/skills/meanest-editor/SKILL.md +112 -0
- package/skills/meanest-editor/examples.md +331 -0
- package/skills/meanest-editor/rubric.md +275 -0
- package/skills/media-list-manager/SKILL.md +204 -0
- package/skills/media-list-manager/examples.md +88 -0
- package/skills/media-list-manager/rubric.md +67 -0
- package/skills/news-search/SKILL.md +56 -0
- package/skills/newsjack-detector/SKILL.md +286 -0
- package/skills/newsjack-detector/examples.md +118 -0
- package/skills/newsjack-detector/references/engine-cli.md +29 -0
- package/skills/newsjack-detector/references/harness-routing.md +38 -0
- package/skills/newsjack-detector/references/rss-feeds.json +106 -0
- package/skills/newsjack-detector/rubric.md +160 -0
- package/skills/newsjack-monitor-setup/SKILL.md +202 -0
- package/skills/newsjack-monitor-setup/examples.md +106 -0
- package/skills/newsjack-triage/SKILL.md +98 -0
- package/skills/newsworthiness-check/SKILL.md +179 -0
- package/skills/newsworthiness-check/examples.md +232 -0
- package/skills/newsworthiness-check/rubric.md +218 -0
- package/skills/pr-strategist/SKILL.md +304 -0
- package/skills/reactive-comment/SKILL.md +297 -0
- package/skills/reactive-comment/examples.md +284 -0
- package/skills/reactive-comment/rubric.md +280 -0
- package/skills/relevance-coarse-filter/SKILL.md +61 -0
- package/skills/story-origin-check/SKILL.md +160 -0
- package/skills/voice-extractor/SKILL.md +330 -0
- package/skills/voice-extractor/examples.md +227 -0
- package/skills/voice-extractor/rubric.md +251 -0
- package/skills-manifest.json +254 -0
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
# Reactive Comment - Worked Examples
|
|
2
|
+
|
|
3
|
+
Four realistic examples showing the expected shape: input query and profile
|
|
4
|
+
before, YAML verdict after. These are not templates to blast. They show
|
|
5
|
+
what the gate should accept, kill, or pause.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Example 1: Clean Fit, Draft
|
|
10
|
+
|
|
11
|
+
### Before
|
|
12
|
+
|
|
13
|
+
```yaml
|
|
14
|
+
profile:
|
|
15
|
+
name: "Jane Doe"
|
|
16
|
+
title: "Co-founder & CTO"
|
|
17
|
+
company: "Acme Security"
|
|
18
|
+
expertise_areas:
|
|
19
|
+
- "application security for SaaS startups"
|
|
20
|
+
- "secrets management in CI/CD"
|
|
21
|
+
do_not_comment_on:
|
|
22
|
+
- "cryptocurrency"
|
|
23
|
+
- "criminal cases"
|
|
24
|
+
- "competitor product comparisons"
|
|
25
|
+
proof_points:
|
|
26
|
+
- claim: "BlackHat 2024 talk on CI/CD secret leakage"
|
|
27
|
+
verifiable_at: "https://blackhat.com/us-24/briefings/schedule/#leak"
|
|
28
|
+
- claim: "10 years building auth systems at Stripe and Okta"
|
|
29
|
+
verifiable_at: "https://linkedin.com/in/janedoe"
|
|
30
|
+
contact_block: |
|
|
31
|
+
Jane Doe, Co-founder & CTO, Acme Security
|
|
32
|
+
jane@acme.security
|
|
33
|
+
linkedin.com/in/janedoe
|
|
34
|
+
response_cap_per_week: 5
|
|
35
|
+
query:
|
|
36
|
+
source: "SourceOfSources"
|
|
37
|
+
journalist_name: "Alex Rivera"
|
|
38
|
+
journalist_outlet: "TechCrunch"
|
|
39
|
+
query_text: "Looking for CTOs at Series A-B SaaS startups: has Copilot/Cursor changed how secrets leak into your repos? Real anecdotes welcome. No vendor pitches. Deadline EOD Friday."
|
|
40
|
+
deadline_iso: "2026-05-22T23:59:00-07:00"
|
|
41
|
+
received_at_iso: "2026-05-20T08:14:00-07:00"
|
|
42
|
+
recent_context:
|
|
43
|
+
journalist_bylines:
|
|
44
|
+
- title: "GitHub Copilot's hidden cost: a year of leaked tokens"
|
|
45
|
+
url: "https://techcrunch.com/2026/03/14/copilot-leak-year"
|
|
46
|
+
published_iso: "2026-03-14"
|
|
47
|
+
internal_state:
|
|
48
|
+
responses_to_this_source_this_week: 2
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### After
|
|
52
|
+
|
|
53
|
+
```yaml
|
|
54
|
+
verdict: draft
|
|
55
|
+
fit_score: 84
|
|
56
|
+
fit_reasoning: |
|
|
57
|
+
Direct fit on CI/CD secrets and SaaS application security. The query asks
|
|
58
|
+
for CTOs discussing Copilot/Cursor secret leakage, and the profile has a
|
|
59
|
+
BlackHat proof point on CI/CD secret leakage plus auth tenure at Stripe
|
|
60
|
+
and Okta. The journalist's recent byline is on leaked tokens. "No vendor
|
|
61
|
+
pitches" is compatible because the response offers an operator anecdote,
|
|
62
|
+
not a product pitch.
|
|
63
|
+
decay_flags:
|
|
64
|
+
hours_until_deadline: 56
|
|
65
|
+
is_fresh: true
|
|
66
|
+
warning: null
|
|
67
|
+
draft_response:
|
|
68
|
+
subject: "Re: AI-code secret leakage, CTO at Acme Security"
|
|
69
|
+
body: |
|
|
70
|
+
Hi Alex,
|
|
71
|
+
|
|
72
|
+
Your March piece on Copilot's leaked-token year matches what we saw from the founder side at Acme. After we instrumented Cursor and Copilot against our repos earlier this year, AI-suggested code raised our secret-leak rate roughly 3x before we put server-side scanning in front of every push. The pattern worth flagging is autocompletion of `.env.example` files with real values, not malice, just muscle memory. Happy to go on record: 10 years building auth at Stripe and Okta before Acme, plus the CI/CD secrets talk at BlackHat 2024.
|
|
73
|
+
|
|
74
|
+
Jane Doe, Co-founder & CTO, Acme Security
|
|
75
|
+
jane@acme.security
|
|
76
|
+
linkedin.com/in/janedoe
|
|
77
|
+
provenance:
|
|
78
|
+
- claim: "BlackHat 2024 CI/CD secret leakage talk"
|
|
79
|
+
sourced_from: "profile.proof_points[0]"
|
|
80
|
+
- claim: "10 years building auth at Stripe and Okta"
|
|
81
|
+
sourced_from: "profile.proof_points[1]"
|
|
82
|
+
- claim: "TechCrunch byline on Copilot leaked tokens"
|
|
83
|
+
sourced_from: "recent_context.journalist_bylines[0]"
|
|
84
|
+
- claim: "Acme instrumented Cursor and Copilot, roughly 3x secret-leak rate"
|
|
85
|
+
sourced_from: "USER MUST CONFIRM"
|
|
86
|
+
slop_check:
|
|
87
|
+
banned_words_found: []
|
|
88
|
+
emdash_count: 0
|
|
89
|
+
placeholders_found: []
|
|
90
|
+
ai_tells_found: []
|
|
91
|
+
passed: true
|
|
92
|
+
anti_spray:
|
|
93
|
+
responses_to_this_source_this_week: 2
|
|
94
|
+
cap: 5
|
|
95
|
+
passed: true
|
|
96
|
+
next_action: |
|
|
97
|
+
Confirm the Cursor/Copilot instrumentation and 3x figure before sending.
|
|
98
|
+
If the number is directional, change it to "noticeably raised." Send
|
|
99
|
+
manually from your mail client. Do not auto-send.
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Example 2: Adjacent Topic, Hard Kill
|
|
105
|
+
|
|
106
|
+
### Before
|
|
107
|
+
|
|
108
|
+
```yaml
|
|
109
|
+
profile:
|
|
110
|
+
name: "Jane Doe"
|
|
111
|
+
title: "Co-founder & CTO"
|
|
112
|
+
company: "Acme Security"
|
|
113
|
+
expertise_areas:
|
|
114
|
+
- "application security for SaaS startups"
|
|
115
|
+
- "SOC 2 Type 2 readiness for sub-100-headcount teams"
|
|
116
|
+
do_not_comment_on:
|
|
117
|
+
- "cryptocurrency"
|
|
118
|
+
- "competitor product comparisons"
|
|
119
|
+
proof_points:
|
|
120
|
+
- claim: "Led SOC 2 Type 2 readiness at Acme Security"
|
|
121
|
+
verifiable_at: "https://acme.security/security"
|
|
122
|
+
contact_block: |
|
|
123
|
+
Jane Doe, Co-founder & CTO, Acme Security
|
|
124
|
+
jane@acme.security
|
|
125
|
+
query:
|
|
126
|
+
source: "Featured"
|
|
127
|
+
journalist_name: "Sam Lin"
|
|
128
|
+
journalist_outlet: "CoinDesk"
|
|
129
|
+
query_text: "How are SaaS CTOs thinking about on-chain authentication for B2B SSO? Looking for comments on wallet-based identity and enterprise readiness."
|
|
130
|
+
deadline_iso: "2026-05-23T17:00:00-07:00"
|
|
131
|
+
internal_state:
|
|
132
|
+
responses_to_this_source_this_week: 1
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### After
|
|
136
|
+
|
|
137
|
+
```yaml
|
|
138
|
+
verdict: kill
|
|
139
|
+
fit_score: 0
|
|
140
|
+
kill_reason: |
|
|
141
|
+
The query is about on-chain authentication and wallet-based identity.
|
|
142
|
+
Your profile's `do_not_comment_on` includes cryptocurrency. The SaaS SSO
|
|
143
|
+
angle is adjacent, but the requested comment would land inside crypto
|
|
144
|
+
coverage at CoinDesk. Hard veto.
|
|
145
|
+
why_not_your_fight: |
|
|
146
|
+
You will be tempted because "SSO" is close to your work. The actual piece
|
|
147
|
+
is about wallet-based identity. Anything useful you say will be excerpted
|
|
148
|
+
into a crypto-auth story, and then you will spend time clarifying a
|
|
149
|
+
position your profile already told us not to take. Skip it.
|
|
150
|
+
suggested_alternative: |
|
|
151
|
+
If this topic matters to you, publish your own post on why wallet-based
|
|
152
|
+
SSO is not ready for mainstream SaaS. That gives future reporters a clean
|
|
153
|
+
reason to come to you without violating the profile.
|
|
154
|
+
decay_flags:
|
|
155
|
+
hours_until_deadline: 72
|
|
156
|
+
is_fresh: true
|
|
157
|
+
warning: null
|
|
158
|
+
anti_spray:
|
|
159
|
+
responses_to_this_source_this_week: 1
|
|
160
|
+
cap: 5
|
|
161
|
+
passed: true
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Example 3: Missing Proof, Ask
|
|
167
|
+
|
|
168
|
+
### Before
|
|
169
|
+
|
|
170
|
+
```yaml
|
|
171
|
+
profile:
|
|
172
|
+
name: "Maya Patel"
|
|
173
|
+
title: "VP Engineering"
|
|
174
|
+
company: "Northstar Data"
|
|
175
|
+
expertise_areas:
|
|
176
|
+
- "data platform reliability"
|
|
177
|
+
- "incident response for enterprise analytics teams"
|
|
178
|
+
do_not_comment_on:
|
|
179
|
+
- "layoffs"
|
|
180
|
+
- "criminal cases"
|
|
181
|
+
proof_points:
|
|
182
|
+
- claim: "Built Northstar's incident review process after a 2024 warehouse outage"
|
|
183
|
+
verifiable_at: "https://northstar.example.com/engineering/outage-review"
|
|
184
|
+
contact_block: |
|
|
185
|
+
Maya Patel, VP Engineering, Northstar Data
|
|
186
|
+
maya@northstar.example.com
|
|
187
|
+
query:
|
|
188
|
+
source: "Qwoted"
|
|
189
|
+
journalist_name: "Priya Mehta"
|
|
190
|
+
journalist_outlet: "InformationWeek"
|
|
191
|
+
query_text: "Looking for CISOs at companies with 500-5,000 employees to discuss how AI governance policies are being structured. Need examples of internal policy language and ownership."
|
|
192
|
+
deadline_iso: "2026-05-21T18:00:00-07:00"
|
|
193
|
+
recent_context: null
|
|
194
|
+
internal_state:
|
|
195
|
+
responses_to_this_source_this_week: 0
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### After
|
|
199
|
+
|
|
200
|
+
```yaml
|
|
201
|
+
verdict: ask
|
|
202
|
+
missing_info:
|
|
203
|
+
- "The query asks for CISOs. Profile says VP Engineering. Are you the accountable security-policy owner, or is this outside your title scope?"
|
|
204
|
+
- "The query requires companies with 500-5,000 employees. What is Northstar's current headcount?"
|
|
205
|
+
- "The query asks for internal AI governance policy language. Add a proof point or paste approved policy language that can be quoted."
|
|
206
|
+
- "Recent context is missing. Paste 1-2 recent Priya Mehta bylines or rerun with browse enabled."
|
|
207
|
+
why_we_paused: |
|
|
208
|
+
Drafting now would guess title scope, company size, policy ownership, and
|
|
209
|
+
journalist context. Any one of those could make this a clean kill.
|
|
210
|
+
decay_flags:
|
|
211
|
+
hours_until_deadline: 30
|
|
212
|
+
is_fresh: true
|
|
213
|
+
warning: null
|
|
214
|
+
anti_spray:
|
|
215
|
+
responses_to_this_source_this_week: 0
|
|
216
|
+
cap: 5
|
|
217
|
+
passed: true
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## Example 4: Strong Fit, Cap Refusal
|
|
223
|
+
|
|
224
|
+
### Before
|
|
225
|
+
|
|
226
|
+
```yaml
|
|
227
|
+
profile:
|
|
228
|
+
name: "Owen Chen"
|
|
229
|
+
title: "Founder"
|
|
230
|
+
company: "Ledgerfield"
|
|
231
|
+
expertise_areas:
|
|
232
|
+
- "restaurant payroll compliance"
|
|
233
|
+
- "tip-credit law for multi-state hospitality groups"
|
|
234
|
+
do_not_comment_on:
|
|
235
|
+
- "immigration enforcement"
|
|
236
|
+
proof_points:
|
|
237
|
+
- claim: "Testified to the California Senate Labor Committee on tip-credit compliance in 2025"
|
|
238
|
+
verifiable_at: "https://senate.ca.gov/archive/tip-credit-hearing-2025"
|
|
239
|
+
contact_block: |
|
|
240
|
+
Owen Chen, Founder, Ledgerfield
|
|
241
|
+
owen@ledgerfield.example.com
|
|
242
|
+
response_cap_per_week: 5
|
|
243
|
+
query:
|
|
244
|
+
source: "HelpAB2BWriter"
|
|
245
|
+
journalist_name: "Dana Ortiz"
|
|
246
|
+
journalist_outlet: "Restaurant Business"
|
|
247
|
+
query_text: "Need payroll operators who can explain the practical impact of the new state tip-credit rules for restaurant groups operating in 3+ states. Deadline tomorrow noon ET."
|
|
248
|
+
deadline_iso: "2026-05-20T12:00:00-04:00"
|
|
249
|
+
recent_context:
|
|
250
|
+
journalist_bylines:
|
|
251
|
+
- title: "Restaurant chains brace for state wage-law divergence"
|
|
252
|
+
url: "https://restaurantbusiness.example.com/labor/state-wage-law-divergence"
|
|
253
|
+
published_iso: "2026-05-01"
|
|
254
|
+
internal_state:
|
|
255
|
+
responses_to_this_source_this_week: 5
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### After
|
|
259
|
+
|
|
260
|
+
```yaml
|
|
261
|
+
verdict: kill
|
|
262
|
+
fit_score: 78
|
|
263
|
+
kill_reason: |
|
|
264
|
+
Topic fit is real: restaurant payroll compliance, multi-state tip-credit
|
|
265
|
+
rules, and a recent journalist byline on state wage-law divergence. Cap
|
|
266
|
+
is the blocker. You have already drafted 5 Help A B2B Writer responses
|
|
267
|
+
this rolling week.
|
|
268
|
+
why_not_your_fight: |
|
|
269
|
+
This is exactly why the cap exists. A good-fit sixth response still makes
|
|
270
|
+
the account look like it is spraying. If this is better than one of the
|
|
271
|
+
five already drafted, retire one of those first. Otherwise hold it.
|
|
272
|
+
suggested_alternative: |
|
|
273
|
+
Turn the point into a short owned post on how multi-state restaurant
|
|
274
|
+
groups should audit tip-credit exposure. It can support the next query
|
|
275
|
+
without spending another source-platform slot.
|
|
276
|
+
decay_flags:
|
|
277
|
+
hours_until_deadline: 20
|
|
278
|
+
is_fresh: true
|
|
279
|
+
warning: "Less than 24 hours until deadline."
|
|
280
|
+
anti_spray:
|
|
281
|
+
responses_to_this_source_this_week: 5
|
|
282
|
+
cap: 5
|
|
283
|
+
passed: false
|
|
284
|
+
```
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
# Reactive Comment Rubric
|
|
2
|
+
|
|
3
|
+
Every query gets one score and then runs through the refusal gates. The
|
|
4
|
+
score decides whether drafting is even eligible. The gates decide whether a
|
|
5
|
+
draft is allowed to leave the model.
|
|
6
|
+
|
|
7
|
+
Trace: all criteria are compressed from the source design's sections on
|
|
8
|
+
Topic fit, Anti-spray rubric, Anti-hallucination rubric, Decay rubric,
|
|
9
|
+
Banned-word list, Em-dash check, Sentence-shape blocks, Placeholder tells,
|
|
10
|
+
and the three output modes.
|
|
11
|
+
|
|
12
|
+
## Score Bands
|
|
13
|
+
|
|
14
|
+
| Fit score | Verdict |
|
|
15
|
+
|-----------|---------|
|
|
16
|
+
| 85-100 | `draft`, if every gate passes |
|
|
17
|
+
| 65-84 | `draft`, if every gate passes and any weak spots are named |
|
|
18
|
+
| 40-64 | `kill`, unless one missing fact could push the score over 65, then `ask` |
|
|
19
|
+
| 0-39 | `kill` |
|
|
20
|
+
|
|
21
|
+
Drafting requires **65+ and clean gates**. A high score never overrides a
|
|
22
|
+
hard veto.
|
|
23
|
+
|
|
24
|
+
## Weighted Fit Score
|
|
25
|
+
|
|
26
|
+
### 1. Specific Expertise Match - 40 Points
|
|
27
|
+
|
|
28
|
+
> Does the query's exact ask intersect the profile's exact expertise?
|
|
29
|
+
|
|
30
|
+
- **0 points:** No real intersection, only broad adjacency.
|
|
31
|
+
- **10 points:** Same general industry, wrong problem.
|
|
32
|
+
- **20 points:** Same problem family, but the query asks for a narrower
|
|
33
|
+
experience the profile does not show.
|
|
34
|
+
- **30 points:** Strong topical fit, with one missing scope detail such as
|
|
35
|
+
company stage, geography, title, or customer type.
|
|
36
|
+
- **40 points:** Direct fit. The query asks for something the profile
|
|
37
|
+
explicitly names.
|
|
38
|
+
|
|
39
|
+
Red flags:
|
|
40
|
+
|
|
41
|
+
- "software" treated as expertise
|
|
42
|
+
- "founder" treated as permission to comment on every business topic
|
|
43
|
+
- query asks for a title the user does not hold
|
|
44
|
+
- query asks for first-hand experience and the profile only supports
|
|
45
|
+
analysis
|
|
46
|
+
|
|
47
|
+
### 2. Proof-Point Support - 25 Points
|
|
48
|
+
|
|
49
|
+
> Can the response make a substantive claim backed by the profile?
|
|
50
|
+
|
|
51
|
+
- **0 points:** No proof point backs the answer.
|
|
52
|
+
- **8 points:** A proof point exists, but only supports a generic bio line.
|
|
53
|
+
- **16 points:** A proof point supports the topic, but not the specific
|
|
54
|
+
angle the query requests.
|
|
55
|
+
- **25 points:** At least one proof point directly backs the claim the
|
|
56
|
+
draft would make.
|
|
57
|
+
|
|
58
|
+
For `draft`, 100% of concrete claims need provenance. Allowed sources:
|
|
59
|
+
|
|
60
|
+
- `profile.proof_points[i]`
|
|
61
|
+
- `recent_context.journalist_bylines[i]`
|
|
62
|
+
- `"USER MUST CONFIRM"`
|
|
63
|
+
|
|
64
|
+
No general-knowledge claims. No invented stats. No fabricated expert
|
|
65
|
+
credentials.
|
|
66
|
+
|
|
67
|
+
### 3. Do-Not-Comment and Identity Fit - 15 Points
|
|
68
|
+
|
|
69
|
+
> Is the query inside the user's declared lane?
|
|
70
|
+
|
|
71
|
+
- **0 points:** The query touches `profile.do_not_comment_on`, asks for a
|
|
72
|
+
credential or title not in profile, or would force a competitor/product
|
|
73
|
+
comparison the profile forbids. This is a hard veto.
|
|
74
|
+
- **8 points:** The query is adjacent to a do-not topic but can be answered
|
|
75
|
+
cleanly without entering it.
|
|
76
|
+
- **15 points:** No conflict with do-not topics, title, employer, stage, or
|
|
77
|
+
identity.
|
|
78
|
+
|
|
79
|
+
Hard-veto examples:
|
|
80
|
+
|
|
81
|
+
- profile says no cryptocurrency; query asks for on-chain auth
|
|
82
|
+
- profile says no competitor comparisons; query asks Cursor vs. Copilot
|
|
83
|
+
- query asks for CISOs; profile only shows CTO
|
|
84
|
+
- query asks for Series A-B; profile has no funding-stage proof
|
|
85
|
+
|
|
86
|
+
### 4. Journalist Context and Real Personalization - 10 Points
|
|
87
|
+
|
|
88
|
+
> Is there a real anchor to the journalist's beat?
|
|
89
|
+
|
|
90
|
+
- **0 points:** The draft would need to fake familiarity with the
|
|
91
|
+
journalist's work.
|
|
92
|
+
- **5 points:** Recent context is unavailable; neutral score. Open with the
|
|
93
|
+
user's credential instead of pretending.
|
|
94
|
+
- **7 points:** Recent context shows the journalist covers the broad beat.
|
|
95
|
+
- **10 points:** A recent byline or post matches the query's topic and can
|
|
96
|
+
be referenced specifically by URL, title, or topic.
|
|
97
|
+
|
|
98
|
+
Never praise generically. "Saw your recent piece" requires a supplied
|
|
99
|
+
recent-context title or URL.
|
|
100
|
+
|
|
101
|
+
### 5. Outlet, Source, and Requirement Hygiene - 10 Points
|
|
102
|
+
|
|
103
|
+
> Does the response respect the outlet, source platform, and query terms?
|
|
104
|
+
|
|
105
|
+
- **0 points:** Outlet matches `profile.outlets_to_skip`, the query says
|
|
106
|
+
"no vendors" and the only angle is vendor-coded, or a source-platform
|
|
107
|
+
rule blocks the response. Outlet skip is a hard veto.
|
|
108
|
+
- **4 points:** The outlet is acceptable, but the draft would brush against
|
|
109
|
+
a requirement or source-platform norm.
|
|
110
|
+
- **7 points:** Requirements are mostly satisfied, with one minor caveat
|
|
111
|
+
that should be stamped.
|
|
112
|
+
- **10 points:** Outlet passes filters, query requirements are met, and the
|
|
113
|
+
response is visibly human-reviewed rather than automated spray.
|
|
114
|
+
|
|
115
|
+
Examples:
|
|
116
|
+
|
|
117
|
+
- "No vendor pitches" means no product pitch.
|
|
118
|
+
- "Real anecdotes only" means analysis is not enough.
|
|
119
|
+
- "Academics only" means operators do not qualify.
|
|
120
|
+
- Featured/HARO should share one cap when the profile treats them as one
|
|
121
|
+
source family.
|
|
122
|
+
|
|
123
|
+
## Hard Gates
|
|
124
|
+
|
|
125
|
+
Any hard-gate failure overrides the score.
|
|
126
|
+
|
|
127
|
+
### Decay Gate
|
|
128
|
+
|
|
129
|
+
- `hours_until_deadline > 24`: fresh.
|
|
130
|
+
- `12 < hours_until_deadline <= 24`: proceed with warning.
|
|
131
|
+
- `2 < hours_until_deadline <= 12`: proceed with tight-window warning.
|
|
132
|
+
- `0 <= hours_until_deadline <= 2`: `ask` unless recent context is already
|
|
133
|
+
loaded and every other gate is clean.
|
|
134
|
+
- `hours_until_deadline < 0`: `kill`.
|
|
135
|
+
|
|
136
|
+
If `received_at_iso` is older than 48 hours, warn that the user is late in
|
|
137
|
+
the source queue.
|
|
138
|
+
|
|
139
|
+
### Anti-Spray Gate
|
|
140
|
+
|
|
141
|
+
Default cap: 5 responses per source per rolling week.
|
|
142
|
+
|
|
143
|
+
- If `profile.response_cap_per_week` is missing, use 5.
|
|
144
|
+
- If it is above 10, `ask` for justification before drafting.
|
|
145
|
+
- If `responses_to_this_source_this_week >= cap`, `kill`.
|
|
146
|
+
- If `responses_to_this_source_this_week >= cap * 0.8`, proceed only with a
|
|
147
|
+
warning.
|
|
148
|
+
|
|
149
|
+
Always stamp:
|
|
150
|
+
|
|
151
|
+
```yaml
|
|
152
|
+
anti_spray:
|
|
153
|
+
responses_to_this_source_this_week: 0
|
|
154
|
+
cap: 5
|
|
155
|
+
passed: true
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Anti-Hallucination Gate
|
|
159
|
+
|
|
160
|
+
Refuse or downgrade if any concrete claim lacks provenance.
|
|
161
|
+
|
|
162
|
+
Concrete claims include:
|
|
163
|
+
|
|
164
|
+
- people
|
|
165
|
+
- companies
|
|
166
|
+
- products
|
|
167
|
+
- publications
|
|
168
|
+
- employers
|
|
169
|
+
- customer anecdotes
|
|
170
|
+
- statistics
|
|
171
|
+
- prior bylines
|
|
172
|
+
- conference talks
|
|
173
|
+
- funding stage
|
|
174
|
+
- headcount
|
|
175
|
+
- geography
|
|
176
|
+
|
|
177
|
+
If the claim could be true but is not in profile or recent context, source
|
|
178
|
+
it as `"USER MUST CONFIRM"` and flag it in `next_action`. If that would make
|
|
179
|
+
the draft misleading, return `ask` instead.
|
|
180
|
+
|
|
181
|
+
### Slop Gate
|
|
182
|
+
|
|
183
|
+
Block the draft if the body contains any of these case-insensitive
|
|
184
|
+
substrings:
|
|
185
|
+
|
|
186
|
+
```text
|
|
187
|
+
world-class
|
|
188
|
+
innovative
|
|
189
|
+
leading
|
|
190
|
+
revolutionary
|
|
191
|
+
best-in-class
|
|
192
|
+
we are committed to
|
|
193
|
+
cutting-edge
|
|
194
|
+
synergy
|
|
195
|
+
synergies
|
|
196
|
+
game-changing
|
|
197
|
+
thought leader
|
|
198
|
+
thought leadership
|
|
199
|
+
next-generation
|
|
200
|
+
robust
|
|
201
|
+
seamless
|
|
202
|
+
leverage
|
|
203
|
+
leveraging
|
|
204
|
+
unparalleled
|
|
205
|
+
industry-leading
|
|
206
|
+
groundbreaking
|
|
207
|
+
disrupting
|
|
208
|
+
disruptive
|
|
209
|
+
we are excited to
|
|
210
|
+
thrilled to announce
|
|
211
|
+
proud to announce
|
|
212
|
+
transform the way
|
|
213
|
+
redefining
|
|
214
|
+
reimagine
|
|
215
|
+
unlock
|
|
216
|
+
empower
|
|
217
|
+
empowering
|
|
218
|
+
comprehensive solution
|
|
219
|
+
end-to-end solution
|
|
220
|
+
holistic
|
|
221
|
+
turn-key
|
|
222
|
+
turnkey
|
|
223
|
+
mission-critical
|
|
224
|
+
move the needle
|
|
225
|
+
deliver value
|
|
226
|
+
add value
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
The word `leading` can appear only as plain grammar inside supplied profile
|
|
230
|
+
material, never as self-awarded praise in the draft.
|
|
231
|
+
|
|
232
|
+
### AI-Tell Gate
|
|
233
|
+
|
|
234
|
+
Block the draft if the body contains:
|
|
235
|
+
|
|
236
|
+
- an em dash character
|
|
237
|
+
- "it's not just X, it's Y"
|
|
238
|
+
- "this isn't just X, it's Y"
|
|
239
|
+
- "X isn't just Y. It's Z."
|
|
240
|
+
- "in a world where"
|
|
241
|
+
- "whether you're X or Y"
|
|
242
|
+
- "not only X but also Y"
|
|
243
|
+
- "at the intersection of X and Y"
|
|
244
|
+
- a triple dash list
|
|
245
|
+
- title case marketing phrases in the middle of a sentence
|
|
246
|
+
|
|
247
|
+
### Placeholder Gate
|
|
248
|
+
|
|
249
|
+
Block placeholder leakage:
|
|
250
|
+
|
|
251
|
+
- `{...}`
|
|
252
|
+
- `[...]` when used for fields such as company, name, title, topic, outlet,
|
|
253
|
+
date, or "your X"
|
|
254
|
+
- `<<...>>`
|
|
255
|
+
- `__...__`
|
|
256
|
+
- `{{first_name}}` or similar mail-merge fields
|
|
257
|
+
|
|
258
|
+
### Identity Gate
|
|
259
|
+
|
|
260
|
+
The response comes from the user, not from the agent.
|
|
261
|
+
|
|
262
|
+
Refuse if:
|
|
263
|
+
|
|
264
|
+
- the draft mentions being an AI or assistant
|
|
265
|
+
- the draft uses a name other than `profile.name`
|
|
266
|
+
- the contact block is rewritten instead of appended verbatim
|
|
267
|
+
- the bio invents a title, employer, credential, or publication
|
|
268
|
+
|
|
269
|
+
## Output Gate
|
|
270
|
+
|
|
271
|
+
Before returning:
|
|
272
|
+
|
|
273
|
+
- exactly one YAML block
|
|
274
|
+
- no surrounding prose unless requested
|
|
275
|
+
- one query only
|
|
276
|
+
- one verdict only
|
|
277
|
+
- `anti_spray` always present
|
|
278
|
+
- `slop_check` present on drafts and any slop downgrade
|
|
279
|
+
- `provenance` present on drafts
|
|
280
|
+
- `next_action` says manual review and manual send on drafts
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: relevance-coarse-filter
|
|
3
|
+
description: "Cheap, high-recall first-pass filter that removes obvious junk from a detector candidate pool before expensive story-origin research and PR judgment. Decides keep, monitor_only, or reject — never ranks, writes angles, verifies dates, or decides whether to pitch."
|
|
4
|
+
when_to_use: "Use as the coarse relevance pass of the newsjack-detector pipeline, or whenever a candidate signal pool needs cheap junk removal before expensive newsworthiness judgment. Designed to run on a low-cost model."
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Relevance Coarse Filter
|
|
8
|
+
|
|
9
|
+
You are **relevance-coarse-filter**, the cheap first gate of a newsjacking pipeline. Your only job is to remove obvious junk before story-origin research and expensive newsworthiness judgment run on the survivors.
|
|
10
|
+
|
|
11
|
+
You are deliberately **recall-biased**: false positives are cheap here, false negatives are expensive. When in doubt, keep.
|
|
12
|
+
|
|
13
|
+
You do **not**: rank signals, choose best bets, write angles, run story-origin research, compute freshness or 24h cutoff status, or decide whether to pitch. Those belong to later passes (`story-origin-check`, then the detector's rubric judgment).
|
|
14
|
+
|
|
15
|
+
## Inputs
|
|
16
|
+
|
|
17
|
+
Evaluate **one signal at a time** against the client profile. For each signal you receive:
|
|
18
|
+
|
|
19
|
+
- signal id, title, excerpt/evidence
|
|
20
|
+
- source/lane and detector `profile_matches`
|
|
21
|
+
- `story_size.band` when present
|
|
22
|
+
- the client profile (company, topics, competitors, standing terms, regulators/customers/categories) as matching context
|
|
23
|
+
|
|
24
|
+
## Decision
|
|
25
|
+
|
|
26
|
+
Return exactly one decision per signal.
|
|
27
|
+
|
|
28
|
+
Allowed decisions: `keep`, `monitor_only`, `reject`.
|
|
29
|
+
|
|
30
|
+
Allowed reasons: `relevant_news`, `plausible_client_bridge`, `major_news_no_bridge`, `keyword_collision`, `not_news`, `owned_docs_or_product_page`, `seo_landing_page`, `competitor_or_promotional`, `low_reach_x_post`, `safety_risk`, `duplicate`, `off_beat`, `no_profile_bridge`.
|
|
31
|
+
|
|
32
|
+
## Rules
|
|
33
|
+
|
|
34
|
+
- Only `reject` clear junk: keyword collisions, obvious non-news, docs/product/SEO pages, evergreen content, low-reach single X posts, safety-risk hooks, or plainly off-beat items.
|
|
35
|
+
- If the client, a named competitor, a profile topic, a profile standing term, a regulator/customer/category named in the profile, or a direct synonym appears anywhere in the title, excerpt, evidence, or `profile_matches` — do not reject as `no_profile_bridge`. Use `keep` or `monitor_only`.
|
|
36
|
+
- A named competitor counts even when it is not the headline subject. If a story is framed around Meta, China, a regulator, an acquirer, a partner, or a blocked deal but the company affected is a profile competitor, keep it for the next stage.
|
|
37
|
+
- **Never `reject` a `high` or `major` `story_size.band` signal — the ceiling is `monitor_only`, even when you see no bridge at all.** A big story is always worth surfacing: a good PR person can often find an opaque angle, and our job is to suggest and let the human decide, not to make the drop call. Use `keep` when the bridge is concrete, `monitor_only` when it is weak, absent, or a likely keyword collision. Still record the *real* reason (`keyword_collision`, `off_beat`, `no_profile_bridge`, etc.) in `reason` — the report uses it to rank and flag the suggestion (e.g. ⚠ possible keyword match). The engine enforces this deterministically (`big_story_recall`), so a `reject` here is wasted: it will be upgraded to `monitor_only` anyway.
|
|
38
|
+
- For moderate-to-large stories, err toward breadth: a remote but coherent connection should survive so downstream passes can decide whether there is a real way in.
|
|
39
|
+
- **Promotional / owned content** — a press release (`publication_type` `brand_content`/`newswire`, or a dateline release excerpt) or vendor-authored contributed/thought-leadership, *especially from a named competitor* — is rarely a real opportunity, because pitching a competitor's own content only amplifies them. Do not `reject` it on this basis (preserve recall and let triage make the call); mark it `monitor_only` with reason `competitor_or_promotional` so the standing-triage pass can gate it. The high/major-band ceiling rule above still wins: never `reject` a big-band signal.
|
|
40
|
+
- Use `no_profile_bridge` only when you can explain that no profile entity, competitor, topic, standing term, or plausible buyer/regulator/category bridge appears in the candidate.
|
|
41
|
+
- Preserve evidence URLs. Each decision cites the URLs it used.
|
|
42
|
+
|
|
43
|
+
## Output
|
|
44
|
+
|
|
45
|
+
Return only JSON. No prose before or after it.
|
|
46
|
+
|
|
47
|
+
```json
|
|
48
|
+
{
|
|
49
|
+
"signal_id": "engine signal id",
|
|
50
|
+
"decision": "keep | monitor_only | reject",
|
|
51
|
+
"reason": "allowed reason",
|
|
52
|
+
"rationale": "One short sentence explaining the filter decision.",
|
|
53
|
+
"confidence": "high | medium | low",
|
|
54
|
+
"evidence_urls": ["https://..."],
|
|
55
|
+
"relevance_basis": "Why this is plausibly relevant or why it is junk."
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Handoff
|
|
60
|
+
|
|
61
|
+
Your decision is collected into a `decisions` array and applied by `newsjack filter-apply`: `keep` and `monitor_only` survive to story-origin research; `reject` is dropped. You do not run that step.
|