content-gateSKILL
內容閘門(substance_gate 含金量、similar_gate 相似度、style 標點)的操作卡。
18 行・放進 ~/.claude/skills/content-gate/SKILL.md
---
name: content-gate
description: 內容閘門(substance_gate 含金量、similar_gate 相似度、style 標點)的操作卡。當使用者說「這篇過不過」「為什麼被擋」「池子體檢」「相似度太高」時使用。
---
# content-gate(①地基:substance_gate.py/similar_gate.py/style.py)
都在 `daily_post._take()` 取稿時自動跑;手動:
- 含金量全池:`python3 substance_gate.py --scan`;只看一條線:`--check carousel`
- 相似度:`python3 similar_gate.py --scan`/`--check threads`
- 單則程式判:`python3 -c "import json,substance_gate as g;it=...;print(g.audit(it,'threads'))"`
## 閘的內容(判準是機械的,不叫模型)
| 線 | 要有 |
|---|---|
| threads/fb | `source` 或 note「出處:」;開頭不是口號;有數字就要有出處 |
| carousel | takeaway ≥12 字、封面是鉤子、≥2 個硬料、**操作層**(steps 或 takeaway 有「看後台/查表」動詞)、**量化層**(stat/table 或「A → B」「N 倍」) |
| 連播串 | `posts` 每則單獨成立:第 1 則鉤子、中間每則有硬料或 ≥28 字、口號整串退回(`chain_audit`) |
| 相似度 | 字元 2-gram Jaccard ≥0.28 或骨架四項撞兩項(開頭句型/結尾八字/行數分桶/口頭禪) |
- `style.clean_deep`:刪「——」與句尾「。」,只清符號不改字
- 擋太嚴就放寬(memory `loosen-dont-tighten`),不要為了過閘把稿寫成說明書
mail-wbsSKILL
Mail → WBS 週報(mail_wbs.py)的操作卡。
27 行・放進 ~/.claude/skills/mail-wbs/SKILL.md
---
name: mail-wbs
description: Mail → WBS 週報(mail_wbs.py)的操作卡。當使用者說「幫我把信整理成週報」「這幾封信有什麼風險」「本週完成/風險/下週行動」「更新 WBS」或貼一段信件文字要判狀態時使用。
---
# mail-wbs(③產線:mail_wbs.py)
把信件文字拆成工作項目,判四種狀態 **Completed/Risk/Bug/Change**,抓負責人、日期、延遲天數,
出「本週完成/本週風險/新增需求/Bug/下週行動」五欄。做法提取自 @light0025 的「Mail → WBS 風險」GPT Skill。
## 怎麼叫
1. 撈信:對話裡用 Gmail MCP(`search_threads` → `get_thread`),把每封的 From/Subject/內文貼成純文字,多封之間用一行 `=====` 隔開,存到 `<tmp>/`。
2. 跑:`python3 mail_wbs.py --file mails.txt`(週報 markdown)/加 `--json`(結構化)/加 `--brain`(機械判完再叫本機大腦補判,$0)。
3. 自測:`python3 mail_wbs.py --demo`。
## 判準(機械,不叫模型也能跑)
| 狀態 | 命中詞(節錄) | 優先序 |
|---|---|---|
| Bug | 錯誤/失敗/無法/500/crash | 1 |
| Risk | 延後/延遲/來不及/卡住/尚未/可能壓縮 | 2 |
| Change | 新增/追加/變更/希望增加/改成 | 3 |
| Completed | 已完成/上線/已交付/已修復/merged | 4 |
- 同句多命中取優先序高的(「原訂完成…延後到」=Risk)。
- 延遲天數:先找「延後 N 天」,沒有就用兩個日期相減。
- 負責人:「由/請 X」「X 處理」或信頭 From。
## 硬條件
- **不編數據**:抓不到日期/負責人就留空,不猜。
- 這支只讀文字不寄信不改任何台帳;WBS 本體(Notion/表格)要更新是下一塊,還沒做。
schedule-auditSKILL
排程體檢的操作卡(schedule_audit/launchctl/run_job/catchup/ceo)。
15 行・放進 ~/.claude/skills/schedule-audit/SKILL.md
---
name: schedule-audit
description: 排程體檢的操作卡(schedule_audit/launchctl/run_job/catchup/ceo)。當使用者說「排程正常嗎」「今天有沒有跑」「為什麼沒發」「補跑」「警報」時使用。
---
# schedule-audit(④看門)
照順序跑,四件一起看才算體檢:
1. 該跑沒跑+跑了失敗:`python3 schedule_audit.py`(缺班會當場 kickstart;失敗只回報不補)
2. 停用清單:`launchctl print-disabled gui/$(id -u) | grep com.stanley | grep -v false`(**`launchctl list` 看不出 disabled**;刻意停的:line-watch/browser-scrape/media-pack/drama)
3. 常駐:`pgrep -fl "brain_daemon|inbox_agent|carousel_render|twstock_bot|caffeinate"` 五支都要在
4. 今天每支結果:`logs/<job>.log` 找今天日期後的「✅ 完成/🔴 失敗/週末休息,跳過」
- 週末規則:`run_job.sh` 的 `WEEKDAY_ONLY`(六日休)/`WEEKEND_TOO`(照跑);**新排程要補進其中一份**,selfcheck 會點名
- 改 plist 後 `launchctl unload` 再 `load -w`;log 行用 `${JOB}` 不能 `$JOB:`
- Mac 睡著=所有本機站與排程消失;查 `pmset -g log | grep -E "Sleep|Wake"`,闔蓋睡 caffeinate 擋不住
- 營運提案層:`.venv/bin/python ceo.py --dry`(00:15 自動跑,存量/產出/故障三句,只提案)
- 改完地基區必跑 `python3 selfcheck.py`;三種 Python 都會載一次
post-dailySKILL
每日發文主控 daily_post.py 的操作卡。
21 行・放進 ~/.claude/skills/post-daily/SKILL.md
---
name: post-daily
description: 每日發文主控 daily_post.py 的操作卡。當使用者說「發一則 Threads」「補發 IG」「今天 FB 發了沒」「池子還剩幾則」「看等審的稿」時使用。只寫怎麼叫、輸入什麼、驗證看哪裡。
---
# post-daily(③產線:daily_post.py)
工作目錄 `.`,一律用 `.venv/bin/python`(系統 3.14 沒 CA、Playwright 也起不來)。**先 `unset NODE_OPTIONS`**。
## 叫法
| 要做 | 指令 |
|---|---|
| 看存量(可用=沒 used_at 也沒 hold) | `python3 -c "import json;d=json.load(open('content_pool.json'));[print(k,sum(1 for x in v if isinstance(x,dict) and not x.get('used_at') and not x.get('hold'))) for k,v in d.items() if not k.startswith('_')]"` |
| 看等審的稿 | `.venv/bin/python daily_post.py --pending` |
| 乾跑(不發) | `.venv/bin/python daily_post.py --kind threads --dry`(kind: threads/carousel/fb/story;carousel 加 `--account both`) |
| 真發 | 去掉 `--dry`;今天已發過會擋,硬要再發加 `--force`(限動則是無視兩天一次) |
## 入池格式
threads:`{id,title,text,takeaway,source,note:"出處:…"}`;連播串加 `posts:[...]`(第 1 則鉤子、每則要單獨成立,`substance_gate.chain_audit` 擋)。carousel 照 `cs-13` 那筆(slides 內 lines/kick/table/stat/steps)。fb:`{id,title,text,takeaway,source}`。story:三張 `{n,pos,big,text}`+howto。
## 入池前必過
`python3 substance_gate.py --scan | grep <id>` 與 `python3 -c "import json,similar_gate as g;..."`;池子改前 `cp content_pool.json _retired/`。
## 驗證看哪裡
- 發出去了沒:`logs/published.jsonl`(platform 值是 threads/ig/fb/youtube)、`logs/post-*.log` 最後一行
- 週末:post-threads/post-ig/post-fb/story-both **六日休息**是規則不是故障
- 失敗第一嫌疑:池空(`_take` 取不到)、Mac 睡著、Playwright 沒 `channel=chrome`
story-renderSKILL
限動出圖 story_render.py/daily_post --kind story 的操作卡。
11 行・放進 ~/.claude/skills/story-render/SKILL.md
---
name: story-render
description: 限動出圖 story_render.py/daily_post --kind story 的操作卡。當使用者說「出一組限動」「限動池空了」「限動圖在哪」時使用。
---
# story-render(①地基 story_render.py,由 daily_post 叫)
- 出圖:`unset NODE_OPTIONS; .venv/bin/python daily_post.py --kind story --dry --force`(--dry 只出圖不記台帳;不加 --force 會被「兩天一次」擋)
- 產出:`~/Desktop/內容產出/限動備份/<月>/<日期>_限動_<標題>/01~03.png`+`並排檢查.jpg`+`貼法.txt`;**一定要打開並排檢查.jpg 看**(撞字、切到頭)
- 照片來源 `selfie_files()`:Desktop 列不出來會退 `ai_photos` 鏡像;`.jpeg` 與 `.jpg` 都要認
- 入池:`story:xingking_0627`/`story:stanley_0627`,三張 `{n:"01.png",pos:"50% 24%",big,text:"<div class='ln'>…</div>"}`,`howto` 寫貼圖要貼哪(投票/滑桿/問答箱輪替,一組只一個互動)
- 台帳 `logs/story_last.json`(兩天一次的判斷);他手機發,圖進相簿走 `to_photos.py`(**不能排程**,launchd 碰不到照片 App)
- 乾跑後把 Desktop 那兩個資料夾搬到 `_retired/`,不然他會以為那是今天要發的