[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6N0GAM8VBZJ8SHV0NXSZFSK":3,"skill-same:01M6N0GAM8VBZJ8SHV0NXSZFSK":89},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":45,"linkOnly":46,"markdownContent":47,"markdownBody":48,"frontMatter":49,"refName":61,"commitSha":62,"skillDirectory":63,"forksCount":64,"repositoryHtmlUrl":65,"repositoryHomepageUrl":6,"ownerHtmlUrl":66,"ownerBlogUrl":67,"ownerDescription":68,"updatedAt":69,"install":70,"resources":82},"01M6N0GAM8VBZJ8SHV0NXSZFSK","book-mirror",null,"Take any book (EPUB\u002FPDF), produce a personalized chapter-by-chapter analysis. Each chapter is preserved in detail (The Chapter) and mirrored back to the reader's actual life (The Mirror) using brain context. The mirror observes and resonates — a friend pointing out parallels, NOT a consultant rearranging the reader's life, NOT a therapist assigning homework. The reader decides what to do about it. Layout is a top-aligned HTML table or stacked sections, never a bare markdown pipe table (pipe tables center-misalign uneven columns). Output is a single brain page at media\u002Fbooks\u002F\u003Cslug>-personalized.md plus an optional PDF via brain-pdf.","garrytan\u002Fgbrain","garrytan","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F19957?v=4","01M6DJCCDDG53MTYYRTXAXFG17","Garry Tan","01M6MZQZCEN3RRMD33E1X9ZZR9",32762,"MIT","https:\u002F\u002Fgithub.com\u002Fgarrytan\u002Fgbrain\u002Fblob\u002Fmaster\u002Fskills\u002Fbook-mirror\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000002","文档处理","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44],"book mirror","book","mirror","brain","bare","\u003Cslug>","at","top","books","consultant","layout","PDF","homework","me","pipe","back","never","markdown","how","Media","analysis","2026-11-10 10:12:30",false,"---\nname: book-mirror\nversion: 0.5.0\ndescription: Take any book (EPUB\u002FPDF), produce a personalized chapter-by-chapter analysis. Each chapter is preserved in detail (The Chapter) and mirrored back to the reader's actual life (The Mirror) using brain context. The mirror observes and resonates — a friend pointing out parallels, NOT a consultant rearranging the reader's life, NOT a therapist assigning homework. The reader decides what to do about it. Layout is a top-aligned HTML table or stacked sections, never a bare markdown pipe table (pipe tables center-misalign uneven columns). Output is a single brain page at media\u002Fbooks\u002F\u003Cslug>-personalized.md plus an optional PDF via brain-pdf.\ntriggers:\n  - \"personalized version of this book\"\n  - \"mirror this book\"\n  - \"two-column book analysis\"\n  - \"apply this book to my life\"\n  - \"how does this book apply to me\"\nmutating: true\nwrites_pages: true\nwrites_to:\n  - media\u002Fbooks\u002F\nupstream: book-mirror@fc834ee\n---\n\n# book-mirror — Personalized Chapter-by-Chapter Book Analysis\n\n> **Convention:** see [_brain-filing-rules.md](..\u002F_brain-filing-rules.md) for the\n> sanctioned `media\u002F\u003Cformat>\u002F\u003Cslug>` exception this skill files under.\n>\n> **Convention:** see [conventions\u002Fquality.md](..\u002Fconventions\u002Fquality.md) for\n> citation rules, back-link enforcement, and output quality bars.\n>\n> **Convention:** see [conventions\u002Fbrain-first.md](..\u002Fconventions\u002Fbrain-first.md)\n> for the lookup chain (brain → search → external) the context-gathering\n> phase follows.\n\n## What this does\n\nGiven a book (EPUB or PDF), produce a brain page where every chapter is\nsummarized in detail on one side (\"The Chapter\") and mirrored back to the\nreader's actual life on the other (\"The Mirror\"), using their own words,\nsituations, people, and patterns from the brain. Output is a brain page at\n`media\u002Fbooks\u002F\u003Cslug>-personalized.md`.\n\nThis is NOT a generic book summary. The mirror is the value: it makes the\nbook read like a smart friend who happens to know the reader's life deeply\nis pointing things out in the margins. The mirror's job is recognition —\n\"that's exactly me\" — and then getting out of the way. If the user wants a\nflat summary instead, route them to a different skill.\n\n## Trust contract (read this before running)\n\nbook-mirror runs as a CLI command (`gbrain book-mirror`), NOT as a pure\nmarkdown skill that the agent dispatches via tools. The CLI is the trusted\nruntime; the skill is the orchestration prose around it.\n\nWhat this means for the agent:\n\n- The CLI submits N read-only subagent jobs (one per chapter). Each subagent\n  has `allowed_tools: ['get_page', 'search']` only. They CANNOT call\n  put_page or any mutating op. They produce markdown analysis via their\n  final message.\n- The CLI reads each child's `job.result`, assembles the final\n  page, and writes it via a single operator-trust `put_page`.\n- This means untrusted EPUB\u002FPDF content cannot prompt-inject any\n  `people\u002F*` page. The trust narrowing happens at the tool allowlist,\n  not at the slug-prefix layer.\n\n## The pipeline\n\n```\n1. ACQUIRE   → User has the EPUB\u002FPDF locally (manual; book-acquisition is\n               not currently shipped — see \"Acquiring the book\" below).\n2. EXTRACT   → Pull chapter text from EPUB\u002FPDF into one .txt per chapter.\n3. CONTEXT   → Gather everything the brain knows about the reader.\n4. ANALYZE   → `gbrain book-mirror` fans out N read-only subagents.\n5. ASSEMBLE  → CLI reads each child result and writes one put_page.\n6. PDF       → Optional: render via skills\u002Fbrain-pdf for delivery.\n```\n\n## 1. Acquiring the book\n\nbook-acquisition (legal-grey-area downloader) was deliberately not shipped\nin this skill wave. The user drops the EPUB\u002FPDF manually. Common paths the\nuser might use:\n\n```bash\n# User-supplied path\nls path\u002Fto\u002Fbook.epub\nls path\u002Fto\u002Fbook.pdf\n\n# Or already in the brain repo (recommended for tracking)\nls $BRAIN_DIR\u002Fmedia\u002Fbooks\u002F\n```\n\nResolve `$BRAIN_DIR` from the gbrain config (`gbrain config get sync.repo_path`)\nor accept it from the user.\n\n## 2. Text extraction\n\nGoal: one `.txt` file per chapter under a temp directory. The agent has\nshell + python access; the CLI is downstream of this and takes the\nextracted directory as input.\n\n### EPUB\n\n```bash\nSLUG=\"this-book\"                                # kebab-case\nWORK=\"$(mktemp -d)\u002F$SLUG\"\nmkdir -p \"$WORK\u002Fchapters\"\nunzip -o path\u002Fto\u002Fbook.epub -d \"$WORK\u002Funpacked\"\n\n# Find content files (XHTML\u002FHTML), sorted (chapter order = sort order)\nfind \"$WORK\u002Funpacked\" -name \"*.xhtml\" -o -name \"*.html\" | sort > \"$WORK\u002Ffiles.txt\"\n\n# Strip HTML to text per chapter\npython3 - \u003C\u003C'PY'\nfrom bs4 import BeautifulSoup\nimport os, sys\nwork = os.environ['WORK']\nfiles = open(f'{work}\u002Ffiles.txt').read().splitlines()\nfor i, path in enumerate(files, 1):\n    html = open(path, encoding='utf-8', errors='replace').read()\n    text = BeautifulSoup(html, 'html.parser').get_text('\\n')\n    text = '\\n'.join(line.strip() for line in text.splitlines() if line.strip())\n    with open(f'{work}\u002Fchapters\u002F{i:02d}.txt', 'w') as f:\n        f.write(text)\nPY\n```\n\nIf `bs4` is missing: `pip3 install beautifulsoup4 lxml`.\n\nInspect the chapter files to identify which are real chapters vs front\nmatter (TOC, copyright, acknowledgments). Often the EPUB ships one file\nper chapter; sometimes multiple chapters per file. Use\n`head -5 \"$WORK\u002Fchapters\u002F\"*.txt` to spot-check.\n\n### PDF\n\n```bash\npdftotext -layout path\u002Fto\u002Fbook.pdf \"$WORK\u002Ffull.txt\"\n```\n\nThen split by chapter heading (look for \"Chapter N\", \"CHAPTER N\", or\nall-caps title lines) using `awk` or `python`. If the PDF is a scan with\nno embedded text, fall back to OCR via `skills\u002Fbrain-pdf` or another\nvision tool.\n\n### Quality check\n\nFor each chapter file:\n\n- Word count > 1500 (typical chapter range 2k–8k words).\n- No HTML tags.\n- Paragraphs preserved with `\\n\\n`.\n\nSave a `chapters\u002FINDEX.md` mapping chapter number → title → file → word\ncount for reference.\n\n## 3. Context gathering\n\nThis is the most critical step. The mirror is only as good as the\ncontext fed to each chapter subagent.\n\n### What to pull\n\n1. **Templates: USER.md and SOUL.md** if the user maintains them\n   (gbrain ships templates at `templates\u002FUSER.md` and `templates\u002FSOUL.md`;\n   they live in the brain repo when populated). Read full.\n2. **Recent daily memory** — last 14 days of brain pages under\n   `wiki\u002Fpersonal\u002Freflections\u002F` or wherever the user files daily notes.\n3. **Topic-relevant brain searches** tuned to the book's themes:\n   - `gbrain query \"marriage\"`, `gbrain query \"couples therapy\"` for a\n     marriage book.\n   - `gbrain query \"founders\"`, `gbrain query \"fundraising\"` for a\n     business book.\n   - `gbrain query \"shame\"`, `gbrain query \"anger\"` for a psychology book.\n4. **Brain pages for relevant entities** — `gbrain query \"\u003Cname>\"` for\n   people who will likely come up.\n5. **Standing patterns** — anything in the user's reflections or\n   originals that's been recurring.\n\n### Deep retrieval (DEFAULT — not optional)\n\nA thin static context pack is the #1 cause of a generic mirror. The\nquality ceiling is the brain itself, not whatever got manually stuffed\ninto one file. Do per-section retrieval before invoking the CLI:\n\n1. Split the book into sections (chapters, parts, or thematic units).\n2. For EACH section, generate 15–20 targeted brain searches based on\n   what the author is saying in that section.\n3. Fetch the top brain pages from those searches.\n4. Fold the retrieved material into the context pack, grouped by chapter,\n   so each chapter subagent sees the pages that map to ITS section.\n\n**Query generation strategy (per section):**\n\n- Literal theme match — what is the author literally talking about?\n- Psychological parallel — what pattern does this map to in the reader's life?\n- Specific incident hunt — what dated events would the author be describing?\n- Relationship\u002Fpeople parallel — who in the reader's life maps to this?\n- Temporal parallel — what period of the reader's life is closest?\n\n**Execution:**\n\n```bash\ngbrain query \"QUERY\" --limit 3\ngbrain get \"PAGE_SLUG\"\n```\n\n**Budget:** 15–20 searches per section × N sections, plus 40–60 full page\nfetches. All local DB queries — essentially free. Target 50–80K chars of\nretrieved brain context total. The chapter subagents also carry read-only\n`search` + `get_page` tools at run time, so the context pack is the floor,\nnot the ceiling — but do not rely on subagents to rediscover what the\norchestrating pass already found.\n\n**Minimum retrieved material for a high-stakes mirror:**\n\n- 40+ brain pages retrieved across all sections.\n- 10+ direct quotes from the reader (verbatim from brain pages).\n- Dated incidents and recurring patterns where available.\n- Coverage across life domains: journal entries and reflections, work and\n  creative output, relationships, public\u002Fcivic life, specific joyful\n  moments, cultural identity — not just the heaviest material.\n\n### Assemble a context pack\n\nWrite everything to a single file the CLI can read:\n\n```bash\nCONTEXT=\"$WORK\u002Fcontext.md\"\n{\n  echo \"## USER.md (if any)\"\n  [ -f \"$BRAIN_DIR\u002FUSER.md\" ] && cat \"$BRAIN_DIR\u002FUSER.md\"\n  echo\n  echo \"## SOUL.md (if any)\"\n  [ -f \"$BRAIN_DIR\u002FSOUL.md\" ] && cat \"$BRAIN_DIR\u002FSOUL.md\"\n  echo\n  echo \"## Recent reflections (last 14 days)\"\n  # Pull recent daily reflections — adapt to the user's filing scheme\n  # ...\n  echo\n  echo \"## Topic-relevant brain pages (grouped per chapter)\"\n  # Deep-retrieval results from above, grouped by the chapter they serve\n  # ...\n  echo\n  echo \"## Themes & cruxes\"\n  # A 1-page summary, written by the agent, calling out:\n  # - What's currently active in the user's life that this book intersects\n  # - Specific quotes from the user that map to book themes\n  # - People and dates that should appear in the mirror\n  # - The anti-repetition constraints (domain map + phrase caps, below)\n} > \"$CONTEXT\"\n```\n\nMake this dense. It's read by every chapter subagent. Encode the\nanti-repetition constraints (next section) here — the per-chapter domain\nassignment and phrase caps only work if every subagent can see them.\n\n## Quality system (hard rules)\n\nThese rules were earned through iteration with cross-modal eval. They are\nmandatory for every book-mirror.\n\n### Principle: the Chapter half IS the variety engine\n\nThe single most important lesson: rich chapter summaries drive varied\nmirrors. When you compress the source material, the mirror has nothing\nto respond to except its own greatest hits. The two halves are symbiotic,\nnot competing for space.\n\n**Rule:** Every distinct idea, story, framework, numbered list item, and\nmemorable phrase the author presents gets its own section. If the author\nlists six kinds of loneliness, that's six sections. If they tell three\nstories, that's three sections. The Chapter half should be detailed enough\nthat someone could skip the book and not lose much. The Mirror half\nresponds to EACH specific idea with a DIFFERENT personal mapping.\n\n### Layout: top-aligned HTML tables OR stacked sections (hard rule)\n\nDo **NOT** emit a bare `| The Chapter | The Mirror |` *markdown* pipe\ntable. GitHub (and most renderers) pad a table row's cells to equal height\nand vertically *center* the shorter cell's text — so when the two halves\ndiffer in length (they always do), one column floats down with a block of\nwhitespace above it. Plain markdown has no per-cell vertical-align. That\nis the root cause, not a styling nit.\n\n**Two valid containers — both are correct, pick by destination:**\n\n1. **Top-aligned HTML table (the CLI default).** The `gbrain book-mirror`\n   chapter prompt already mandates an HTML `\u003Ctable>` with `valign=\"top\"`\n   on EVERY `\u003Ctd>` — this is baked into the trusted runtime. Facts worth\n   knowing when hand-writing or repairing a mirror: GitHub KEEPS\n   `valign=\"top\"` but STRIPS inline `style=\"vertical-align\"`, and does NOT\n   render markdown emphasis inside a raw `\u003Ctd>` — pre-convert emphasis to\n   `\u003Cem>`\u002F`\u003Cstrong>`, and use `\u003Cbr>\u003Cbr>` for paragraph breaks within a\n   cell.\n\n2. **Stacked sections** — best for mobile and chat delivery, and the\n   right choice for any hand-assembled mirror (children's variant,\n   retro-fixes of legacy pages):\n\n   ```markdown\n   ### Chapter N: \u003Ctitle>\n\n   **The Chapter**\n\n   \u003Cchapter prose, normal paragraphs separated by blank lines>\n\n   **The Mirror**\n\n   \u003Cmirror prose, normal paragraphs separated by blank lines>\n   ```\n\n   Use real blank-line paragraph breaks, never `\u003Cbr>\u003Cbr>` outside a table\n   cell. Reads top-to-top every time, zero alignment bug. The\n   Chapter\u002FMirror naming and the one-section-per-idea richness rule are\n   unchanged — only the container changes.\n\n### Anti-repetition (hard constraints, not vibes)\n\n\"Be more varied\" doesn't work as an instruction. LLMs remix the deck\nthey're given — if the deck is 6 cards, you get 6 cards N times. Use hard\nconstraints, written into the context pack's \"Themes & cruxes\" section:\n\n1. **Domain mapping:** Before writing, assign each chapter a PRIMARY life\n   domain (career, family, civic work, creative life, a specific\n   relationship, childhood, intellectual life, spiritual practice, etc.).\n   No two adjacent chapters should share the same primary domain.\n\n2. **Phrase caps:** No word or phrase may appear as a thematic anchor in\n   more than 3 chapters. Identify the reader's \"greatest hits\" (the 5–6\n   themes that would dominate without constraints) and set explicit\n   limits or bans.\n\n3. **Story deduplication:** Before writing each mirror, check: \"Have I\n   already used this story\u002Fincident\u002Fquote in a previous chapter?\" If yes,\n   find a different one.\n\n4. **Emotional range requirement:** At least 25% of chapters must map to\n   JOY, HUMOR, CREATIVE EXCITEMENT, or VICTORY — not only wounds and\n   struggle. When the author describes something beautiful, the mirror\n   should find something beautiful in the reader's life.\n\n### The editorial rule (THE MOST IMPORTANT RULE)\n\nDeep retrieval is the engine, not the product. The reader should never\nfeel like they're reading a research paper or a search results page.\nThe mirror must read like a brilliant essay by someone who knows the\nreader deeply — not a report proving it did homework.\n\n**The test:** If you remove all citations and source attributions, does\nthe mirror still make the reader feel seen? Does it still produce\nepiphanies? Does it still work as standalone writing? If yes, the\nretrieval served its purpose. If the mirror only works because of its\ncitations, the retrieval failed.\n\n**Citations:** Optional. Use sparingly as footnotes when the source adds\ngenuine value (\"you wrote this at 19\" lands differently when the reader\nknows you actually read the journal entry). But never let citations\nbecome the point. Never let the mirror read like it's performing\nthoroughness.\n\n### Cross-modal eval gate (recommended for high-stakes mirrors)\n\nAfter generating a mirror, run `gbrain eval cross-modal` (or the manual\ngate in `skills\u002Fcross-modal-review\u002FSKILL.md`) with these custom\ndimensions:\n\n- VARIETY (fresh each chapter?)\n- SPECIFICITY (real stories\u002Fdates\u002Fquotes?)\n- DEPTH (new insight vs restating profile?)\n- LEFT_COLUMN_FIDELITY (preserves the book?)\n- EMOTIONAL_RANGE (joy as well as struggle?)\n\n```bash\ngbrain eval cross-modal --slug \u003Cslug>-personalized \\\n  --dimensions VARIETY,SPECIFICITY,DEPTH,LEFT_COLUMN_FIDELITY,EMOTIONAL_RANGE\n```\n\nPass threshold: all dimensions average 7+ across models. If any dimension\nis below 6, rebuild with targeted fixes. The eval→fix→re-eval cycle is the\nquality multiplier. Evaluator model pairs and refusal routing follow\n[conventions\u002Fcross-modal.yaml](..\u002Fconventions\u002Fcross-modal.yaml).\n\n### Children's book variant\n\nFor picture books and children's books (under ~5K words), use a\n**Parent's Reading Guide** format instead of the standard mirror:\n\n- The Chapter half: what the book says on each page\u002Fspread.\n- The Mirror half: written FOR THE PARENT reading aloud — what each page\n  will feel like, what the child might ask at each age, what to say if\n  they do, and what the book is really teaching underneath the simple\n  words.\n- Include: when to read it, how to handle specific reactions, and the\n  book's deeper structure mapped to developmental psychology research.\n- Tone: warm, practical, specific to the reader's children by name and\n  age (from brain context).\n\nHand-assembled variants like this use the stacked-sections container.\n\n## 4. Analysis: invoke `gbrain book-mirror`\n\n```bash\ngbrain book-mirror \\\n  --chapters-dir \"$WORK\u002Fchapters\" \\\n  --context-file \"$CONTEXT\" \\\n  --slug \"$SLUG\" \\\n  --title \"Book Title Goes Here\" \\\n  --author \"Author Name\" \\\n  --model claude-opus-4-7\n```\n\nThe CLI:\n\n- Validates inputs and loads chapter files.\n- Prints a cost estimate (~$0.30\u002Fchapter at Opus) and prompts to confirm.\n- Submits N child subagent jobs with read-only `allowed_tools`.\n- Waits for every child to complete.\n- Reads each child's `job.result` (the markdown analysis text).\n- Assembles all chapters into one page with frontmatter + intro + per-chapter\n  sections + closing.\n- Writes ONE `put_page` to `media\u002Fbooks\u002F\u003Cslug>-personalized.md`.\n- Reports a JSON envelope on stdout:\n  `{\"slug\": \"...\", \"chapters_total\": N, \"chapters_completed\": N, \"chapters_failed\": 0}`.\n\nIf any chapter failed, the CLI exits 1 and the user can re-run — idempotency\nkeys (`book-mirror:\u003Cslug>:ch-\u003CN>`) deduplicate completed chapters at the\nqueue level, so retry is cheap. Note that reproducing verbatim book quotes\nplus the reader's verbatim words can occasionally trip a provider output\nfilter; a chapter blocked that way is just a failed chapter — re-run, or\nretry with a different `--model`.\n\n### Model: Opus by default\n\nThe default model is `claude-opus-4-7`. Sonnet works (use `--model\nclaude-sonnet-4-6`) but the mirror quality drops noticeably — the\ntexture that makes the analysis feel like it was written by someone who\nknows the reader needs Opus-grade reasoning.\n\n### Cost gate\n\nThe CLI refuses to spend in a non-TTY context without `--yes`. CI \u002F scripted\ninvocations must pass `--yes` explicitly. TTY users get a `[y\u002FN]` prompt\nbefore submission.\n\nDeep retrieval raises total cost meaningfully versus a thin static\ncontext pack (roughly an order of magnitude at Opus rates). The quality\njump is worth it for a book the reader cares about; use a static pack\nonly for low-stakes runs.\n\n## 5. PDF (optional)\n\nAfter the brain page is written (the CLI already did the `put_page`),\nrender to PDF using `skills\u002Fbrain-pdf`:\n\n```bash\n# See skills\u002Fbrain-pdf\u002FSKILL.md for the invocation.\n```\n\nIf the user asked for a deliverable, prefer the PDF over sending raw\nmarkdown — the brain page is the source of truth; the PDF is the artifact\nthat travels.\n\n## 6. Fact-check and cross-link\n\nAfter the page lands, run a fact-check pass on factual claims about the\nreader (parents, siblings, marriage history, jobs, heritage). Common error\npatterns to look for:\n\n- Conflating the reader's parents' relationship with patterns in extended\n  family.\n- Inventing backstory (\"after his parents' divorce…\") when the\n  reader's parents are still together.\n- Wrong number\u002Fage of children, wrong spouse \u002F kid \u002F sibling names.\n\nIf you can't verify a claim, remove it. Better to lose texture than to\nintroduce a falsehood.\n\nCross-link entities mentioned in the analysis:\n\n- For every person the mirror references with a brain page, add a\n  back-link from `people\u002F\u003Cslug>` to the new `media\u002Fbooks\u002F\u003Cslug>-personalized`\n  page (per `conventions\u002Fquality.md` Iron Law).\n\n## Quality bar (the bar)\n\nThe **Chapter half** should:\n\n- Preserve the author's actual stories, statistics, frameworks, examples.\n- Quote memorable phrases verbatim.\n- Be detailed enough that the reader could skip the book and not lose much.\n\nThe **Mirror half** should:\n\n- Use the reader's *actual quoted words* from the context pack.\n- Reference *specific* dates, situations, people by name.\n- Read like a smart friend who happens to know the reader's life deeply —\n  pointing things out, not giving instructions.\n- **OBSERVE, never PRESCRIBE.** The mirror holds up a reflection. The\n  reader decides what to do about it. No directives, no action items, no\n  \"you should,\" no \"consider whether,\" no rearranging of the reader's life.\n- Frame connections as observations or gentle nudges: \"This is the same\n  pattern as…\" or \"Hard not to hear echoes of…\" — NOT \"You need to\n  address this\" or \"Apply this framework to your Q3 planning.\"\n- Be plain about direct hits (\"This is exactly the [name a real situation]\").\n- Be honest about misses (\"This chapter is less directly relevant\n  because…\"). Don't force connections.\n- **Resonant, not actionable.** The mirror's job is recognition, not\n  instruction. \"That's exactly what we're doing\" is the win. \"Here's a\n  7-point plan to fix it\" is overstepping.\n- **For team mirrors:** Name team members for context (\"this connects to\n  what a teammate does\"), NEVER for task assignment (\"teammate: do X by\n  Friday\"). Don't invent organizational policies, veto chains, checklists,\n  or structural decisions the team hasn't made. Only reference decisions\n  that are in the team's actual documents. Frame everything else as\n  questions or observations.\n\nThe **whole document** should feel like one coherent voice, calibrated to\nthe reader's actual life rather than a generic profile, and honest about\nwhere the book's framing breaks down for this specific reader. It should\nmake the reader feel SEEN, not studied — and work as good standalone\nwriting even with every citation stripped.\n\n## Anti-patterns (do not do these)\n\n- ❌ **Skimming chapters.** Standing instruction: preserve detail.\n- ❌ **Generic mirror.** \"This might apply if you've ever felt…\" →\n  kill on sight.\n- ❌ **Factual errors about the reader's life.** Always fact-check after\n  assembly.\n- ❌ **Giving the subagent put_page access.** Trust contract is read-only;\n  the CLI does the writing.\n- ❌ **Forcing connections.** If a chapter doesn't apply, say so plainly.\n- ❌ **Sycophancy or moralizing in the mirror.** No \"you should…\",\n  no \"consider…\", no \"perhaps it's time to…\".\n- ❌ **Consultant mode.** The mirror is not a strategy deck. No action\n  items, no task assignments to named people, no invented policies or org\n  structures, no \"audit this quarterly,\" no numbered implementation\n  checklists. The mirror OBSERVES and RESONATES. It's a friend at a bar\n  saying \"this part is so us\" — not a consulting engagement. If the\n  reader wants to turn an observation into a plan, that's their move.\n  Not ours.\n- ❌ **Inventing rules the reader never said.** Veto chains, editorial\u002F\n  marketing separations, ombudsperson structures, campaign checklists —\n  if the reader didn't establish it, the mirror can't declare it. Frame\n  it as a question the author would ask (\"who has the veto here?\") or\n  don't include it.\n- ❌ **Truncating the Chapter half.** The book's actual content needs to\n  survive. This is the #1 quality failure — rich chapter = varied mirror.\n- ❌ **Bare markdown pipe tables.** They center-misalign uneven cells on\n  GitHub and most renderers. HTML `\u003Ctable>` with `valign=\"top\"` on every\n  `\u003Ctd>`, or stacked sections. See the layout hard rule above.\n- ❌ **Repeating the same 5–6 themes across all chapters.** Use the domain\n  mapping and phrase caps from the quality system.\n- ❌ **Thin context pack.** If the context pack is just USER.md bullets,\n  the mirror will be generic. Invest in deep retrieval.\n- ❌ **Skipping the eval gate on high-stakes mirrors.** At minimum, run a\n  self-check: count mentions of key themes across chapters. If any theme\n  appears in more than 3 chapters, fix before delivering.\n\n## Output checklist\n\n- [ ] Book file exists locally (path known).\n- [ ] Chapter texts under `$WORK\u002Fchapters\u002F*.txt` with sane word counts.\n- [ ] Context pack at `$WORK\u002Fcontext.md` is dense: deep-retrieval results\n      grouped per chapter + domain map + phrase caps.\n- [ ] `gbrain book-mirror --chapters-dir … --context-file … --slug … --title …` returned exit 0.\n- [ ] `media\u002Fbooks\u002F\u003Cslug>-personalized.md` exists in the brain.\n- [ ] Layout check: no bare markdown pipe tables in the page.\n- [ ] Anti-repetition self-check: no theme anchors more than 3 chapters.\n- [ ] Fact-check pass complete (no errors against USER.md or other source-of-truth pages).\n- [ ] Cross-links added from referenced people\u002Fcompanies.\n- [ ] Optional: cross-modal eval gate passed (all dimensions 7+).\n- [ ] Optional: PDF rendered via brain-pdf and delivered.\n\n## Related skills\n\n- `skills\u002Fbrain-pdf\u002FSKILL.md` — render the personalized page to PDF.\n- `skills\u002Fstrategic-reading\u002FSKILL.md` — read a book through a specific\n  problem-lens instead of personalizing to the whole reader.\n- `skills\u002Farticle-enrichment\u002FSKILL.md` — same shape applied to articles\n  rather than books.\n- `skills\u002Fcross-modal-review\u002FSKILL.md` — the manual second-model quality\n  gate; `gbrain eval cross-modal` is the scripted sibling surface.\n\n\n## Contract\n\nThis skill guarantees:\n\n- Routing matches the canonical triggers in the frontmatter.\n- Output written under the directories listed in `writes_to:` (when applicable).\n- Conventions referenced (`quality.md`, `brain-first.md`, `_brain-filing-rules.md`) are followed.\n- Privacy contract preserved: no real names, no fork-specific filesystem path literals, no upstream-fork references.\n\nThe full behavior contract is documented in the body sections above; this section exists for the conformance test.\n\n## Output Format\n\nThe skill's output shape is documented inline in the body sections above (see \"Output\", \"Brain page format\", or equivalent). The literal section header here exists for the conformance test (`test\u002Fskills-conformance.test.ts`).\n\n## When it fails\n\nFollow the [agent operator protocol](..\u002Fconventions\u002Fagent-operator-protocol.md) for any gbrain error `code`, exit code, `[AGENT]` block or notice block. Specific to this skill:\n\n- The CLI stops for cost confirmation (exit 3, or a non-TTY refusal without `--yes`): relay the per-chapter estimate and wait for the user's agreement before adding `--yes`.\n- A paid run stops with `no_pricing` under a user cost cap: look up the model's per-token rate, tell the user, and after they agree ask the brain host's operator to run `gbrain pricing set \u003Cmodel> --input \u003Cusd-per-1M> --output \u003Cusd-per-1M>`; then retry.\n- Exit 1 with `chapters_failed > 0`: the finished chapters are kept; re-run the same command to retry only the failed ones and tell the user how many chapters are still missing.\n\n## Anti-Patterns\n\nThe full anti-pattern list is in the body sections above; this header exists for the conformance test if the body uses a different casing.\n","# book-mirror — Personalized Chapter-by-Chapter Book Analysis\n\n> **Convention:** see [_brain-filing-rules.md](..\u002F_brain-filing-rules.md) for the\n> sanctioned `media\u002F\u003Cformat>\u002F\u003Cslug>` exception this skill files under.\n>\n> **Convention:** see [conventions\u002Fquality.md](..\u002Fconventions\u002Fquality.md) for\n> citation rules, back-link enforcement, and output quality bars.\n>\n> **Convention:** see [conventions\u002Fbrain-first.md](..\u002Fconventions\u002Fbrain-first.md)\n> for the lookup chain (brain → search → external) the context-gathering\n> phase follows.\n\n## What this does\n\nGiven a book (EPUB or PDF), produce a brain page where every chapter is\nsummarized in detail on one side (\"The Chapter\") and mirrored back to the\nreader's actual life on the other (\"The Mirror\"), using their own words,\nsituations, people, and patterns from the brain. Output is a brain page at\n`media\u002Fbooks\u002F\u003Cslug>-personalized.md`.\n\nThis is NOT a generic book summary. The mirror is the value: it makes the\nbook read like a smart friend who happens to know the reader's life deeply\nis pointing things out in the margins. The mirror's job is recognition —\n\"that's exactly me\" — and then getting out of the way. If the user wants a\nflat summary instead, route them to a different skill.\n\n## Trust contract (read this before running)\n\nbook-mirror runs as a CLI command (`gbrain book-mirror`), NOT as a pure\nmarkdown skill that the agent dispatches via tools. The CLI is the trusted\nruntime; the skill is the orchestration prose around it.\n\nWhat this means for the agent:\n\n- The CLI submits N read-only subagent jobs (one per chapter). Each subagent\n  has `allowed_tools: ['get_page', 'search']` only. They CANNOT call\n  put_page or any mutating op. They produce markdown analysis via their\n  final message.\n- The CLI reads each child's `job.result`, assembles the final\n  page, and writes it via a single operator-trust `put_page`.\n- This means untrusted EPUB\u002FPDF content cannot prompt-inject any\n  `people\u002F*` page. The trust narrowing happens at the tool allowlist,\n  not at the slug-prefix layer.\n\n## The pipeline\n\n```\n1. ACQUIRE   → User has the EPUB\u002FPDF locally (manual; book-acquisition is\n               not currently shipped — see \"Acquiring the book\" below).\n2. EXTRACT   → Pull chapter text from EPUB\u002FPDF into one .txt per chapter.\n3. CONTEXT   → Gather everything the brain knows about the reader.\n4. ANALYZE   → `gbrain book-mirror` fans out N read-only subagents.\n5. ASSEMBLE  → CLI reads each child result and writes one put_page.\n6. PDF       → Optional: render via skills\u002Fbrain-pdf for delivery.\n```\n\n## 1. Acquiring the book\n\nbook-acquisition (legal-grey-area downloader) was deliberately not shipped\nin this skill wave. The user drops the EPUB\u002FPDF manually. Common paths the\nuser might use:\n\n```bash\n# User-supplied path\nls path\u002Fto\u002Fbook.epub\nls path\u002Fto\u002Fbook.pdf\n\n# Or already in the brain repo (recommended for tracking)\nls $BRAIN_DIR\u002Fmedia\u002Fbooks\u002F\n```\n\nResolve `$BRAIN_DIR` from the gbrain config (`gbrain config get sync.repo_path`)\nor accept it from the user.\n\n## 2. Text extraction\n\nGoal: one `.txt` file per chapter under a temp directory. The agent has\nshell + python access; the CLI is downstream of this and takes the\nextracted directory as input.\n\n### EPUB\n\n```bash\nSLUG=\"this-book\"                                # kebab-case\nWORK=\"$(mktemp -d)\u002F$SLUG\"\nmkdir -p \"$WORK\u002Fchapters\"\nunzip -o path\u002Fto\u002Fbook.epub -d \"$WORK\u002Funpacked\"\n\n# Find content files (XHTML\u002FHTML), sorted (chapter order = sort order)\nfind \"$WORK\u002Funpacked\" -name \"*.xhtml\" -o -name \"*.html\" | sort > \"$WORK\u002Ffiles.txt\"\n\n# Strip HTML to text per chapter\npython3 - \u003C\u003C'PY'\nfrom bs4 import BeautifulSoup\nimport os, sys\nwork = os.environ['WORK']\nfiles = open(f'{work}\u002Ffiles.txt').read().splitlines()\nfor i, path in enumerate(files, 1):\n    html = open(path, encoding='utf-8', errors='replace').read()\n    text = BeautifulSoup(html, 'html.parser').get_text('\\n')\n    text = '\\n'.join(line.strip() for line in text.splitlines() if line.strip())\n    with open(f'{work}\u002Fchapters\u002F{i:02d}.txt', 'w') as f:\n        f.write(text)\nPY\n```\n\nIf `bs4` is missing: `pip3 install beautifulsoup4 lxml`.\n\nInspect the chapter files to identify which are real chapters vs front\nmatter (TOC, copyright, acknowledgments). Often the EPUB ships one file\nper chapter; sometimes multiple chapters per file. Use\n`head -5 \"$WORK\u002Fchapters\u002F\"*.txt` to spot-check.\n\n### PDF\n\n```bash\npdftotext -layout path\u002Fto\u002Fbook.pdf \"$WORK\u002Ffull.txt\"\n```\n\nThen split by chapter heading (look for \"Chapter N\", \"CHAPTER N\", or\nall-caps title lines) using `awk` or `python`. If the PDF is a scan with\nno embedded text, fall back to OCR via `skills\u002Fbrain-pdf` or another\nvision tool.\n\n### Quality check\n\nFor each chapter file:\n\n- Word count > 1500 (typical chapter range 2k–8k words).\n- No HTML tags.\n- Paragraphs preserved with `\\n\\n`.\n\nSave a `chapters\u002FINDEX.md` mapping chapter number → title → file → word\ncount for reference.\n\n## 3. Context gathering\n\nThis is the most critical step. The mirror is only as good as the\ncontext fed to each chapter subagent.\n\n### What to pull\n\n1. **Templates: USER.md and SOUL.md** if the user maintains them\n   (gbrain ships templates at `templates\u002FUSER.md` and `templates\u002FSOUL.md`;\n   they live in the brain repo when populated). Read full.\n2. **Recent daily memory** — last 14 days of brain pages under\n   `wiki\u002Fpersonal\u002Freflections\u002F` or wherever the user files daily notes.\n3. **Topic-relevant brain searches** tuned to the book's themes:\n   - `gbrain query \"marriage\"`, `gbrain query \"couples therapy\"` for a\n     marriage book.\n   - `gbrain query \"founders\"`, `gbrain query \"fundraising\"` for a\n     business book.\n   - `gbrain query \"shame\"`, `gbrain query \"anger\"` for a psychology book.\n4. **Brain pages for relevant entities** — `gbrain query \"\u003Cname>\"` for\n   people who will likely come up.\n5. **Standing patterns** — anything in the user's reflections or\n   originals that's been recurring.\n\n### Deep retrieval (DEFAULT — not optional)\n\nA thin static context pack is the #1 cause of a generic mirror. The\nquality ceiling is the brain itself, not whatever got manually stuffed\ninto one file. Do per-section retrieval before invoking the CLI:\n\n1. Split the book into sections (chapters, parts, or thematic units).\n2. For EACH section, generate 15–20 targeted brain searches based on\n   what the author is saying in that section.\n3. Fetch the top brain pages from those searches.\n4. Fold the retrieved material into the context pack, grouped by chapter,\n   so each chapter subagent sees the pages that map to ITS section.\n\n**Query generation strategy (per section):**\n\n- Literal theme match — what is the author literally talking about?\n- Psychological parallel — what pattern does this map to in the reader's life?\n- Specific incident hunt — what dated events would the author be describing?\n- Relationship\u002Fpeople parallel — who in the reader's life maps to this?\n- Temporal parallel — what period of the reader's life is closest?\n\n**Execution:**\n\n```bash\ngbrain query \"QUERY\" --limit 3\ngbrain get \"PAGE_SLUG\"\n```\n\n**Budget:** 15–20 searches per section × N sections, plus 40–60 full page\nfetches. All local DB queries — essentially free. Target 50–80K chars of\nretrieved brain context total. The chapter subagents also carry read-only\n`search` + `get_page` tools at run time, so the context pack is the floor,\nnot the ceiling — but do not rely on subagents to rediscover what the\norchestrating pass already found.\n\n**Minimum retrieved material for a high-stakes mirror:**\n\n- 40+ brain pages retrieved across all sections.\n- 10+ direct quotes from the reader (verbatim from brain pages).\n- Dated incidents and recurring patterns where available.\n- Coverage across life domains: journal entries and reflections, work and\n  creative output, relationships, public\u002Fcivic life, specific joyful\n  moments, cultural identity — not just the heaviest material.\n\n### Assemble a context pack\n\nWrite everything to a single file the CLI can read:\n\n```bash\nCONTEXT=\"$WORK\u002Fcontext.md\"\n{\n  echo \"## USER.md (if any)\"\n  [ -f \"$BRAIN_DIR\u002FUSER.md\" ] && cat \"$BRAIN_DIR\u002FUSER.md\"\n  echo\n  echo \"## SOUL.md (if any)\"\n  [ -f \"$BRAIN_DIR\u002FSOUL.md\" ] && cat \"$BRAIN_DIR\u002FSOUL.md\"\n  echo\n  echo \"## Recent reflections (last 14 days)\"\n  # Pull recent daily reflections — adapt to the user's filing scheme\n  # ...\n  echo\n  echo \"## Topic-relevant brain pages (grouped per chapter)\"\n  # Deep-retrieval results from above, grouped by the chapter they serve\n  # ...\n  echo\n  echo \"## Themes & cruxes\"\n  # A 1-page summary, written by the agent, calling out:\n  # - What's currently active in the user's life that this book intersects\n  # - Specific quotes from the user that map to book themes\n  # - People and dates that should appear in the mirror\n  # - The anti-repetition constraints (domain map + phrase caps, below)\n} > \"$CONTEXT\"\n```\n\nMake this dense. It's read by every chapter subagent. Encode the\nanti-repetition constraints (next section) here — the per-chapter domain\nassignment and phrase caps only work if every subagent can see them.\n\n## Quality system (hard rules)\n\nThese rules were earned through iteration with cross-modal eval. They are\nmandatory for every book-mirror.\n\n### Principle: the Chapter half IS the variety engine\n\nThe single most important lesson: rich chapter summaries drive varied\nmirrors. When you compress the source material, the mirror has nothing\nto respond to except its own greatest hits. The two halves are symbiotic,\nnot competing for space.\n\n**Rule:** Every distinct idea, story, framework, numbered list item, and\nmemorable phrase the author presents gets its own section. If the author\nlists six kinds of loneliness, that's six sections. If they tell three\nstories, that's three sections. The Chapter half should be detailed enough\nthat someone could skip the book and not lose much. The Mirror half\nresponds to EACH specific idea with a DIFFERENT personal mapping.\n\n### Layout: top-aligned HTML tables OR stacked sections (hard rule)\n\nDo **NOT** emit a bare `| The Chapter | The Mirror |` *markdown* pipe\ntable. GitHub (and most renderers) pad a table row's cells to equal height\nand vertically *center* the shorter cell's text — so when the two halves\ndiffer in length (they always do), one column floats down with a block of\nwhitespace above it. Plain markdown has no per-cell vertical-align. That\nis the root cause, not a styling nit.\n\n**Two valid containers — both are correct, pick by destination:**\n\n1. **Top-aligned HTML table (the CLI default).** The `gbrain book-mirror`\n   chapter prompt already mandates an HTML `\u003Ctable>` with `valign=\"top\"`\n   on EVERY `\u003Ctd>` — this is baked into the trusted runtime. Facts worth\n   knowing when hand-writing or repairing a mirror: GitHub KEEPS\n   `valign=\"top\"` but STRIPS inline `style=\"vertical-align\"`, and does NOT\n   render markdown emphasis inside a raw `\u003Ctd>` — pre-convert emphasis to\n   `\u003Cem>`\u002F`\u003Cstrong>`, and use `\u003Cbr>\u003Cbr>` for paragraph breaks within a\n   cell.\n\n2. **Stacked sections** — best for mobile and chat delivery, and the\n   right choice for any hand-assembled mirror (children's variant,\n   retro-fixes of legacy pages):\n\n   ```markdown\n   ### Chapter N: \u003Ctitle>\n\n   **The Chapter**\n\n   \u003Cchapter prose, normal paragraphs separated by blank lines>\n\n   **The Mirror**\n\n   \u003Cmirror prose, normal paragraphs separated by blank lines>\n   ```\n\n   Use real blank-line paragraph breaks, never `\u003Cbr>\u003Cbr>` outside a table\n   cell. Reads top-to-top every time, zero alignment bug. The\n   Chapter\u002FMirror naming and the one-section-per-idea richness rule are\n   unchanged — only the container changes.\n\n### Anti-repetition (hard constraints, not vibes)\n\n\"Be more varied\" doesn't work as an instruction. LLMs remix the deck\nthey're given — if the deck is 6 cards, you get 6 cards N times. Use hard\nconstraints, written into the context pack's \"Themes & cruxes\" section:\n\n1. **Domain mapping:** Before writing, assign each chapter a PRIMARY life\n   domain (career, family, civic work, creative life, a specific\n   relationship, childhood, intellectual life, spiritual practice, etc.).\n   No two adjacent chapters should share the same primary domain.\n\n2. **Phrase caps:** No word or phrase may appear as a thematic anchor in\n   more than 3 chapters. Identify the reader's \"greatest hits\" (the 5–6\n   themes that would dominate without constraints) and set explicit\n   limits or bans.\n\n3. **Story deduplication:** Before writing each mirror, check: \"Have I\n   already used this story\u002Fincident\u002Fquote in a previous chapter?\" If yes,\n   find a different one.\n\n4. **Emotional range requirement:** At least 25% of chapters must map to\n   JOY, HUMOR, CREATIVE EXCITEMENT, or VICTORY — not only wounds and\n   struggle. When the author describes something beautiful, the mirror\n   should find something beautiful in the reader's life.\n\n### The editorial rule (THE MOST IMPORTANT RULE)\n\nDeep retrieval is the engine, not the product. The reader should never\nfeel like they're reading a research paper or a search results page.\nThe mirror must read like a brilliant essay by someone who knows the\nreader deeply — not a report proving it did homework.\n\n**The test:** If you remove all citations and source attributions, does\nthe mirror still make the reader feel seen? Does it still produce\nepiphanies? Does it still work as standalone writing? If yes, the\nretrieval served its purpose. If the mirror only works because of its\ncitations, the retrieval failed.\n\n**Citations:** Optional. Use sparingly as footnotes when the source adds\ngenuine value (\"you wrote this at 19\" lands differently when the reader\nknows you actually read the journal entry). But never let citations\nbecome the point. Never let the mirror read like it's performing\nthoroughness.\n\n### Cross-modal eval gate (recommended for high-stakes mirrors)\n\nAfter generating a mirror, run `gbrain eval cross-modal` (or the manual\ngate in `skills\u002Fcross-modal-review\u002FSKILL.md`) with these custom\ndimensions:\n\n- VARIETY (fresh each chapter?)\n- SPECIFICITY (real stories\u002Fdates\u002Fquotes?)\n- DEPTH (new insight vs restating profile?)\n- LEFT_COLUMN_FIDELITY (preserves the book?)\n- EMOTIONAL_RANGE (joy as well as struggle?)\n\n```bash\ngbrain eval cross-modal --slug \u003Cslug>-personalized \\\n  --dimensions VARIETY,SPECIFICITY,DEPTH,LEFT_COLUMN_FIDELITY,EMOTIONAL_RANGE\n```\n\nPass threshold: all dimensions average 7+ across models. If any dimension\nis below 6, rebuild with targeted fixes. The eval→fix→re-eval cycle is the\nquality multiplier. Evaluator model pairs and refusal routing follow\n[conventions\u002Fcross-modal.yaml](..\u002Fconventions\u002Fcross-modal.yaml).\n\n### Children's book variant\n\nFor picture books and children's books (under ~5K words), use a\n**Parent's Reading Guide** format instead of the standard mirror:\n\n- The Chapter half: what the book says on each page\u002Fspread.\n- The Mirror half: written FOR THE PARENT reading aloud — what each page\n  will feel like, what the child might ask at each age, what to say if\n  they do, and what the book is really teaching underneath the simple\n  words.\n- Include: when to read it, how to handle specific reactions, and the\n  book's deeper structure mapped to developmental psychology research.\n- Tone: warm, practical, specific to the reader's children by name and\n  age (from brain context).\n\nHand-assembled variants like this use the stacked-sections container.\n\n## 4. Analysis: invoke `gbrain book-mirror`\n\n```bash\ngbrain book-mirror \\\n  --chapters-dir \"$WORK\u002Fchapters\" \\\n  --context-file \"$CONTEXT\" \\\n  --slug \"$SLUG\" \\\n  --title \"Book Title Goes Here\" \\\n  --author \"Author Name\" \\\n  --model claude-opus-4-7\n```\n\nThe CLI:\n\n- Validates inputs and loads chapter files.\n- Prints a cost estimate (~$0.30\u002Fchapter at Opus) and prompts to confirm.\n- Submits N child subagent jobs with read-only `allowed_tools`.\n- Waits for every child to complete.\n- Reads each child's `job.result` (the markdown analysis text).\n- Assembles all chapters into one page with frontmatter + intro + per-chapter\n  sections + closing.\n- Writes ONE `put_page` to `media\u002Fbooks\u002F\u003Cslug>-personalized.md`.\n- Reports a JSON envelope on stdout:\n  `{\"slug\": \"...\", \"chapters_total\": N, \"chapters_completed\": N, \"chapters_failed\": 0}`.\n\nIf any chapter failed, the CLI exits 1 and the user can re-run — idempotency\nkeys (`book-mirror:\u003Cslug>:ch-\u003CN>`) deduplicate completed chapters at the\nqueue level, so retry is cheap. Note that reproducing verbatim book quotes\nplus the reader's verbatim words can occasionally trip a provider output\nfilter; a chapter blocked that way is just a failed chapter — re-run, or\nretry with a different `--model`.\n\n### Model: Opus by default\n\nThe default model is `claude-opus-4-7`. Sonnet works (use `--model\nclaude-sonnet-4-6`) but the mirror quality drops noticeably — the\ntexture that makes the analysis feel like it was written by someone who\nknows the reader needs Opus-grade reasoning.\n\n### Cost gate\n\nThe CLI refuses to spend in a non-TTY context without `--yes`. CI \u002F scripted\ninvocations must pass `--yes` explicitly. TTY users get a `[y\u002FN]` prompt\nbefore submission.\n\nDeep retrieval raises total cost meaningfully versus a thin static\ncontext pack (roughly an order of magnitude at Opus rates). The quality\njump is worth it for a book the reader cares about; use a static pack\nonly for low-stakes runs.\n\n## 5. PDF (optional)\n\nAfter the brain page is written (the CLI already did the `put_page`),\nrender to PDF using `skills\u002Fbrain-pdf`:\n\n```bash\n# See skills\u002Fbrain-pdf\u002FSKILL.md for the invocation.\n```\n\nIf the user asked for a deliverable, prefer the PDF over sending raw\nmarkdown — the brain page is the source of truth; the PDF is the artifact\nthat travels.\n\n## 6. Fact-check and cross-link\n\nAfter the page lands, run a fact-check pass on factual claims about the\nreader (parents, siblings, marriage history, jobs, heritage). Common error\npatterns to look for:\n\n- Conflating the reader's parents' relationship with patterns in extended\n  family.\n- Inventing backstory (\"after his parents' divorce…\") when the\n  reader's parents are still together.\n- Wrong number\u002Fage of children, wrong spouse \u002F kid \u002F sibling names.\n\nIf you can't verify a claim, remove it. Better to lose texture than to\nintroduce a falsehood.\n\nCross-link entities mentioned in the analysis:\n\n- For every person the mirror references with a brain page, add a\n  back-link from `people\u002F\u003Cslug>` to the new `media\u002Fbooks\u002F\u003Cslug>-personalized`\n  page (per `conventions\u002Fquality.md` Iron Law).\n\n## Quality bar (the bar)\n\nThe **Chapter half** should:\n\n- Preserve the author's actual stories, statistics, frameworks, examples.\n- Quote memorable phrases verbatim.\n- Be detailed enough that the reader could skip the book and not lose much.\n\nThe **Mirror half** should:\n\n- Use the reader's *actual quoted words* from the context pack.\n- Reference *specific* dates, situations, people by name.\n- Read like a smart friend who happens to know the reader's life deeply —\n  pointing things out, not giving instructions.\n- **OBSERVE, never PRESCRIBE.** The mirror holds up a reflection. The\n  reader decides what to do about it. No directives, no action items, no\n  \"you should,\" no \"consider whether,\" no rearranging of the reader's life.\n- Frame connections as observations or gentle nudges: \"This is the same\n  pattern as…\" or \"Hard not to hear echoes of…\" — NOT \"You need to\n  address this\" or \"Apply this framework to your Q3 planning.\"\n- Be plain about direct hits (\"This is exactly the [name a real situation]\").\n- Be honest about misses (\"This chapter is less directly relevant\n  because…\"). Don't force connections.\n- **Resonant, not actionable.** The mirror's job is recognition, not\n  instruction. \"That's exactly what we're doing\" is the win. \"Here's a\n  7-point plan to fix it\" is overstepping.\n- **For team mirrors:** Name team members for context (\"this connects to\n  what a teammate does\"), NEVER for task assignment (\"teammate: do X by\n  Friday\"). Don't invent organizational policies, veto chains, checklists,\n  or structural decisions the team hasn't made. Only reference decisions\n  that are in the team's actual documents. Frame everything else as\n  questions or observations.\n\nThe **whole document** should feel like one coherent voice, calibrated to\nthe reader's actual life rather than a generic profile, and honest about\nwhere the book's framing breaks down for this specific reader. It should\nmake the reader feel SEEN, not studied — and work as good standalone\nwriting even with every citation stripped.\n\n## Anti-patterns (do not do these)\n\n- ❌ **Skimming chapters.** Standing instruction: preserve detail.\n- ❌ **Generic mirror.** \"This might apply if you've ever felt…\" →\n  kill on sight.\n- ❌ **Factual errors about the reader's life.** Always fact-check after\n  assembly.\n- ❌ **Giving the subagent put_page access.** Trust contract is read-only;\n  the CLI does the writing.\n- ❌ **Forcing connections.** If a chapter doesn't apply, say so plainly.\n- ❌ **Sycophancy or moralizing in the mirror.** No \"you should…\",\n  no \"consider…\", no \"perhaps it's time to…\".\n- ❌ **Consultant mode.** The mirror is not a strategy deck. No action\n  items, no task assignments to named people, no invented policies or org\n  structures, no \"audit this quarterly,\" no numbered implementation\n  checklists. The mirror OBSERVES and RESONATES. It's a friend at a bar\n  saying \"this part is so us\" — not a consulting engagement. If the\n  reader wants to turn an observation into a plan, that's their move.\n  Not ours.\n- ❌ **Inventing rules the reader never said.** Veto chains, editorial\u002F\n  marketing separations, ombudsperson structures, campaign checklists —\n  if the reader didn't establish it, the mirror can't declare it. Frame\n  it as a question the author would ask (\"who has the veto here?\") or\n  don't include it.\n- ❌ **Truncating the Chapter half.** The book's actual content needs to\n  survive. This is the #1 quality failure — rich chapter = varied mirror.\n- ❌ **Bare markdown pipe tables.** They center-misalign uneven cells on\n  GitHub and most renderers. HTML `\u003Ctable>` with `valign=\"top\"` on every\n  `\u003Ctd>`, or stacked sections. See the layout hard rule above.\n- ❌ **Repeating the same 5–6 themes across all chapters.** Use the domain\n  mapping and phrase caps from the quality system.\n- ❌ **Thin context pack.** If the context pack is just USER.md bullets,\n  the mirror will be generic. Invest in deep retrieval.\n- ❌ **Skipping the eval gate on high-stakes mirrors.** At minimum, run a\n  self-check: count mentions of key themes across chapters. If any theme\n  appears in more than 3 chapters, fix before delivering.\n\n## Output checklist\n\n- [ ] Book file exists locally (path known).\n- [ ] Chapter texts under `$WORK\u002Fchapters\u002F*.txt` with sane word counts.\n- [ ] Context pack at `$WORK\u002Fcontext.md` is dense: deep-retrieval results\n      grouped per chapter + domain map + phrase caps.\n- [ ] `gbrain book-mirror --chapters-dir … --context-file … --slug … --title …` returned exit 0.\n- [ ] `media\u002Fbooks\u002F\u003Cslug>-personalized.md` exists in the brain.\n- [ ] Layout check: no bare markdown pipe tables in the page.\n- [ ] Anti-repetition self-check: no theme anchors more than 3 chapters.\n- [ ] Fact-check pass complete (no errors against USER.md or other source-of-truth pages).\n- [ ] Cross-links added from referenced people\u002Fcompanies.\n- [ ] Optional: cross-modal eval gate passed (all dimensions 7+).\n- [ ] Optional: PDF rendered via brain-pdf and delivered.\n\n## Related skills\n\n- `skills\u002Fbrain-pdf\u002FSKILL.md` — render the personalized page to PDF.\n- `skills\u002Fstrategic-reading\u002FSKILL.md` — read a book through a specific\n  problem-lens instead of personalizing to the whole reader.\n- `skills\u002Farticle-enrichment\u002FSKILL.md` — same shape applied to articles\n  rather than books.\n- `skills\u002Fcross-modal-review\u002FSKILL.md` — the manual second-model quality\n  gate; `gbrain eval cross-modal` is the scripted sibling surface.\n\n\n## Contract\n\nThis skill guarantees:\n\n- Routing matches the canonical triggers in the frontmatter.\n- Output written under the directories listed in `writes_to:` (when applicable).\n- Conventions referenced (`quality.md`, `brain-first.md`, `_brain-filing-rules.md`) are followed.\n- Privacy contract preserved: no real names, no fork-specific filesystem path literals, no upstream-fork references.\n\nThe full behavior contract is documented in the body sections above; this section exists for the conformance test.\n\n## Output Format\n\nThe skill's output shape is documented inline in the body sections above (see \"Output\", \"Brain page format\", or equivalent). The literal section header here exists for the conformance test (`test\u002Fskills-conformance.test.ts`).\n\n## When it fails\n\nFollow the [agent operator protocol](..\u002Fconventions\u002Fagent-operator-protocol.md) for any gbrain error `code`, exit code, `[AGENT]` block or notice block. Specific to this skill:\n\n- The CLI stops for cost confirmation (exit 3, or a non-TTY refusal without `--yes`): relay the per-chapter estimate and wait for the user's agreement before adding `--yes`.\n- A paid run stops with `no_pricing` under a user cost cap: look up the model's per-token rate, tell the user, and after they agree ask the brain host's operator to run `gbrain pricing set \u003Cmodel> --input \u003Cusd-per-1M> --output \u003Cusd-per-1M>`; then retry.\n- Exit 1 with `chapters_failed > 0`: the finished chapters are kept; re-run the same command to retry only the failed ones and tell the user how many chapters are still missing.\n\n## Anti-Patterns\n\nThe full anti-pattern list is in the body sections above; this header exists for the conformance test if the body uses a different casing.\n",{"name":5,"version":50,"mutating":51,"triggers":52,"upstream":58,"writes_to":59,"description":7,"writes_pages":51},"0.5.0",true,[53,54,55,56,57],"personalized version of this book","mirror this book","two-column book analysis","apply this book to my life","how does this book apply to me","book-mirror@fc834ee",[60],"media\u002Fbooks\u002F","master","074ec301549ded4930f04d2c3b22d709a6c095cc","skills\u002Fbook-mirror",4884,"https:\u002F\u002Fgithub.com\u002Fgarrytan\u002Fgbrain","https:\u002F\u002Fgithub.com\u002Fgarrytan","https:\u002F\u002Fblog.garrytan.com","Writes software, dreams. ","2026-11-13 04:05:07",{"source":8,"skillName":5,"commands":71,"prompt":81,"zipAvailable":51},[72,75,78],{"tool":73,"command":74},"npx","npx skills add garrytan\u002Fgbrain --skill book-mirror",{"tool":76,"command":77},"bunx","bunx skills add garrytan\u002Fgbrain --skill book-mirror",{"tool":79,"command":80},"pnpm","pnpm dlx skills add garrytan\u002Fgbrain --skill book-mirror","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fgarrytan\u002Fgbrain\u002Fblob\u002Fmaster\u002Fskills\u002Fbook-mirror\u002FSKILL.md",[83],{"path":84,"resourceType":85,"resourceTypeDesc":86,"sizeBytes":87,"sourceHtmlUrl":88},"routing-eval.jsonl","OTHER","其他",1405,"https:\u002F\u002Fgithub.com\u002Fgarrytan\u002Fgbrain\u002Fblob\u002Fmaster\u002Fskills\u002Fbook-mirror\u002Frouting-eval.jsonl",[90,103,109,131,157,171],{"skillNo":91,"name":92,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":93,"categories":94,"keywords":95,"publishedAt":45},"01M6N109FNGH1PK49T734PZXGB","query-helper","https:\u002F\u002Fgithub.com\u002Fgarrytan\u002Fgbrain\u002Fblob\u002Fmaster\u002Ftest\u002Ffixtures\u002Fskill-catalog\u002Fskills\u002Fquery-helper\u002FSKILL.md",[],[96,97,98,99,100,101,102],"query helper","helper","query","search","page","find","false",{"skillNo":104,"name":105,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":106,"categories":107,"keywords":108,"publishedAt":45},"01M6N108A23GW6NGQEQ0E7GV0A","broken","https:\u002F\u002Fgithub.com\u002Fgarrytan\u002Fgbrain\u002Fblob\u002Fmaster\u002Ftest\u002Ffixtures\u002Fskill-catalog\u002Fskills\u002Fbroken\u002FSKILL.md",[],[105],{"skillNo":110,"name":111,"nameZh":6,"description":112,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":113,"categories":114,"keywords":115,"publishedAt":45},"01M6N105E88C5K2H03H0CC79G1","brain-ops","Read, enrich, and write brain pages with source attribution.","https:\u002F\u002Fgithub.com\u002Fgarrytan\u002Fgbrain\u002Fblob\u002Fmaster\u002Ftest\u002Ffixtures\u002Fskill-catalog\u002Fskills\u002Fbrain-ops\u002FSKILL.md",[],[116,27,117,118,119,100,120,121,122,123,98,124,125,126,127,128,129,130,99],"brain ops","ops","true","attribution","read","write","up","look","pages","people","with","enrich","web","path","source",{"skillNo":132,"name":133,"nameZh":6,"description":134,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":135,"categories":136,"keywords":142,"publishedAt":45},"01M6N102GRMF22TVCNT6RK5MRD","meeting-prep","Build a briefing before you meet someone, from their recent threads, open loops and what they care about.","https:\u002F\u002Fgithub.com\u002Fgarrytan\u002Fgbrain\u002Fblob\u002Fmaster\u002Ftest\u002Ffixtures\u002Fskill-catalog-query\u002Fskills\u002Fmeeting-prep\u002FSKILL.md",[137],{"categoryNo":138,"categoryName":139,"taxonomyType":140,"taxonomyTypeDesc":141},"01JBSEEDCAT000000000000034","行政与办公人员","PROFESSION","适用职业",[143,144,145,37,146,99,147,148,149,98,102,150,151,152,153,154,155,156],"meeting","prep","meeting prep","prepare","brief","open","build","loops","about","you","briefing","threads","for","Meet",{"skillNo":158,"name":159,"nameZh":6,"description":160,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":161,"categories":162,"keywords":163,"publishedAt":45},"01M6N1005QK7REHX5KGMNR5PF0","inbox-zero","Triage the inbox into replies, delegations and archives.","https:\u002F\u002Fgithub.com\u002Fgarrytan\u002Fgbrain\u002Fblob\u002Fmaster\u002Ftest\u002Ffixtures\u002Fskill-catalog-query\u002Fskills\u002Finbox-zero\u002FSKILL.md",[],[164,165,166,99,167,102,168,169,170],"inbox zero","ZeRO","inbox","clear","replies","my","triage",{"skillNo":172,"name":173,"nameZh":6,"description":174,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":175,"categories":176,"keywords":177,"publishedAt":45},"01M6N0ZXQ8RRRW71PNV61T57GP","deal-memo","Draft an investment memo from the deal pages and the founder history already in the brain.","https:\u002F\u002Fgithub.com\u002Fgarrytan\u002Fgbrain\u002Fblob\u002Fmaster\u002Ftest\u002Ffixtures\u002Fskill-catalog-query\u002Fskills\u002Fdeal-memo\u002FSKILL.md",[],[178,179,180,124,27,181,182,121,183,118,99,184],"deal memo","deal","memo","draft","investment","history","founder"]