Why use it: this is the repository's only functionality outside chat — downloading/cleaning subtitles to ingest primary material, consolidating research tables for gate 1.5, and self-checking the six Phase 4 criteria. What it produces: clean transcript files, research summary tables, and pass/fail reports with exit codes usable in CI.
⚠️ This entire file contains SHELLcommands. Chat commands are in 02, 03, 04.
The symbol $NUWA below means the skill installation directory, for example ~/.claude/skills/nuwa-skill:
export NUWA=~/.claude/skills/nuwa-skill
Dependencies: Python 3 (uses type hints list[str]/tuple[bool, str] → requires 3.9+, preferably 3.10+), and yt-dlp for the subtitle download script. There is no requirements.txt; all four scripts use only the standard library (sys, re, pathlib).
download_subtitles.sh — download YouTube subtitles
bash $NUWA/scripts/download_subtitles.sh <YouTube_URL> [thư_mục_ra]
Attempt order: human-made Chinese subtitles (zh-Hans,zh-Hant,zh,zh-CN,zh-TW) → human-made English subtitles (en,en-US,en-GB) → automatic subtitles (zh-Hans,zh,en). SRT format, with --skip-download so the video is not downloaded.
Exit codes: 0 when subtitles are found, 1 when no URL is supplied or no subtitles are found (verified: invoking without arguments → exit 1 with a usage message).
Check yt-dlp first:
command -v yt-dlp || brew install yt-dlp # macOS; hoặc: pipx install yt-dlp
Verified bug in branch 1: the Chinese subtitle branch searches for new files with find ... -newer /tmp/.ytdlp_marker, but /tmp/.ytdlp_marker is never created anywhere in the repository. find fails, stderr is swallowed, and the FOUND variable is empty → the script always falls through to branch 2 and makes an extra English yt-dlp request, then reports success in branch 2 (this branch uses -mmin -1 , so it still finds the Chinese .srt file just downloaded). Practical effect: the file is correct, but there is an extra network request and the success message names the wrong language. Check the actual filename:
ls -la <thư_mục_ra>/*.srt <thư_mục_ra>/*.vtt 2>/dev/null
srt_to_transcript.py — clean SRT/VTT into readable text
python3 $NUWA/scripts/srt_to_transcript.py input.srt [output.txt]
python3 $NUWA/scripts/srt_to_transcript.py input.vtt
Without a second argument, the output is <tên>_transcript.txt beside the input file. The script removes sequence numbers, timestamps, HTML tags, and align:/position:, removes consecutive duplicate lines (a chronic issue in automatic subtitles), then joins paragraphs when they exceed 200 characters or encounter sentence-ending punctuation 。!?.!?. VTT is recognized by its extension or the WEBVTTheader; the header and NOTE blocks are removed before processing it as SRT.
Actual run with a three-line SRT containing one duplicate line and one <i>:
✅ 转换完成: demo_transcript.txt
字数: 28 段落数: 3
Output — the <i> tag is removed and the duplicate line eliminated:
Hello world.
This is a test
Exit codes: 0 on success; 1 when arguments are missing or the input file does not exist (❌ 文件不存在: ...).
Place the result in references/sources/transcripts/ inside the skill directory being distilled.
merge_research.py — summary table for the Phase 1.5 gate
python3 $NUWA/scripts/merge_research.py <đường_dẫn_thư_mục_skill>
Scans <skill>/references/research/01-writings.md … 06-timeline.md, counts unique URLs as sources and primary/secondary markers, extracts ## headings as key findings, and detects contradictions using the keywords 矛盾/相反/但实际上/然而…不同/争议.
Actual run on examples/steve-jobs-perspective:
┌──────────────┬──────────┬──────────────────────────┐
│ Agent │ 来源数量 │ 关键发现 │
├──────────────┼──────────┼──────────────────────────┤
│ 著作 │ 24 │ 一、核心著作与一手文献, ... │
│ 对话 │ 27 │ 一、核心访谈索引, ... │
│ 表达 │ 26 │ 一、Keynote演讲:语言特征... │
│ 他者 │ 29 │ 一、同事与合作者视角, ... │
│ 决策 │ 0 │ 一、早期决策(1972-1976)...│
│ 时间线 │ 12 │ 第一章:早年(1955-1976)...│
├──────────────┼──────────┼──────────────────────────┤
│ 总来源数 │ 118 │ 一手占比: 134/244 │
│ 矛盾点 │ 5处 │ 著作: 争议。不妥协 │
│ 信息不足维度 │ 无 │ — │
└──────────────┴──────────┴──────────────────────────┘
Exit codes: 0 when the table is printed; 1 when arguments are missing or there is no references/research/ (verified on examples/munger-perspective: ❌ 目录不存在: .../references/research, exits with 1).
How to read the table:
- A zero in the 来源数量 (source count) column does not mean that dimension is empty — it counts URLs, so a file citing sources without links (such as Jobs's
05-decisions.md) returns 0. Inspect the file visually before requiring another research run. - 一手占比 (primary-source share) counts keywords, rather than actually classifying sources (it counts 一手/primary/本人/原文 versus 二手/转述/总结/评论). The figure
134/244is a rough indicator, not an accurate source ratio. - Automatic warnings: total sources <10 → lower expectations or add sources; missing dimensions → add research or record the gap in the honest limits.
quality_check.py — self-check the six Phase 4 criteria
python3 $NUWA/scripts/quality_check.py <đường_dẫn/SKILL.md>
Actual run on examples/steve-jobs-perspective/SKILL.md:
质量检查: SKILL.md
==================================================
心智模型数量 ✅ PASS 6个心智模型 ✅
模型局限性 ✅ PASS 有局限性标注 ✅
表达DNA辨识度 ✅ PASS 表达DNA特征: 21项 ✅
诚实边界 ✅ PASS 诚实边界: 3条 ✅
内在张力 ✅ PASS 内在张力: 2处 ✅
一手来源占比 ✅ PASS 未标记来源类型(跳过检查)
==================================================
结果: 6/6 通过
🎉 全部通过,可以交付
There are only two exit codes: 0 for 6/6, 1 for every other result. Do not mistake 「⚠️ 基本通过」 (roughly passed, 5/6) for a pass — verified on examples/munger-perspective/SKILL.md: it prints 「基本通过,建议修复不通过项后交付」 (roughly passed; fix failed items before delivery), but still exits with 1:
诚实边界 ❌ FAIL 诚实边界: 0条 ❌ (应≥3条)
结果: 5/6 通过
⚠️ 基本通过,建议修复不通过项后交付
Therefore, when integrating into CI, exit != 0 means "not perfect yet", rather than "broken" — choose the threshold deliberately instead of blocking by default (see the sample CI gate in 07).
Some blind spots to know when interpreting this checker:
- 诚实边界 (honest limits) is counted by regex: it recognizes only list items beginning with
-or*beneath a heading containing 「诚实边界」. Honest limits written as prose or a table count as 0 and fail even when the content exists (the exact reasonmunger-perspectivefails). - 一手来源占比 (primary-source share) is automatically skipped when no 来源/Source/Reference section or 一手/二手 labels are found — both cases report PASS. A PASS on this line does not prove that primary sources exceed 50%.
- 内在张力 (internal tension) counts keywords (张力/矛盾/tension/paradox/一方面…另一方面/既…又), without understanding meaning. It is easy to pass by including enough matching words.
In other words: quality_check.py is a formal-structure gate, and cannot replace the fidelity scorecard in 06.