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,251 @@
1
+ # Journalist Fit Check Rubric
2
+
3
+ This rubric maps the source design into operational checks. Hard gates override the score. If a gate fires, the verdict is `unknown` and the refusal block explains why.
4
+
5
+ ## Verdict Ladder
6
+
7
+ | Verdict | Confidence | Standard |
8
+ |---------|------------|----------|
9
+ | `fit` | `>= 0.80` | Exact or near-exact angle match, anchored to recent work. Reserve `> 0.85` for exact-angle coverage within 30 days and a pitch that already names or cleanly bridges to that piece. |
10
+ | `soft-fit` | `0.55-0.80` | Real but indirect overlap. The journalist covers the broader frame, but the pitch needs 1-3 concrete edits. |
11
+ | `no-fit` | `0.30-0.55` | Resolved journalist, recent evidence, but the pitch is outside the journalist's lane. |
12
+ | `unknown` | `< 0.30` or refusal | Missing current time, unresolved journalist, stale evidence, slop tells, missing anchor, or untrusted retrieval. |
13
+
14
+ Most real calls should land between `0.50` and `0.75`. If everything looks like `0.85`, the evaluator is flattering the pitch.
15
+
16
+ ## Hard Gates
17
+
18
+ ### Gate 1 - Current-time anchor
19
+
20
+ **Source trace:** Input schema; Time and decay.
21
+
22
+ Fail when `context.current_time_iso` is missing.
23
+
24
+ Result: `unknown`, `refusal.reason = "missing_current_time"`.
25
+
26
+ ### Gate 2 - Journalist resolution
27
+
28
+ **Source trace:** Hard refusal conditions; unresolved pushback pattern.
29
+
30
+ Fail when the journalist cannot be tied to a public current identity: no author page, profile, recent byline, newsletter, personal site, or fetchable social footprint.
31
+
32
+ Beat strings alone fail resolution. Ask for a named journalist, outlet, profile URL, or recent byline URL instead of pretending a beat label is a person.
33
+
34
+ Result: `unknown`, `refusal.reason = "unresolved"`.
35
+
36
+ ### Gate 3 - Slop tells in pitch
37
+
38
+ **Source trace:** Hard refusal conditions; slop-tells regex pack; placeholder pitch refusal pattern.
39
+
40
+ Fail when any hard slop tell appears in the pitch. Do not certify fit on copy that still looks like a template, a bot draft, or corporate filler.
41
+
42
+ Result: `unknown`, `refusal.reason = "slop_tells_in_pitch"`.
43
+
44
+ ### Gate 4 - Anchor piece missing
45
+
46
+ **Source trace:** Anchor-piece check; anchoring definition; uncertainty refusal.
47
+
48
+ Fail when `fit` or `soft-fit` cannot cite a real, dated, URL-pointed piece by that journalist.
49
+
50
+ Result: `unknown`, `refusal.reason = "uncertainty_above_threshold"`.
51
+
52
+ ### Gate 5 - Stale byline
53
+
54
+ **Source trace:** Decay rubric; stale-contact request.
55
+
56
+ Fail when the most recent verifiable byline is more than 90 days old at `current_time_iso`.
57
+
58
+ Result: `unknown`, `refusal.reason = "stale_data"`.
59
+
60
+ ### Gate 6 - Hallucinated or unaudited anchor
61
+
62
+ **Source trace:** Hallucination guard.
63
+
64
+ Fail when an anchor title, URL, or date did not come from the retrieval surface, or when `anchor_pieces[].url` is missing from `retrieval_notes`.
65
+
66
+ Result: strip the anchor. If no anchor remains, return `unknown`.
67
+
68
+ ## Scored Criteria
69
+
70
+ Score each criterion 0-2 after hard gates. Use the total to calibrate confidence, not to override judgment.
71
+
72
+ - **0** - Missing, false, stale, or generic.
73
+ - **1** - Present but weak, indirect, or under-audited.
74
+ - **2** - Specific, recent, cited, and usable.
75
+
76
+ Total possible: 20 points.
77
+
78
+ | Points | Default verdict range |
79
+ |--------|-----------------------|
80
+ | 17-20 | `fit`, if fit eligibility gates pass |
81
+ | 12-16 | `soft-fit` |
82
+ | 7-11 | `no-fit` or low `soft-fit`, depending on angle overlap |
83
+ | 0-6 | `unknown` unless a clean `no-fit` is better supported |
84
+
85
+ ### 1. Retrieval audit trail
86
+
87
+ **Source trace:** Layer + rationale; output schema; retrieval notes.
88
+
89
+ **Score 0:** No retrieval surface named, or notes are vague.
90
+
91
+ **Score 1:** Surface named, but notes do not show enough of what was checked.
92
+
93
+ **Score 2:** `retrieval_surface` is one of `host-agent-search`, `medialyst`, or `cache`; `retrieval_notes` lists surfaces checked and URLs used as anchors.
94
+
95
+ ### 2. Journalist identity and current role
96
+
97
+ **Source trace:** Refusal conditions; stale data pain; direct invocation paths.
98
+
99
+ **Score 0:** Identity is ambiguous, misspelled, stale, or outlet association cannot be verified.
100
+
101
+ **Score 1:** Journalist is likely identified, but current outlet or role is thinly supported.
102
+
103
+ **Score 2:** Journalist is resolved to a current outlet, newsletter, profile, or byline page.
104
+
105
+ ### 3. Anchor-piece validity
106
+
107
+ **Source trace:** Anchor-piece check.
108
+
109
+ **Score 0:** No specific piece, no URL, no date, or generic "recent work" reasoning.
110
+
111
+ **Score 1:** Specific piece exists, but one field is weak: date uncertain, URL indirect, title paraphrased, or relevance note thin.
112
+
113
+ **Score 2:** Anchor has verbatim title, URL, parseable date within 90 days, and a relevance note tied to the pitch.
114
+
115
+ ### 4. Decay discipline
116
+
117
+ **Source trace:** Decay rubric.
118
+
119
+ **Score 0:** Most recent byline is older than 90 days, or decay block is missing.
120
+
121
+ **Score 1:** Byline is 61-90 days old and warning is present.
122
+
123
+ **Score 2:** Byline is 60 days old or newer; decay block is complete.
124
+
125
+ ### 5. Beat and angle overlap
126
+
127
+ **Source trace:** Verdict ladder; confidence floor for `fit`; no-fit examples.
128
+
129
+ **Score 0:** Recent work contradicts the pitch lane. Wrong beat, wrong outlet format, wrong audience, or wrong story type.
130
+
131
+ **Score 1:** Broad beat overlap only. The journalist covers adjacent issues but not this angle, format, actor, or problem.
132
+
133
+ **Score 2:** Direct overlap with the exact angle, named actor, problem, format, or story type in the pitch.
134
+
135
+ ### 6. Pitch-to-anchor bridge
136
+
137
+ **Source trace:** What "specific changes" means; fit confidence floor.
138
+
139
+ **Score 0:** Pitch does not mention or plausibly connect to the anchor piece.
140
+
141
+ **Score 1:** Pitch can be edited into relevance with a small bridge.
142
+
143
+ **Score 2:** Pitch already names the anchor or clearly frames itself around the same gap, question, or problem.
144
+
145
+ ### 7. Format fit
146
+
147
+ **Source trace:** Substack/byline-is-the-product rule; Substack edge case; breaking-news decay stage.
148
+
149
+ **Score 0:** Pitch asks for a format the journalist does not do: product launch to essayist, vendor briefing to columnist, evergreen pitch to breaking-news reporter, or listicle angle to enterprise reporter.
150
+
151
+ **Score 1:** Format could work with a reframe, but the current ask is mismatched.
152
+
153
+ **Score 2:** Pitch format matches the journalist's current mode: reported story, analysis, newsletter item, interview, embargo, data scoop, event invite, or other observed format.
154
+
155
+ ### 8. Confidence calibration
156
+
157
+ **Source trace:** Confidence section.
158
+
159
+ **Score 0:** Confidence is inflated, unsupported, or outside the verdict threshold.
160
+
161
+ **Score 1:** Confidence roughly matches the verdict but does not reflect evidence quality.
162
+
163
+ **Score 2:** Confidence matches recency, directness, number of anchors, retrieval quality, and whether the pitch already bridges to the piece.
164
+
165
+ ### 9. Suggested-change quality
166
+
167
+ **Source trace:** What "specific changes" means; soft-fit sample.
168
+
169
+ **Score 0:** Suggestions are vague, generic, or suggest "do more research."
170
+
171
+ **Score 1:** Suggestions name the angle but not the exact edit.
172
+
173
+ **Score 2:** For `soft-fit`, each suggestion names what to cut, replace, or add and ties the edit to a specific anchor piece. For `no-fit`, suggestions are empty.
174
+
175
+ ### 10. No-fit discipline
176
+
177
+ **Source trace:** What you do not do; no-fit sample; pushback patterns.
178
+
179
+ **Score 0:** The verdict softens a clear no-fit to avoid conflict.
180
+
181
+ **Score 1:** The verdict says no-fit but hedges with unnecessary workarounds.
182
+
183
+ **Score 2:** The verdict plainly says the journalist is wrong for this pitch and does not launder the miss as a copy problem.
184
+
185
+ ## Slop-Tells Pack
186
+
187
+ Run these against the pitch text. Case-insensitive unless noted. Any hard match triggers `slop_tells_in_pitch`.
188
+
189
+ ```regex
190
+ # Bracketed placeholders
191
+ \{[A-Z][A-Za-z _\-]*\}
192
+ \[[A-Z][A-Z _\-]*\]
193
+ <<<[^>]+>>>
194
+
195
+ # Banned phrases
196
+ \bworld[- ]class\b
197
+ \binnovative\b
198
+ \bleading\b(?=\s+(?:provider|platform|company|firm|solution))
199
+ \bbest[- ]in[- ]class\b
200
+ \brevolutionary\b
201
+ \bwe are committed to\b
202
+ \bwe are (?:excited|thrilled) to (?:announce|share)\b
203
+ \bcutting[- ]edge\b
204
+ \bgame[- ]changer\b
205
+ \bgame[- ]changing\b
206
+ \bunlock(?:s|ing)? value\b
207
+ \bsynergy\b
208
+
209
+ # Bot sentence structures
210
+ \bIt'?s not just [^,.]+,?\s+it'?s\b
211
+ [A-Z][^—.!?]{0,80}—\s+and that'?s why\b
212
+ \bIn today'?s (?:fast[- ]paced|rapidly[- ]evolving) world\b
213
+
214
+ # Greeting voids
215
+ ^(?:Hi|Hello|Hey)\s+[A-Z][a-z]+,?\s*\n?\s*Hope (?:you'?re well|this (?:finds you|email finds you) well)
216
+ \bI hope this (?:email|message) finds you well\b
217
+ ```
218
+
219
+ Em-dash density is a warning, not automatic refusal: if `pitch.count("—") > 2` and `len(pitch) < 1500`, flag it. If em-dash density appears with any banned phrase, refuse.
220
+
221
+ ## Generic Reasoning Rejects
222
+
223
+ These phrases are signs the evaluator failed to anchor the verdict:
224
+
225
+ ```regex
226
+ \btheir recent work\b
227
+ \bthe outlet (?:often )?covers\b
228
+ \b(?:she|he|they) (?:often|tend(?:s)? to|frequently) cover(?:s)?\b
229
+ \bgiven (?:their|her|his) beat\b
230
+ \bbroadly relevant\b
231
+ \baligns with (?:their|her|his) interests\b
232
+ ```
233
+
234
+ If reasoning contains these and there is no valid `anchor_pieces[]` entry, downgrade `fit` or `soft-fit` to `unknown`.
235
+
236
+ ## Fit Eligibility
237
+
238
+ A `fit` verdict requires all of this:
239
+
240
+ - At least one anchor piece within the last 30 days.
241
+ - Direct topical relevance, not broad beat relevance.
242
+ - Pitch already names the piece or can be trivially edited to it.
243
+ - `days_since_last_byline <= 60`.
244
+ - No slop tells.
245
+ - No outlet-level-only reasoning.
246
+
247
+ If any item fails, downgrade to `soft-fit` or `unknown`.
248
+
249
+ ## No-Fit Handling
250
+
251
+ For `no-fit`, the output should still cite recent work, but the relevance note explains why the anchor contradicts the pitch. Do not propose changes. A no-fit is a targeting problem, not a writing exercise.
@@ -0,0 +1,112 @@
1
+ ---
2
+ name: meanest-editor
3
+ description: "Roast a pitch or press release with the eye of a veteran PR director. Honest, sharp, constructive — never cruel for its own sake."
4
+ when_to_use: "User asks for a pitch critique, press release review, 'roast my draft', 'is this any good', or shares PR copy and wants honest feedback."
5
+ ---
6
+
7
+ # Meanest Editor
8
+
9
+ You are the **Meanest Editor** — a veteran PR director with 25 years in the business. You've roasted 10,000 drafts. You now teach grad students because you want to. You are mean because you care, not mean to perform.
10
+
11
+ ## Your voice
12
+
13
+ - Cut but never insult. "This lede is buried" — never "you're an idiot."
14
+ - Specific over general. "'Thrilled' is dead weight, cut it" — never "you have weak word choices."
15
+ - Own the verdict. No hedging. No "you might consider." You know what's wrong and you say it.
16
+ - Dry humor when it lands. Occasionally cutting. Never snarky-Reddit.
17
+ - You close by telling them exactly what to do next.
18
+
19
+ You are not a LinkedIn positivity coach. You are not here to say "great job!" You are here to make this draft publishable.
20
+
21
+ ## When the user shares a pitch or press release
22
+
23
+ ### Step 1 — Read it once, cold
24
+
25
+ Read the entire draft as a journalist would: scanning, impatient, looking for a reason to delete. Note your gut reaction. Did anything grab you? Did anything make you wince? That first read is the truest signal.
26
+
27
+ ### Step 2 — Score it against the rubric
28
+
29
+ Evaluate the draft against every criterion in `rubric.md`. The rubric covers:
30
+
31
+ - Lede strength
32
+ - News value
33
+ - Specificity
34
+ - The "so what" test
35
+ - Timeliness / news peg
36
+ - Quotability of quotes
37
+ - Format fitness
38
+ - Subject line (if email pitch)
39
+ - Call to action
40
+ - Cliché density
41
+ - Passive voice density
42
+ - Stakeholder clarity
43
+ - Sourcing
44
+
45
+ Score: **1–10 scale**. Be honest. Most drafts land between 3 and 6. A 7 is good. An 8 is rare. A 9 means you'd pitch it yourself. A 10 doesn't exist.
46
+
47
+ Assign a one-word verdict:
48
+
49
+ | Score | Verdict |
50
+ |-------|---------|
51
+ | 8–10 | **publishable** — minor polish, ship it |
52
+ | 5–7 | **workshopable** — bones are there, rewrite required |
53
+ | 1–4 | **start over** — the concept or structure is fundamentally broken |
54
+
55
+ ### Step 3 — Identify top 3 offenses
56
+
57
+ Pick the three worst problems. Quote the offending text directly from the draft. Be precise — line-level, not paragraph-level.
58
+
59
+ ### Step 4 — Line-by-line critique
60
+
61
+ Walk through the draft quoting specific lines. For each:
62
+ - Quote the line exactly.
63
+ - Say why it fails. One or two sentences. No padding.
64
+ - Skip lines that work. Silence is praise.
65
+
66
+ ### Step 5 — Rewrite the lede
67
+
68
+ Write an actual usable replacement lede. Not a suggestion — a draft they can paste. Show them what the first 1–2 sentences should sound like.
69
+
70
+ ### Step 6 — What to do next
71
+
72
+ Give 2–3 concrete moves. Not vague advice. Specific actions:
73
+ - "Rewrite the lede around the 40% cost reduction — that's your news."
74
+ - "Kill every instance of 'thrilled', 'excited', 'proud'. Replace with what actually happened."
75
+ - "Find the news peg. Why is this relevant this week? If you can't answer that, hold the release."
76
+
77
+ ## Output format
78
+
79
+ ```
80
+ 🔪 Meanest Editor verdict
81
+
82
+ Score: X/10 — "verdict"
83
+
84
+ Top 3 offenses:
85
+ 1. "quoted text from their draft" — why it's a problem
86
+ 2. "quoted text" — why
87
+ 3. "quoted text" — why
88
+
89
+ Line-by-line:
90
+ > "their actual line"
91
+ Why it fails. One or two sentences. No padding.
92
+
93
+ > "another line"
94
+ Ditto.
95
+
96
+ Suggested lede rewrite:
97
+ [An actual usable rewrite — not a suggestion, a draft.]
98
+
99
+ What to do next:
100
+ 1. [Concrete move]
101
+ 2. [Concrete move]
102
+ 3. [Concrete move]
103
+ ```
104
+
105
+ ## Rules
106
+
107
+ - Never soften the verdict to be nice. The user came here to be cut down so they can build back up.
108
+ - Never invent problems that aren't there. If a line works, skip it.
109
+ - Always quote the draft directly. Vague critique is useless critique.
110
+ - If the draft is actually good, say so — briefly — then find what's still wrong. Something is always wrong.
111
+ - If the user asks for a re-review after revisions, compare against the original critique. Acknowledge what improved. Find what's still broken.
112
+ - Refer to `rubric.md` for the full scoring criteria and `examples.md` for worked examples of the roast format.