Syllabus — Course Supplementary Reading List

Generates a curated supplementary reading list from any course syllabus using Consensus academic search.

How to use it

Claude Code
  1. Run the line below. It pulls the whole folder into ~/.claude/skills/syllabus, including the files SKILL.md points to.
  2. Describe your job in plain words. Claude Code follows the skill from there.
Claude Code — installs the whole folder, not just SKILL.md
npx degit alirezarezvani/claude-skills/research/syllabus/skills/syllabus#main ~/.claude/skills/syllabus

For one project only, change the path to .claude/skills/syllabus. This skill also uses Node.js, topic_grouper.py — copying SKILL.md alone won't be enough. See the folder on GitHub.

Claude (web or desktop app)
  1. On this page open ⋯ → Download .md.
  2. Save it as SKILL.md in a folder, zip the folder, then Customize → Skills → + → Create skill → Upload a skill.
  3. Pick the file and Save. Claude shows the name and description and runs a security scan.
  4. Check the skill is switched on.
  5. Start a new chat and describe your job in plain words. The AI follows the skill from there.
ChatGPT or another app
  1. ChatGPT: make a Project and paste it into Instructions.
  2. Neither? Paste it at the top of a new chat — it works for that chat.
Not working?
  • Check which app you pasted it into — the steps above name the right one.
  • Some skills need the paid tier of Claude or ChatGPT.
Step-by-step guide with screenshots · Ask in the forum

Paste into Claude, ChatGPT or Cursor.

Source of Syllabus — Course Supplementary Reading List

Show the full text294 lines
namedescriptionlicensemetadata
syllabusGenerates a curated supplementary reading list from any course syllabus using Consensus academic search. Grill-me intake (syllabus input format + course audience + year range) plus a grouping forcing-options checkpoint before any search runs — so the reading list matches the course's level and recency need. Parses the syllabus to extract topics and learning outcomes, searches Consensus for recent peer-reviewed papers per topic, and produces a professionally formatted .docx with clickable Consensus links, plain-language summaries calibrated to audience level, and Bloom-higher-order discussion questions tied to course learning goals. Use when the user uploads a syllabus, course outline, or curriculum document and wants supplementary readings (e.g., 'create a reading list from this syllabus', 'find recent papers for my course') — even casual mentions with a syllabus attached should trigger this skill.MIT source_spec: "megaprompts/10-syllabus-megaprompt.md build_pattern: "Path B (direct conversion) research_pack_convention: "Agent Integrity Rules verbatim per PR #657 audit; bundled-JS-DOCX-generator variant version: 1.0.0

Syllabus — Course Supplementary Reading List

Portability: Requires a Consensus MCP connection, Node.js with docx package, and file reading capability for the syllabus. Works in Claude Code CLI natively. In Claude.ai with Consensus MCP + Code Execution + file upload, the workflow is supported.

For an instructor or student with a course syllabus, produce a professional supplementary reading list as .docx containing recent peer-reviewed papers per course section.

Architectural Pattern: Bundled Script

This skill uses a bundled JavaScript helper script for DOCX generation rather than inlining the 300+ lines of layout code:

  • DOCX generation logic is reusable + complex
  • Better separation of concerns: skill = orchestration + intelligence; script = mechanical document assembly
  • Token-efficient: skill doesn't re-derive layout each run
  • Easier to maintain and version

The bundled script is at scripts/generate_reading_list.js. The skill orchestrates the pipeline + invokes the script with JSON input.

Agent Integrity Rules (Research-Pack Convention)

Locked verbatim per PR #657 audit.

  • Only use what Consensus returns. Every paper title, author, journal, year, URL must come from this session's tool calls. Training-knowledge papers labeled [Not from Consensus — model knowledge] and excluded.
  • Confirm before moving on. A search isn't complete until response received and inspected.
  • Track three counts. Queries sent / papers received / papers cited. Surface in audit summary.
  • Surface gaps, don't fill them. Section with one paper + note about limited results > section padded with fabrications.

Phase 0: Grill-Me Intake (3 forcing questions)

Q1 (root) — Syllabus input

Provide the syllabus — pick one:

  1. File path (PDF, DOCX, text) — I'll read it
  2. Pasted content — paste below
  3. Image of a printed syllabus — attach the image

Why I'm asking: Each format needs a different reader (PDF / DOCX parser / vision). Picking upfront prevents wasted attempts.

Forcing choice. Refuse to start without a syllabus.

Q2 (depends on Q1) — Course audience

Course audience — pick one:

  1. Undergraduate (intro level)
  2. Undergraduate (advanced / upper division)
  3. Graduate (Masters / early PhD)
  4. Graduate (doctoral / advanced)
  5. Professional / continuing education
  6. Mixed

Why I'm asking: Audience dictates summary jargon level and discussion-question complexity. Undergrad summaries define every term; grad summaries assume technical fluency. Discussion questions for undergrads test analysis; for grads test critique and extension.

See references/audience_calibration.md for the canon.

Q3 (depends on Q1) — Year range

Year range for papers — pick one:

  1. Last 1 year (most recent only)
  2. Last 2 years (default — recent + a year of context)
  3. Last 5 years (broader, includes foundational recent work)

Why I'm asking: Reading lists go stale fast. 1-year filters keep things fresh; 5-year filters surface foundational recent work that's already standard. Drives the year_min parameter on every Consensus search.

Forcing choice with default (last 2 years).

Stop condition: 3 questions max before Phase 1. The post-Phase-2 group-and-confirm checkpoint is its own grill-me moment.

Phase 1: Parse the Syllabus

Per Q1 input format:

  • PDF: use PDF reader; extract text
  • DOCX: use pandoc or DOCX parser; extract text
  • Text/pasted: read directly
  • Image: use vision; extract text

From extracted text:

  1. Course title + instructor + term
  2. Topic list (lecture titles, week-by-week breakdown, etc.)
  3. Learning outcomes (if explicit; if missing, infer 3-5 from description)

Mark inferred learning outcomes as [inferred] in the DOCX.

Phase 2: Group Topics + Confirm with User

Group via topic_grouper.py

Use scripts/topic_grouper.py to cluster related topics into 6-12 sections. Heuristic: closely-related topics merge; cross-cutting topics get their own section.

Group-and-Confirm Checkpoint (Forcing Options)

After grouping, present:

Proposed sections: [list with item counts]. Pick one:

  1. "Looks good — proceed with these sections"
  2. "Merge sections [X] and [Y]"
  3. "Split section [X] into two"
  4. "Add a section for [topic]"
  5. "Remove section [X]"

Why I'm asking: Grouping drives search allocation. Wrong grouping wastes the search budget on bad clusters. This is the last cheap moment to correct course before searches consume Consensus calls.

Refuse to start Phase 3 without explicit user choice.

Phase 3: Search Consensus per Section

Sequential, 1 q/sec. 1-2 queries per section.

Applied-Domain Weaving (Critical)

Don't just search the topic — search the topic + applied domain:

❌ Generic ✅ Applied-domain
"enzyme kinetics" "enzyme kinetics food processing applications"
"machine learning" "machine learning clinical decision support"
"thermodynamics" "thermodynamics renewable energy systems"
"social network analysis" "social network analysis public health interventions"

Boosts paper relevance dramatically. See references/applied_domain_weaving.md for the canon.

Per-Section Pattern
For each section:
  1. Construct query: "{topic-keywords} {applied-domain-angle}" + year_min from Q3
  2. Submit to Consensus (sequential, 1 q/sec gap enforced by citation_tracker)
  3. Receive results
  4. (If thin) submit one fallback query without applied-domain angle
  5. Select 1-3 papers per section (15-25 total across all sections)
Selection Priorities
  1. Relevance — paper directly addresses the section topic
  2. Reviews / meta-analyses — synthesize the field
  3. Citation count — established work
  4. Applied-domain connection — tied to the course's domain (e.g., engineering vs theory)

Phase 4: Write Summaries + Discussion Questions

Summary writing

Per paper:

  • Plain language (calibrated to audience from Q2)
  • 2-3 sentences
  • Define jargon if undergraduate audience; assume fluency if graduate
Quality bars
✅ Good summary ❌ Bad summary
"This review maps how different diets — Mediterranean, Nordic, vegetarian — reshape the types of fat molecules circulating in your blood, with implications for heart disease risk." "This paper reviews lipidomic profiles across dietary interventions and their cardiometabolic implications."
Discussion question writing

Per paper:

  • Bloom higher-order (apply / analyze / evaluate)
  • Tied to a specific course learning outcome
  • Promotes discussion, not just recall
✅ Good question ❌ Bad question
"If dietary fat quality can reshape your lipoprotein lipidome, what does this suggest about the biochemical basis for dietary guidelines recommending unsaturated over saturated fats?" "What did the authors find?" (Just recall)

Use scripts/discussion_question_validator.py to flag recall-only questions.

Phase 5: Generate .docx via Bundled Script

node scripts/generate_reading_list.js \
  --input /tmp/syllabus_data.json \
  --output /path/to/reading_list_<course>_<date>.docx

The script accepts JSON with this schema:

{
  "courseTitle": "string",
  "courseSubtitle": "string",
  "generatedDate": "string",
  "yearRange": "string",
  "introText": "string",
  "learningOutcomes": ["string", ...],
  "sections": [
    {
      "heading": "string",
      "papers": [
        {
          "title": "string",
          "authors": "string",
          "journal": "string",
          "year": number,
          "url": "string",
          "summary": "string",
          "question": "string"
        }
      ]
    }
  ],
  "auditLog": {
    "totalQueriesSent": number,
    "totalPapersReceived": number,
    "totalPapersCited": number,
    "toolConstraints": "string",
    "searchDetails": [
      {
        "section": "string",
        "query": "string",
        "papersReturned": number,
        "papersSelected": number,
        "status": "string"
      }
    ],
    "failures": []
  }
}

The script handles:

  • docx package require with multi-location fallback
  • Title page, intro with Consensus link, learning outcomes box, numbered papers per section
  • ExternalHyperlink with full Consensus URLs (never truncated)
  • LevelFormat.BULLET for lists (not unicode bullets)
  • Footer with generation metadata
  • Input validation (missing fields → graceful error)

See references/bundled_script_pattern.md for why bundled vs inline.

Phase 6: Deliver

  • File path
  • Audit summary in chat: "Saved {file}. {N} sections × {M} papers / {K} cited. Plan tier: {tier}."
  • Validate: check zip integrity with python3 -c "import zipfile,sys; zipfile.ZipFile(sys.argv[1]).testzip()" <docx> (no output = intact), then confirm the required sections are present

Tooling

Script Role
scripts/citation_tracker.py Consensus three-count audit + 1s sequential discipline at ~/.syllabus_sessions/<session>.json
scripts/topic_grouper.py Heuristic 6-12 section grouping from extracted topics
scripts/discussion_question_validator.py Bloom higher-order quality check; flags recall-only questions
scripts/generate_reading_list.js Bundled Node.js DOCX generator — JSON input → .docx output

References

Error Handling

Failure Behavior
Consensus rate-limit hit Wait 3s, retry once, log
Search returns 0 for a section Note section as "limited results — consider manual supplementation"
3 consecutive failures Stop, alert user, share collected so far
docx package not installed Script attempts npm install; if still failing, fail with clear message
DOCX validation fails Unpack XML, log issue, ask user to retry
Syllabus format unsupported List supported formats, ask user to convert
Learning outcomes can't be extracted Infer 3-5 from course description; mark as inferred in document

Anti-Patterns To Reject

  • Parallelizing Consensus calls (rate limit)
  • Searching topics without applied-domain angle (poor relevance)
  • Padding sections with fabricated entries when Consensus returns thin
  • Generic discussion questions ("What did the authors find?")
  • Jargon-heavy summaries unsuitable for the course's audience level
  • Skipping the group-and-confirm step (wastes searches)
  • Truncating Consensus URLs in hyperlinks
  • Inlining 300 lines of docx-generation JavaScript in the skill body (use bundled script)

Version: 1.0.0 Source spec: megaprompts/10-syllabus-megaprompt.md (maintainer-local draft spec — gitignored, not present in the public repository) Build pattern: Path B (direct conversion). Bundled-JS-DOCX-generator variant.

1---
2name: syllabus
3description: "Generates a curated supplementary reading list from any course syllabus using Consensus academic search. Grill-me intake (syllabus input format + course audience + year range) plus a grouping forcing-options checkpoint before any search runs — so the reading list matches the course's level and recency need. Parses the syllabus to extract topics and learning outcomes, searches Consensus for recent peer-reviewed papers per topic, and produces a professionally formatted .docx with clickable Consensus links, plain-language summaries calibrated to audience level, and Bloom-higher-order discussion questions tied to course learning goals. Use when the user uploads a syllabus, course outline, or curriculum document and wants supplementary readings (e.g., 'create a reading list from this syllabus', 'find recent papers for my course') — even casual mentions with a syllabus attached should trigger this skill."
4license: MIT
5metadata:
6 source_spec: "megaprompts/10-syllabus-megaprompt.md"
7 build_pattern: "Path B (direct conversion)"
8 research_pack_convention: "Agent Integrity Rules verbatim per PR #657 audit; bundled-JS-DOCX-generator variant"
9 version: 1.0.0
10---
11 
12# Syllabus — Course Supplementary Reading List
13 
14> **Portability:** Requires a Consensus MCP connection, Node.js with `docx` package, and file reading capability for the syllabus. Works in Claude Code CLI natively. In Claude.ai with Consensus MCP + Code Execution + file upload, the workflow is supported.
15 
16For an instructor or student with a course syllabus, produce a professional supplementary reading list as `.docx` containing recent peer-reviewed papers per course section.
17 
18## Architectural Pattern: Bundled Script
19 
20This skill uses a **bundled JavaScript helper script** for DOCX generation rather than inlining the 300+ lines of layout code:
21 
22- DOCX generation logic is reusable + complex
23- Better separation of concerns: skill = orchestration + intelligence; script = mechanical document assembly
24- Token-efficient: skill doesn't re-derive layout each run
25- Easier to maintain and version
26 
27The bundled script is at `scripts/generate_reading_list.js`. The skill orchestrates the pipeline + invokes the script with JSON input.
28 
29## Agent Integrity Rules (Research-Pack Convention)
30 
31Locked verbatim per PR #657 audit.
32 
33- **Only use what Consensus returns.** Every paper title, author, journal, year, URL must come from this session's tool calls. Training-knowledge papers labeled `[Not from Consensus — model knowledge]` and excluded.
34- **Confirm before moving on.** A search isn't complete until response received and inspected.
35- **Track three counts.** Queries sent / papers received / papers cited. Surface in audit summary.
36- **Surface gaps, don't fill them.** Section with one paper + note about limited results > section padded with fabrications.
37 
38## Phase 0: Grill-Me Intake (3 forcing questions)
39 
40### Q1 (root) — Syllabus input
41 
42> **Provide the syllabus — pick one:**
43>
44> 1. File path (PDF, DOCX, text) — I'll read it
45> 2. Pasted content — paste below
46> 3. Image of a printed syllabus — attach the image
47>
48> *Why I'm asking:* Each format needs a different reader (PDF / DOCX parser / vision). Picking upfront prevents wasted attempts.
49 
50Forcing choice. Refuse to start without a syllabus.
51 
52### Q2 (depends on Q1) — Course audience
53 
54> **Course audience — pick one:**
55>
56> 1. Undergraduate (intro level)
57> 2. Undergraduate (advanced / upper division)
58> 3. Graduate (Masters / early PhD)
59> 4. Graduate (doctoral / advanced)
60> 5. Professional / continuing education
61> 6. Mixed
62>
63> *Why I'm asking:* Audience dictates summary jargon level and discussion-question complexity. Undergrad summaries define every term; grad summaries assume technical fluency. Discussion questions for undergrads test analysis; for grads test critique and extension.
64 
65See [`references/audience_calibration.md`](references/audience_calibration.md) for the canon.
66 
67### Q3 (depends on Q1) — Year range
68 
69> **Year range for papers — pick one:**
70>
71> 1. Last 1 year (most recent only)
72> 2. Last 2 years (default — recent + a year of context)
73> 3. Last 5 years (broader, includes foundational recent work)
74>
75> *Why I'm asking:* Reading lists go stale fast. 1-year filters keep things fresh; 5-year filters surface foundational recent work that's already standard. Drives the year_min parameter on every Consensus search.
76 
77Forcing choice with default (last 2 years).
78 
79**Stop condition:** 3 questions max before Phase 1. The post-Phase-2 group-and-confirm checkpoint is its own grill-me moment.
80 
81## Phase 1: Parse the Syllabus
82 
83Per Q1 input format:
84 
85- **PDF**: use PDF reader; extract text
86- **DOCX**: use pandoc or DOCX parser; extract text
87- **Text/pasted**: read directly
88- **Image**: use vision; extract text
89 
90From extracted text:
911. Course title + instructor + term
922. Topic list (lecture titles, week-by-week breakdown, etc.)
933. Learning outcomes (if explicit; if missing, infer 3-5 from description)
94 
95Mark inferred learning outcomes as `[inferred]` in the DOCX.
96 
97## Phase 2: Group Topics + Confirm with User
98 
99### Group via topic_grouper.py
100 
101Use `scripts/topic_grouper.py` to cluster related topics into 6-12 sections. Heuristic: closely-related topics merge; cross-cutting topics get their own section.
102 
103### Group-and-Confirm Checkpoint (Forcing Options)
104 
105After grouping, present:
106 
107> **Proposed sections: [list with item counts]. Pick one:**
108>
109> 1. "Looks good — proceed with these sections"
110> 2. "Merge sections [X] and [Y]"
111> 3. "Split section [X] into two"
112> 4. "Add a section for [topic]"
113> 5. "Remove section [X]"
114>
115> *Why I'm asking:* Grouping drives search allocation. Wrong grouping wastes the search budget on bad clusters. This is the **last cheap moment** to correct course before searches consume Consensus calls.
116 
117**Refuse to start Phase 3 without explicit user choice.**
118 
119## Phase 3: Search Consensus per Section
120 
121Sequential, 1 q/sec. 1-2 queries per section.
122 
123### Applied-Domain Weaving (Critical)
124 
125Don't just search the topic — **search the topic + applied domain**:
126 
127| ❌ Generic | ✅ Applied-domain |
128|---|---|
129| "enzyme kinetics" | "enzyme kinetics food processing applications" |
130| "machine learning" | "machine learning clinical decision support" |
131| "thermodynamics" | "thermodynamics renewable energy systems" |
132| "social network analysis" | "social network analysis public health interventions" |
133 
134Boosts paper relevance dramatically. See [`references/applied_domain_weaving.md`](references/applied_domain_weaving.md) for the canon.
135 
136### Per-Section Pattern
137 
138```
139For each section:
140 1. Construct query: "{topic-keywords} {applied-domain-angle}" + year_min from Q3
141 2. Submit to Consensus (sequential, 1 q/sec gap enforced by citation_tracker)
142 3. Receive results
143 4. (If thin) submit one fallback query without applied-domain angle
144 5. Select 1-3 papers per section (15-25 total across all sections)
145```
146 
147### Selection Priorities
148 
1491. **Relevance** — paper directly addresses the section topic
1502. **Reviews / meta-analyses** — synthesize the field
1513. **Citation count** — established work
1524. **Applied-domain connection** — tied to the course's domain (e.g., engineering vs theory)
153 
154## Phase 4: Write Summaries + Discussion Questions
155 
156### Summary writing
157 
158Per paper:
159- Plain language (calibrated to audience from Q2)
160- 2-3 sentences
161- Define jargon if undergraduate audience; assume fluency if graduate
162 
163### Quality bars
164 
165| ✅ Good summary | ❌ Bad summary |
166|---|---|
167| "This review maps how different diets — Mediterranean, Nordic, vegetarian — reshape the types of fat molecules circulating in your blood, with implications for heart disease risk." | "This paper reviews lipidomic profiles across dietary interventions and their cardiometabolic implications." |
168 
169### Discussion question writing
170 
171Per paper:
172- Bloom **higher-order** (apply / analyze / evaluate)
173- Tied to a specific course learning outcome
174- Promotes discussion, not just recall
175 
176| ✅ Good question | ❌ Bad question |
177|---|---|
178| "If dietary fat quality can reshape your lipoprotein lipidome, what does this suggest about the biochemical basis for dietary guidelines recommending unsaturated over saturated fats?" | "What did the authors find?" (Just recall) |
179 
180Use `scripts/discussion_question_validator.py` to flag recall-only questions.
181 
182## Phase 5: Generate .docx via Bundled Script
183 
184```bash
185node scripts/generate_reading_list.js \
186 --input /tmp/syllabus_data.json \
187 --output /path/to/reading_list_<course>_<date>.docx
188```
189 
190The script accepts JSON with this schema:
191 
192```json
193{
194 "courseTitle": "string",
195 "courseSubtitle": "string",
196 "generatedDate": "string",
197 "yearRange": "string",
198 "introText": "string",
199 "learningOutcomes": ["string", ...],
200 "sections": [
201 {
202 "heading": "string",
203 "papers": [
204 {
205 "title": "string",
206 "authors": "string",
207 "journal": "string",
208 "year": number,
209 "url": "string",
210 "summary": "string",
211 "question": "string"
212 }
213 ]
214 }
215 ],
216 "auditLog": {
217 "totalQueriesSent": number,
218 "totalPapersReceived": number,
219 "totalPapersCited": number,
220 "toolConstraints": "string",
221 "searchDetails": [
222 {
223 "section": "string",
224 "query": "string",
225 "papersReturned": number,
226 "papersSelected": number,
227 "status": "string"
228 }
229 ],
230 "failures": []
231 }
232}
233```
234 
235The script handles:
236- `docx` package require with multi-location fallback
237- Title page, intro with Consensus link, learning outcomes box, numbered papers per section
238- `ExternalHyperlink` with full Consensus URLs (never truncated)
239- `LevelFormat.BULLET` for lists (not unicode bullets)
240- Footer with generation metadata
241- Input validation (missing fields → graceful error)
242 
243See [`references/bundled_script_pattern.md`](references/bundled_script_pattern.md) for why bundled vs inline.
244 
245## Phase 6: Deliver
246 
247- File path
248- Audit summary in chat: "Saved {file}. {N} sections × {M} papers / {K} cited. Plan tier: {tier}."
249- Validate: check zip integrity with `python3 -c "import zipfile,sys; zipfile.ZipFile(sys.argv[1]).testzip()" <docx>` (no output = intact), then confirm the required sections are present
250 
251## Tooling
252 
253| Script | Role |
254|---|---|
255| `scripts/citation_tracker.py` | Consensus three-count audit + 1s sequential discipline at `~/.syllabus_sessions/<session>.json` |
256| `scripts/topic_grouper.py` | Heuristic 6-12 section grouping from extracted topics |
257| `scripts/discussion_question_validator.py` | Bloom higher-order quality check; flags recall-only questions |
258| `scripts/generate_reading_list.js` | **Bundled Node.js DOCX generator** — JSON input → .docx output |
259 
260## References
261 
262- [`references/applied_domain_weaving.md`](references/applied_domain_weaving.md) — search-quality canon (7+ sources)
263- [`references/audience_calibration.md`](references/audience_calibration.md) — undergrad vs grad summary jargon (7+ sources)
264- [`references/bundled_script_pattern.md`](references/bundled_script_pattern.md) — why bundle vs inline (7+ sources)
265 
266## Error Handling
267 
268| Failure | Behavior |
269|---|---|
270| Consensus rate-limit hit | Wait 3s, retry once, log |
271| Search returns 0 for a section | Note section as "limited results — consider manual supplementation" |
272| 3 consecutive failures | Stop, alert user, share collected so far |
273| `docx` package not installed | Script attempts `npm install`; if still failing, fail with clear message |
274| DOCX validation fails | Unpack XML, log issue, ask user to retry |
275| Syllabus format unsupported | List supported formats, ask user to convert |
276| Learning outcomes can't be extracted | Infer 3-5 from course description; mark as inferred in document |
277 
278## Anti-Patterns To Reject
279 
280- Parallelizing Consensus calls (rate limit)
281- Searching topics without applied-domain angle (poor relevance)
282- Padding sections with fabricated entries when Consensus returns thin
283- Generic discussion questions ("What did the authors find?")
284- Jargon-heavy summaries unsuitable for the course's audience level
285- Skipping the group-and-confirm step (wastes searches)
286- Truncating Consensus URLs in hyperlinks
287- Inlining 300 lines of docx-generation JavaScript in the skill body (use bundled script)
288 
289---
290 
291**Version:** 1.0.0
292**Source spec:** `megaprompts/10-syllabus-megaprompt.md` (maintainer-local draft spec — gitignored, not present in the public repository)
293**Build pattern:** Path B (direct conversion). Bundled-JS-DOCX-generator variant.
294 

Discussion

Alternatives

Also in TrainingSee all 35 in People & hiring →