Skill v1.0.1
currentAutomated scan100/100+4 new
version: "1.0.1" name: lumi-reading-chapter-ingest description: > Ingest one book chapter into the wiki and extract character mentions, theme tags, and plot beats into the graph. Use whenever the user wants to ingest, file, or process a chapter — including phrasings like "I just finished chapter 3", "add this chapter to the wiki", "file chapter 2 of [book]", or "track what happened in chapter 5". allowed-tools:
- Bash
- Read
- Write
- Edit
/lumi-reading-chapter-ingest
TL;DR
Turns one chapter (raw text or PDF page range) into a wiki/chapters/<book-slug>/ page, seeds character stubs, records theme tags, writes plot beats, and registers bidirectional edges — all idempotently. Re-running against the same slug is always safe.
All graph and frontmatter mutations go through _lumina/scripts/wiki.mjs. Never edit wiki/graph/edges.jsonl directly. add-edge is idempotent and writes reverse edges automatically except terminal/symmetric cases.
Context
Read README.md at the project root before this SKILL.md.
When to use
Invoke when the user hands you a book chapter — either as raw text pasted inline, a file path under raw/, or a PDF with a page range (e.g. raw/sources/gatsby.pdf 12-34).
This skill follows the reader chapter by chapter, so the wiki never knows more of the book than the user does — that is what keeps /lumi-reading-plot-recap spoiler-safe. If the user instead wants a finished book absorbed whole ("ingest this book", "add the whole book to the wiki"), route to /lumi-ingest — its long-source pipeline reads the entire document and writes page-anchored reading notes. Do not run this skill dozens of times as a substitute, and do not let /lumi-ingest deep-read a novel the user is still reading. This skill writes the chapter page, seeds character stubs, records theme tags, and registers plot beats. It is designed to be run once per chapter and is fully idempotent: re-running against the same chapter slug produces byte-identical output.
Inputs
<book-slug>— kebab-case identifier for the book. All reading-pack pages for this book
live under <book-slug>/ subdirectories. Namespacing is mandatory: a workspace may hold multiple books and the same character name must not collide across books.
<chapter-reference>— one of:- Raw text (pasted or piped)
- A file path:
raw/sources/<book-slug>/<filename> - A PDF page range:
raw/sources/<book-slug>.pdf <start>-<end> <chapter-number>— integer (1-based). Stored asnumber:in frontmatter; used by
plot-recap for spoiler-boundary ordering.
<chapter-title>— human-readable title (converted to slug automatically).
Workflow
Playbook A: Raw text input
- Receive text. Run
node _lumina/scripts/wiki.mjs slug "<chapter-title>" --jsonto get
the canonical slug. Chapter page path: wiki/chapters/<book-slug>/<chapter-slug>.md.
- Check idempotency: if the page already exists, read its frontmatter with
node _lumina/scripts/wiki.mjs read-meta chapters/<book-slug>/<chapter-slug> --json. If number, book, and title match the current inputs, skip page creation and proceed directly to the edge-sync step (step 5). This ensures re-runs are no-ops.
- If the chapter page is new, write the full markdown file with valid frontmatter
and body via Write. For an existing page, update frontmatter with set-meta. Required fields: id, title, type: chapter, created, updated, book, number.
- Extract from the chapter text:
- Character mentions: proper nouns that appear as actors in the narrative. Create a
stub entry for each new character (see character-track skill for full character pages).
- Theme tags: 2-5 thematic labels (e.g.
isolation,class-conflict,memory). - Plot beats: 3-7 one-sentence event summaries in narrative order.
- Register edges using
node _lumina/scripts/wiki.mjs add-edge:
- For each character mentioned:
add-edge chapters/<book-slug>/<chapter-slug> features characters/<book-slug>/<character-slug> - The engine writes the
appears_inreverse edge automatically. - For each theme:
add-edge chapters/<book-slug>/<chapter-slug> tagged_with themes/<book-slug>/<theme-slug> - The engine writes the
appears_inreverse edge automatically.
- Write plot beats into
wiki/plot/<book-slug>/ch<N>-beats.mdwith valid plot
frontmatter (book, up_to_chapter: <N>, etc.) and body.
- Update
wiki/index.mdso the new chapter, character/theme stubs, and plot page are
cataloged. Prefer the workspace linter/index workflow when available; do not edit graph files by hand.
- Append one line through the wiki engine:
``bash node _lumina/scripts/wiki.mjs log reading-chapter-ingest "<book-slug> ch<N> \"<chapter-title>\" -> <K> characters, <M> themes" ` Log entry text: ## [YYYY-MM-DD] reading-chapter-ingest | <book-slug> ch<N> "<chapter-title>" → <K> characters, <M> themes`
- Self-verification: run
node _lumina/scripts/wiki.mjs read-edges chapters/<book-slug>/<chapter-slug> --json
and confirm that at least one features edge and one tagged_with edge are present. If either is missing, add the missing edges before finishing.
- Run
node _lumina/scripts/lint.mjs --jsonwhen the workspace has the linter. Use
--fix only for index/frontmatter fixes that match the user's requested scope.
Playbook B: PDF page range
Follow Playbook A steps, but in step 1 extract text using the bundled tool:
python3 _lumina/tools/extract_pdf.py raw/sources/<book-slug>.pdf --pages <start>-<end>
If the tool exits 3 with pip install pypdf, ask the user to run that and retry. If it warns "may be scanned", inform the user and ask them to paste the text directly. Claude Code's native Read tool also parses PDFs and is an acceptable substitute when running in Claude Code.
Output / DoD
wiki/chapters/<book-slug>/<chapter-slug>.mdexists with valid frontmatter (id, title,
type, created, updated, book, number).
wiki/characters/<book-slug>/<character-slug>.mdstub exists for each mentioned character.wiki/themes/<book-slug>/<theme-slug>.mdstub exists for each tagged theme.wiki/plot/<book-slug>/ch<N>-beats.mdexists with the chapter's plot beats.- Bidirectional edges registered:
features/appears_inandtagged_with/appears_in. wiki/index.mdupdated.wiki/log.mdappended.- Lint/check run where available; unresolved issues are reported with exact slugs.
- Re-running this skill against the same chapter slug produces byte-identical files.
Guardrails
- Use
Writeonly when creating a new page with complete frontmatter. For frontmatter
mutations on an existing page, use wiki.mjs set-meta.
- Graph/frontmatter mutation must go through
_lumina/scripts/wiki.mjs; never edit
wiki/graph/edges.jsonl, generated citation files, or existing frontmatter by raw text edits.
- Do not pass
--booktoadd-edge; the<book-slug>namespace is part of the slug
path, e.g. characters/<book-slug>/<character-slug>.
- Do not add reverse edges manually for
featuresortagged_with;add-edgewrites
appears_in automatically and remains a no-op on re-run.
- Do not infer character genders, ages, or relationships from a single chapter. Record
only what the text states directly.
- Limit theme tags to 2-5 per chapter. Over-tagging dilutes theme pages.
- The
numberfrontmatter field on the chapter page is the authoritative ordering key
for plot-recap. Set it correctly; do not guess.
Examples
<example> Input: user pastes text of chapter 1 of "The Great Gatsby", book-slug great-gatsby, chapter-number 1, title "In My Younger and More Vulnerable Years". Action: slug -> in-my-younger-and-more-vulnerable-years. Writes: wiki/chapters/great-gatsby/in-my-younger-and-more-vulnerable-years.md with number: 1. Extracts characters Nick, Gatsby, Daisy, Tom, Jordan. Themes: class, the-american-dream. Registers 5 features edges + 5 reverse appears_in edges. Writes wiki/plot/great-gatsby/ch1-beats.md. </example>
<example> Input: same chapter, re-run. Action: read-meta returns matching number/book/title -> skip page creation, run edge-sync only -> add-edge calls return no-op (idempotent) -> byte-identical output confirmed. </example>
<example> Input: chapter 2 of the same book, introduces new character "Myrtle". Action: creates wiki/characters/great-gatsby/myrtle.md stub (first_seen: ch2). Adds features/appears_in edges. Existing character pages (Nick, Gatsby) are NOT rewritten by this skill; character-track handles updates. </example>
<example> Input: raw/sources/gatsby.pdf 35-67, chapter 3, title "The Parties Begin". Action: reads pages 35-67, follows Playbook B. If text is extractable, proceeds normally. If scanned, responds: "This PDF appears to be scanned. Please paste the chapter text." </example>