sc-research 1.0.13 → 1.1.0

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 (31) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +225 -64
  3. package/dist/web/assets/index-Bo0b_RP8.css +1 -0
  4. package/dist/web/assets/{index-sZb3bzqd.js → index-DhbLI1q5.js} +16 -16
  5. package/dist/web/icon.svg +3 -0
  6. package/dist/web/index.html +4 -4
  7. package/dist/web/mocks/classified_controversy.json +122 -0
  8. package/dist/web/mocks/classified_discovery.json +151 -0
  9. package/dist/web/mocks/classified_rank.json +160 -0
  10. package/dist/web/mocks/classified_sentiment.json +52 -0
  11. package/dist/web/mocks/classified_trend.json +175 -0
  12. package/package.json +2 -1
  13. package/templates/base/commands/controversy.md +8 -20
  14. package/templates/base/commands/deep-research.md +8 -19
  15. package/templates/base/commands/discovery.md +10 -22
  16. package/templates/base/commands/quick.md +6 -7
  17. package/templates/base/commands/rank.md +8 -19
  18. package/templates/base/commands/research.md +12 -6
  19. package/templates/base/commands/sentiment.md +8 -20
  20. package/templates/base/commands/trend.md +8 -19
  21. package/templates/base/commands/visualize.md +7 -7
  22. package/templates/base/skills/social_media_controversy.md +53 -23
  23. package/templates/base/skills/social_media_discovery.md +55 -43
  24. package/templates/base/skills/social_media_fetch.md +81 -49
  25. package/templates/base/skills/social_media_rank.md +49 -20
  26. package/templates/base/skills/social_media_schema.md +105 -19
  27. package/templates/base/skills/social_media_sentiment.md +59 -23
  28. package/templates/base/skills/social_media_trend.md +60 -20
  29. package/templates/base/skills/using_social_media_research.md +92 -74
  30. package/dist/web/assets/index-FB2oq23H.css +0 -1
  31. package/dist/web/vite.svg +0 -11
@@ -0,0 +1,175 @@
1
+ {
2
+ "topic": "Sennheiser HD600",
3
+ "date_range": {
4
+ "from": "2024-08-06",
5
+ "to": "2026-02-13"
6
+ },
7
+ "granularity": "month",
8
+ "timeline": [
9
+ {
10
+ "period": "2024-08",
11
+ "post_count": 6,
12
+ "total_engagement": 85,
13
+ "reddit_posts": 6,
14
+ "x_posts": 0
15
+ },
16
+ {
17
+ "period": "2024-09",
18
+ "post_count": 6,
19
+ "total_engagement": 131,
20
+ "reddit_posts": 6,
21
+ "x_posts": 0
22
+ },
23
+ {
24
+ "period": "2024-10",
25
+ "post_count": 0,
26
+ "total_engagement": 0,
27
+ "reddit_posts": 0,
28
+ "x_posts": 0
29
+ },
30
+ {
31
+ "period": "2024-11",
32
+ "post_count": 0,
33
+ "total_engagement": 0,
34
+ "reddit_posts": 0,
35
+ "x_posts": 0
36
+ },
37
+ {
38
+ "period": "2024-12",
39
+ "post_count": 0,
40
+ "total_engagement": 0,
41
+ "reddit_posts": 0,
42
+ "x_posts": 0
43
+ },
44
+ {
45
+ "period": "2025-01",
46
+ "post_count": 6,
47
+ "total_engagement": 219,
48
+ "reddit_posts": 6,
49
+ "x_posts": 0
50
+ },
51
+ {
52
+ "period": "2025-02",
53
+ "post_count": 0,
54
+ "total_engagement": 0,
55
+ "reddit_posts": 0,
56
+ "x_posts": 0
57
+ },
58
+ {
59
+ "period": "2025-03",
60
+ "post_count": 0,
61
+ "total_engagement": 0,
62
+ "reddit_posts": 0,
63
+ "x_posts": 0
64
+ },
65
+ {
66
+ "period": "2025-04",
67
+ "post_count": 6,
68
+ "total_engagement": 65,
69
+ "reddit_posts": 6,
70
+ "x_posts": 0
71
+ },
72
+ {
73
+ "period": "2025-05",
74
+ "post_count": 7,
75
+ "total_engagement": 269,
76
+ "reddit_posts": 6,
77
+ "x_posts": 1
78
+ },
79
+ {
80
+ "period": "2025-06",
81
+ "post_count": 0,
82
+ "total_engagement": 0,
83
+ "reddit_posts": 0,
84
+ "x_posts": 0
85
+ },
86
+ {
87
+ "period": "2025-07",
88
+ "post_count": 1,
89
+ "total_engagement": 297,
90
+ "reddit_posts": 0,
91
+ "x_posts": 1
92
+ },
93
+ {
94
+ "period": "2025-08",
95
+ "post_count": 1,
96
+ "total_engagement": 18,
97
+ "reddit_posts": 0,
98
+ "x_posts": 1
99
+ },
100
+ {
101
+ "period": "2025-09",
102
+ "post_count": 2,
103
+ "total_engagement": 280,
104
+ "reddit_posts": 0,
105
+ "x_posts": 2
106
+ },
107
+ {
108
+ "period": "2025-10",
109
+ "post_count": 2,
110
+ "total_engagement": 26,
111
+ "reddit_posts": 0,
112
+ "x_posts": 2
113
+ },
114
+ {
115
+ "period": "2025-11",
116
+ "post_count": 3,
117
+ "total_engagement": 121,
118
+ "reddit_posts": 0,
119
+ "x_posts": 3
120
+ },
121
+ {
122
+ "period": "2025-12",
123
+ "post_count": 1,
124
+ "total_engagement": 3,
125
+ "reddit_posts": 0,
126
+ "x_posts": 1
127
+ },
128
+ {
129
+ "period": "2026-01",
130
+ "post_count": 2,
131
+ "total_engagement": 11,
132
+ "reddit_posts": 0,
133
+ "x_posts": 2
134
+ },
135
+ {
136
+ "period": "2026-02",
137
+ "post_count": 2,
138
+ "total_engagement": 578,
139
+ "reddit_posts": 0,
140
+ "x_posts": 2
141
+ }
142
+ ],
143
+ "key_moments": [
144
+ {
145
+ "date": "2025-01-10",
146
+ "event": "Discussions highlight HD600 as a 'legendary' collection staple still relevant in 2025",
147
+ "significance": "medium",
148
+ "url": "https://www.reddit.com/r/headphones/comments/1hyeacg"
149
+ },
150
+ {
151
+ "date": "2025-05-01",
152
+ "event": "Sennheiser Summer Sale promotion drives interest with 'sub 19K' pricing mentions",
153
+ "significance": "medium",
154
+ "url": "https://x.com/TechWhirlUlt/status/1917966547483500602"
155
+ },
156
+ {
157
+ "date": "2025-09-17",
158
+ "event": "K-pop idol Gunwook (ZEROBASEONE) mentions using HD600 in fan chat, sparking viral interest",
159
+ "significance": "high",
160
+ "url": "https://x.com/pgwchats/status/1968244315316219980"
161
+ },
162
+ {
163
+ "date": "2026-01-23",
164
+ "event": "Deeply emotional user testimonials on X reinforce the model's 'magical' audio reputation",
165
+ "significance": "low",
166
+ "url": "https://x.com/DVADigital323/status/2014803819603861891"
167
+ },
168
+ {
169
+ "date": "2026-02-03",
170
+ "event": "GoldenSoundHiFi comparison to HD800s via EQ goes viral, proving HD600's technical evergreen status",
171
+ "significance": "high",
172
+ "url": "https://x.com/GoldenSoundHiFi/status/2018637887319822829"
173
+ }
174
+ ]
175
+ }
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "sc-research",
3
- "version": "1.0.13",
3
+ "version": "1.1.0",
4
4
  "description": "Headless Social Media Research Data Provider for AI Agents",
5
+ "license": "MIT",
5
6
  "type": "module",
6
7
  "main": "dist/index.js",
7
8
  "exports": {
@@ -1,28 +1,16 @@
1
1
  ---
2
- description: Find controversial debates in existing research data.
2
+ description: Generate a controversy map from social media data.
3
3
  ---
4
4
 
5
- 1. Check for data existence
5
+ This command produces a controversy analysis. It follows the orchestrated pipeline with controversy as the target.
6
6
 
7
- > Ensure `reddit_data.json` or `x_data.json` exists in the current directory.
7
+ 1. **Ensure raw data exists**
8
8
 
9
- 2. Check freshness for the current request
9
+ > Check if `reddit_data.json` or `x_data.json` exists. If missing or stale, delegate to the `social_media_fetch` skill to fetch fresh data with deep depth.
10
10
 
11
- > Confirm raw data matches the requested topic and date window (if provided). If it does not match, re-fetch with **deep research**: `sc-research research:deep "TOPIC"`.
11
+ 2. **Run analysis**
12
12
 
13
- 3. Run the controversy skill
13
+ > Read the `social_media_controversy` skill instructions and follow them to generate `classified_controversy.json`.
14
14
 
15
- > Use the `social_media_controversy` skill to identify polarizing topics, extract opposing quotes, and generate `classified_controversy.json`.
16
-
17
- 4. Validate output schema
18
-
19
- > Ensure `classified_controversy.json` includes:
20
- >
21
- > - `topic`
22
- > - `overall_divisiveness`
23
- > - `controversies` array
24
- > - each controversy contains `topic`, `heat_score`, `divisiveness`, `side_a`, and `side_b`
25
- > - each side contains `position`, `supporter_count`, and `sample_quote` with `text`, `author`, `link`
26
-
27
- 5. Display the results
28
- > Read `classified_controversy.json` and display controversies with side-by-side opposing views and heat scores.
15
+ 3. **Present results**
16
+ > Display controversies with side-by-side opposing views and heat scores from `classified_controversy.json`.
@@ -1,25 +1,14 @@
1
1
  ---
2
- description: Deeply research a topic and route to the best analysis template. This is the default fetch depth for all templates.
2
+ description: Run deep research on a topic and produce a classified analysis report. This command triggers the full orchestrated pipeline.
3
3
  ---
4
4
 
5
- 1. Run the deep research fetcher
5
+ This command runs the full research pipeline. Follow the `using_social_media_research` orchestrator skill to execute all steps.
6
6
 
7
- > `sc-research research:deep "ARGUMENTS"` (you may also add `--from=YYYY-MM-DD --to=YYYY-MM-DD` for a custom window)
7
+ **Pipeline overview** (orchestrator handles the details):
8
8
 
9
- 2. Route to the right analysis mode
9
+ 1. **Resolve intent** determine which analysis type fits the user's question (rank, sentiment, trend, controversy, discovery, or all).
10
+ 2. **Fetch data** — the orchestrator delegates to `social_media_fetch` to run `sc-research research:deep "ARGUMENTS"` (add `--from=YYYY-MM-DD --to=YYYY-MM-DD` if the user specifies a date range).
11
+ 3. **Analyze** — the orchestrator delegates to the matched worker skill(s) to produce `classified_*.json` output.
12
+ 4. **Present results** — display the analysis summary to the user.
10
13
 
11
- > Follow **Intent Template Routing** rules in `using_social_media_research`.
12
- >
13
- > - If the user explicitly asks for "full analysis", "everything", or "all views": run all 4 templates in order (`rank` -> `sentiment` -> `trend` -> `controversy`).
14
- > - Otherwise: pick the SINGLE most suitable template for the user's question.
15
-
16
- 3. Validate outputs before presenting
17
-
18
- > Confirm the generated `classified_*.json` file(s):
19
- >
20
- > - Match the requested topic (or close variant of the same topic).
21
- > - Match requested date window when `--from/--to` was provided.
22
- > - Include required fields from `../skills/social_media_schema/SKILL.md`.
23
-
24
- 4. Display the results
25
- > Present whichever template output(s) were selected after validation.
14
+ Read the `using_social_media_research` skill now and follow its Step 1 through Step 6.
@@ -1,31 +1,19 @@
1
1
  ---
2
- description: Discover viral topics and emerging themes from existing research data.
2
+ description: Discover viral topics and emerging themes from social media data.
3
3
  ---
4
4
 
5
- 1. Check for data existence
5
+ This command produces a discovery analysis. It follows the orchestrated pipeline with discovery as the target.
6
6
 
7
- > Ensure `reddit_data.json` or `x_data.json` exists in the current directory.
7
+ 1. **Ensure raw data exists**
8
8
 
9
- 2. Check freshness for the current request
10
-
11
- > Confirm raw data matches the requested topic and date window (if provided). If it does not match, re-fetch with **deep research discovery mode**:
9
+ > Check if `reddit_data.json` or `x_data.json` exists. If missing or stale, delegate to the `social_media_fetch` skill to fetch data with `--mode=discovery`:
12
10
  >
13
- > - Broad weekly feed: `sc-research research:deep "DISCOVERY_WEEKLY" --mode=discovery`
14
- > - Topic-focused: `sc-research research:deep "TOPIC" --mode=discovery`
15
- > - Optional filters: add `--source=reddit|x|both --from=YYYY-MM-DD --to=YYYY-MM-DD`
16
-
17
- 3. Run the discovery skill
11
+ > - Broad weekly feed: topic = `DISCOVERY_WEEKLY`
12
+ > - Topic-focused: topic = user's query
18
13
 
19
- > Use the `social_media_discovery` skill to cluster posts by topic and generate `classified_discovery.json`.
14
+ 2. **Run analysis**
20
15
 
21
- 4. Validate output schema
22
-
23
- > Ensure `classified_discovery.json` includes:
24
- >
25
- > - `period`
26
- > - `total_posts_analyzed`
27
- > - `trending_topics` array
28
- > - per topic: `id`, `topic_name`, `description`, `category`, `engagement_score`, `sentiment`, `key_posts`
16
+ > Read the `social_media_discovery` skill instructions and follow them to generate `classified_discovery.json`.
29
17
 
30
- 5. Display the results
31
- > Read `classified_discovery.json` and display the discovered topics with their engagement scores, sentiment, and top posts.
18
+ 3. **Present results**
19
+ > Display discovered topics with engagement scores, sentiment, and top posts from `classified_discovery.json`.
@@ -2,15 +2,14 @@
2
2
  description: Quick research a topic and get a fast text answer (Reddit only, skips X).
3
3
  ---
4
4
 
5
- 1. Run the quick research fetcher (Reddit only)
5
+ 1. **Fetch data (Reddit only)**
6
6
 
7
- > `sc-research research "ARGUMENTS" --source=reddit`
8
- >
9
- > This fetches Reddit data only and skips X for speed. Use `/deep-research` if you need deeper multi-source analysis.
7
+ > Delegate to the `social_media_fetch` skill with: topic = `"ARGUMENTS"`, depth = `quick`, source = `reddit`.
8
+ > This fetches Reddit data only and skips X for speed. Use `/deep-research` for deeper multi-source analysis.
10
9
 
11
- 2. Read the raw data
10
+ 2. **Read the raw data**
12
11
 
13
12
  > Read `reddit_data.json` only. Ignore `x_data.json` even if it exists from a prior run.
14
13
 
15
- 3. Provide a concise answer
16
- > Synthesize a 3-5 sentence answer directly from the Reddit data. Mention the community favorite, 1-2 alternatives, and a real user quote. Do NOT generate any classified files.
14
+ 3. **Provide a concise answer**
15
+ > Synthesize a 35 sentence answer directly from the Reddit data. Mention the community favorite, 12 alternatives, and a real user quote. Do NOT generate any classified files.
@@ -1,27 +1,16 @@
1
1
  ---
2
- description: Rank and classify existing research data.
2
+ description: Generate a ranking report from social media data.
3
3
  ---
4
4
 
5
- 1. Check for data existence
5
+ This command produces a ranked analysis. It follows the orchestrated pipeline with rank as the target.
6
6
 
7
- > Ensure `reddit_data.json` or `x_data.json` exists in the current directory.
7
+ 1. **Ensure raw data exists**
8
8
 
9
- 2. Check freshness for the current request
9
+ > Check if `reddit_data.json` or `x_data.json` exists. If missing or stale, delegate to the `social_media_fetch` skill to fetch fresh data with deep depth.
10
10
 
11
- > Confirm raw data matches the requested topic and date window (if provided). If it does not match, re-fetch with **deep research**: `sc-research research:deep "TOPIC"`.
11
+ 2. **Run analysis**
12
12
 
13
- 3. Run the ranking skill
13
+ > Read the `social_media_rank` skill instructions and follow them to generate `classified_rank.json`.
14
14
 
15
- > Use the `social_media_rank` skill to generate `classified_rank.json` from the existing data files.
16
-
17
- 4. Validate output schema
18
-
19
- > Ensure `classified_rank.json` includes:
20
- >
21
- > - `topic`
22
- > - `key_insights` (array)
23
- > - `products` (array)
24
- > - per product: `rank`, `name`, `sentiment`, `mentions`, `estimated_engagement_score`, `consensus`, `pros`, `cons`
25
-
26
- 5. Display the results
27
- > Read `classified_rank.json` and display key insights plus a summary of the ranked products.
15
+ 3. **Present results**
16
+ > Display key insights and ranked products from `classified_rank.json`.
@@ -1,10 +1,16 @@
1
- 1. Run the research fetcher
1
+ ---
2
+ description: Research a topic and get a concise text answer.
3
+ ---
2
4
 
3
- > `sc-research research "ARGUMENTS"` (optionally add `--from=YYYY-MM-DD --to=YYYY-MM-DD` to focus on a specific date range)
5
+ 1. **Fetch data**
4
6
 
5
- 2. Analyze the results
7
+ > Delegate to the `social_media_fetch` skill with **quick** depth:
8
+ > Topic = `"ARGUMENTS"`, depth = `quick`.
9
+ > Optionally add `--from=YYYY-MM-DD --to=YYYY-MM-DD` if user specifies a date range.
6
10
 
7
- > Read the generated `reddit_data.json` and `x_data.json`.
11
+ 2. **Analyze the results**
8
12
 
9
- 3. Provide an answer
10
- > Based on the data, provide a concise answer including the Community Favorite, decent alternatives, and a representative quote.
13
+ > Read the generated `reddit_data.json` and `x_data.json`.
14
+
15
+ 3. **Provide an answer**
16
+ > Based on the data, provide a concise answer including the Community Favorite, decent alternatives, and a representative quote. Do not produce any `classified_*.json` file.
@@ -1,28 +1,16 @@
1
1
  ---
2
- description: Analyze sentiment from existing research data.
2
+ description: Generate a sentiment analysis report from social media data.
3
3
  ---
4
4
 
5
- 1. Check for data existence
5
+ This command produces a sentiment breakdown. It follows the orchestrated pipeline with sentiment as the target.
6
6
 
7
- > Ensure `reddit_data.json` or `x_data.json` exists in the current directory.
7
+ 1. **Ensure raw data exists**
8
8
 
9
- 2. Check freshness for the current request
9
+ > Check if `reddit_data.json` or `x_data.json` exists. If missing or stale, delegate to the `social_media_fetch` skill to fetch fresh data with deep depth.
10
10
 
11
- > Confirm raw data matches the requested topic and date window (if provided). If it does not match, re-fetch with **deep research**: `sc-research research:deep "TOPIC"`.
11
+ 2. **Run analysis**
12
12
 
13
- 3. Run the sentiment skill
13
+ > Read the `social_media_sentiment` skill instructions and follow them to generate `classified_sentiment.json`.
14
14
 
15
- > Use the `social_media_sentiment` skill to analyze the raw data and generate `classified_sentiment.json`.
16
-
17
- 4. Validate output schema
18
-
19
- > Ensure `classified_sentiment.json` includes:
20
- >
21
- > - `topic`
22
- > - `overall_mood`
23
- > - `distribution` (`very_positive`, `positive`, `mixed`, `negative`)
24
- > - `by_source` with both `reddit` and `x`
25
- > - `product_sentiments`
26
-
27
- 5. Display the results
28
- > Read `classified_sentiment.json` and display the overall mood, sentiment distribution, and per-product sentiment breakdown.
15
+ 3. **Present results**
16
+ > Display overall mood, sentiment distribution, and per-product breakdown from `classified_sentiment.json`.
@@ -1,27 +1,16 @@
1
1
  ---
2
- description: Analyze discussion trends over time from existing research data.
2
+ description: Generate a trend timeline report from social media data.
3
3
  ---
4
4
 
5
- 1. Check for data existence
5
+ This command produces a trend analysis. It follows the orchestrated pipeline with trend as the target.
6
6
 
7
- > Ensure `reddit_data.json` or `x_data.json` exists in the current directory.
7
+ 1. **Ensure raw data exists**
8
8
 
9
- 2. Check freshness for the current request
9
+ > Check if `reddit_data.json` or `x_data.json` exists. If missing or stale, delegate to the `social_media_fetch` skill to fetch fresh data with deep depth.
10
10
 
11
- > Confirm raw data matches the requested topic and date window (if provided). If it does not match, re-fetch with **deep research**: `sc-research research:deep "TOPIC"`.
11
+ 2. **Run analysis**
12
12
 
13
- 3. Run the trend skill
13
+ > Read the `social_media_trend` skill instructions and follow them to generate `classified_trend.json`.
14
14
 
15
- > Use the `social_media_trend` skill to parse dates, choose an adaptive granularity (day/week/month), and generate `classified_trend.json`.
16
-
17
- 4. Validate output schema
18
-
19
- > Ensure `classified_trend.json` includes:
20
- >
21
- > - `topic`
22
- > - `date_range` with `from` and `to`
23
- > - `timeline` entries with `period`, `post_count`, `total_engagement`, `reddit_posts`, `x_posts`
24
- > - `key_moments` entries with `date`, `event`, `significance`
25
-
26
- 5. Display the results
27
- > Read `classified_trend.json` and display timeline activity, engagement trends, and key moments.
15
+ 3. **Present results**
16
+ > Display timeline activity, engagement trends, and key moments from `classified_trend.json`.
@@ -1,14 +1,14 @@
1
1
  ---
2
- description: Launch the visualization dashboard.
2
+ description: Launch the visualization dashboard for classified research data.
3
3
  ---
4
4
 
5
- 1. Check for classified data
5
+ 1. **Check for classified data**
6
6
 
7
- > Ensure at least one `classified_*.json` file exists (e.g., `classified_rank.json`, `classified_sentiment.json`, `classified_trend.json`, `classified_controversy.json`). If none exist, suggest running `/rank`, `/sentiment`, `/trend`, or `/controversy` first.
7
+ > Verify at least one `classified_*.json` file exists (`classified_rank.json`, `classified_sentiment.json`, `classified_trend.json`, `classified_controversy.json`, `classified_discovery.json`). If none exist, suggest running `/deep-research` first.
8
8
 
9
- 2. Launch the visualizer
9
+ 2. **Launch the dashboard**
10
10
 
11
- > `sc-research visualize`
11
+ > `sc-research visualize`
12
12
 
13
- 3. Inform the user
14
- > Tell the user to open the URL provided by the command (usually http://localhost:5173). The dashboard will show tabs for each available classified file.
13
+ 3. **Inform the user**
14
+ > Tell the user to open the URL provided by the command (usually `http://localhost:5173`). The dashboard shows tabs for each available classified file.
@@ -1,36 +1,19 @@
1
1
  ---
2
2
  name: social_media_controversy
3
- description: Analyze existing Reddit/X raw data to identify divisive topics and generate `classified_controversy.json` with strict `ControversyData` output. Use for debate, disagreement, or polarizing-topic requests.
3
+ description: Analysis-only worker. Reads existing raw Reddit/X data to identify divisive topics and generates `classified_controversy.json` with strict `ControversyData` output. Use for debate, disagreement, or polarizing-topic requests.
4
4
  ---
5
5
 
6
6
  # Social Media Controversy Skill
7
7
 
8
- This worker maps where social media opinions conflict and presents both sides with evidence.
8
+ This worker maps where social media opinions conflict and presents both sides with evidence. It performs **analysis only** — fetching is handled by the orchestrator via `social_media_fetch`.
9
9
 
10
- ## Required Inputs
10
+ ## Prerequisites
11
11
 
12
- Use existing raw files only:
12
+ The following files must already exist (produced by `social_media_fetch`):
13
13
 
14
- - `reddit_data.json`
15
- - `x_data.json`
14
+ - `reddit_data.json` and/or `x_data.json`
16
15
 
17
- At least one valid source file must exist.
18
-
19
- ## Command Execution Flow
20
-
21
- Use this sequence for controversy analysis:
22
-
23
- 1. Fetch or refresh raw data (outside this worker):
24
-
25
- - `sc-research research:deep "TOPIC"`
26
- - Optional filters: `--source=reddit|x|both --from=YYYY-MM-DD --to=YYYY-MM-DD`
27
-
28
- 2. Run this `social_media_controversy` worker to generate `classified_controversy.json`.
29
- 3. Optional visualization:
30
-
31
- - `sc-research visualize`
32
-
33
- If raw files are missing, stale, or mismatched for the requested topic/date range, run step 1 first.
16
+ At least one valid source file must be present. If both are missing, **stop and report failure** — do not attempt to fetch data.
34
17
 
35
18
  ## Step 1: Preflight Validation
36
19
 
@@ -94,6 +77,53 @@ Save strict JSON to:
94
77
 
95
78
  - `classified_controversy.json`
96
79
 
80
+ ## Output Type Contract
81
+
82
+ Your output MUST match this exact shape. The dashboard detects controversy data by checking for `overall_divisiveness` (string) + `controversies` (array). Missing either field = broken tab.
83
+
84
+ ```json
85
+ {
86
+ "topic": "AI replacing developers",
87
+ "overall_divisiveness": "High",
88
+ "controversies": [
89
+ {
90
+ "topic": "Will AI make junior devs obsolete?",
91
+ "heat_score": 82,
92
+ "divisiveness": "High",
93
+ "side_a": {
94
+ "position": "AI will eliminate most entry-level coding jobs within 5 years",
95
+ "supporter_count": 45,
96
+ "sample_quotes": [
97
+ {
98
+ "text": "Why would a company hire juniors when Copilot can do 80% of their work?",
99
+ "author": "u/startup_cto",
100
+ "link": "https://reddit.com/r/programming/comments/ghi789"
101
+ }
102
+ ]
103
+ },
104
+ "side_b": {
105
+ "position": "AI is a tool that augments developers, not replaces them",
106
+ "supporter_count": 62,
107
+ "sample_quotes": [
108
+ {
109
+ "text": "Every generation says the same thing. We still need people who understand the problem domain.",
110
+ "author": "u/senior_eng_20yr",
111
+ "link": "https://reddit.com/r/ExperiencedDevs/comments/jkl012"
112
+ }
113
+ ]
114
+ }
115
+ }
116
+ ]
117
+ }
118
+ ```
119
+
120
+ ### Enum Rules for Controversy
121
+
122
+ - `overall_divisiveness`: **Title Case** — `"Low"`, `"Medium"`, `"High"`. NEVER use `"low"`, `"medium"`, `"high"`.
123
+ - `divisiveness` on each controversy: **Title Case** — same as above.
124
+ - `heat_score`: integer `0-100`. NEVER use a value outside this range.
125
+ - `supporter_count`: integer `>= 0`. Use `0` if unknown, NEVER use null.
126
+
97
127
  ## Final Validation Checklist
98
128
 
99
129
  - JSON parse succeeds.