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.
Files changed (54) hide show
  1. package/.mcp.json +9 -0
  2. package/.newsjack-npm +1 -0
  3. package/COMMIT +1 -0
  4. package/LICENSE +21 -0
  5. package/README.md +133 -0
  6. package/VERSION +1 -0
  7. package/bin/newsjack +74 -0
  8. package/package.json +37 -0
  9. package/skills/.gitkeep +0 -0
  10. package/skills/ETHICS.md +265 -0
  11. package/skills/WHY-NOT-SPAM.md +257 -0
  12. package/skills/angle-generator/SKILL.md +224 -0
  13. package/skills/angle-generator/examples.md +517 -0
  14. package/skills/angle-generator/rubric.md +219 -0
  15. package/skills/coverage-tracker/SKILL.md +124 -0
  16. package/skills/coverage-tracker-setup/SKILL.md +84 -0
  17. package/skills/crisis-holding/SKILL.md +336 -0
  18. package/skills/crisis-holding/examples.md +302 -0
  19. package/skills/crisis-holding/rubric.md +218 -0
  20. package/skills/fact-check/SKILL.md +212 -0
  21. package/skills/fact-check/examples.md +195 -0
  22. package/skills/fact-check/rubric.md +228 -0
  23. package/skills/journalist-fit-check/SKILL.md +199 -0
  24. package/skills/journalist-fit-check/examples.md +271 -0
  25. package/skills/journalist-fit-check/rubric.md +251 -0
  26. package/skills/meanest-editor/SKILL.md +112 -0
  27. package/skills/meanest-editor/examples.md +331 -0
  28. package/skills/meanest-editor/rubric.md +275 -0
  29. package/skills/media-list-manager/SKILL.md +204 -0
  30. package/skills/media-list-manager/examples.md +88 -0
  31. package/skills/media-list-manager/rubric.md +67 -0
  32. package/skills/news-search/SKILL.md +56 -0
  33. package/skills/newsjack-detector/SKILL.md +286 -0
  34. package/skills/newsjack-detector/examples.md +118 -0
  35. package/skills/newsjack-detector/references/engine-cli.md +29 -0
  36. package/skills/newsjack-detector/references/harness-routing.md +38 -0
  37. package/skills/newsjack-detector/references/rss-feeds.json +106 -0
  38. package/skills/newsjack-detector/rubric.md +160 -0
  39. package/skills/newsjack-monitor-setup/SKILL.md +202 -0
  40. package/skills/newsjack-monitor-setup/examples.md +106 -0
  41. package/skills/newsjack-triage/SKILL.md +98 -0
  42. package/skills/newsworthiness-check/SKILL.md +179 -0
  43. package/skills/newsworthiness-check/examples.md +232 -0
  44. package/skills/newsworthiness-check/rubric.md +218 -0
  45. package/skills/pr-strategist/SKILL.md +304 -0
  46. package/skills/reactive-comment/SKILL.md +297 -0
  47. package/skills/reactive-comment/examples.md +284 -0
  48. package/skills/reactive-comment/rubric.md +280 -0
  49. package/skills/relevance-coarse-filter/SKILL.md +61 -0
  50. package/skills/story-origin-check/SKILL.md +160 -0
  51. package/skills/voice-extractor/SKILL.md +330 -0
  52. package/skills/voice-extractor/examples.md +227 -0
  53. package/skills/voice-extractor/rubric.md +251 -0
  54. 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.