讀者站上回報(Supabase)→ 分類/反 spam/去重 → GitHub issue(對齊既有 template)→ 接 MAINTAINER 飛輪。Routine twmd-feedback-triage fires 07:00 daily(maintainer-am 之前); manual via "/twmd-feedback-triage" or "跑 feedback triage" or "把回報轉成 issue". TRIGGER when: routine twmd-feedback-triage fires / user says "跑 feedback triage" / "處理讀者回報" / "把站上回報開成 issue".
業務邏輯 canonical 在 FEEDBACK-TRIAGE-PIPELINE.md。 本 skill 是薄殼,只 pointer + HARD gate,不複寫 threshold / SOP / step。
跑 /twmd-become review 完整走 BECOME_TAIWANMD.md Step 0-9。Review mode self-test(含 Q13 anti-bias + Q14 cross-session)全過才進 Stage 1。
ACK 一行(寫 memory 頂部):
✅ BECOME ack: mode=review / 8 organ 最低=<consciousness-snapshot.sh> / Q13=PASS / Q14=PASS開 issue = 機械轉錄讀者原話(可自動)。以維護者身份回覆 / close / merge 永遠留人類 —— 那是 MAINTAINER-PIPELINE 的事,不在本 routine。
完整 5 stage(BECOME → PULL → TRIAGE → FILE → WRITE-BACK → FINALE)讀 FEEDBACK-TRIAGE-PIPELINE.md §每 stage。核心動作:
git pull origin main
# 機器身份:開 issue 走 GitHub App,不用宿主機的哲宇帳號(HG11)
export GH_TOKEN="$(bash scripts/tools/gh-app-token.sh)"
bash scripts/tools/gh-app-token.sh --whoami # 應為 {"issues": "write", "metadata": "read"}
# 先 dry-run 看分類(HG2 無 email / HG5 spam / HG6 dedupe 自己核一遍)
node scripts/feedback/triage.mjs
# 確認 OK 才 --commit(真開 issue + 回寫 status)
node scripts/feedback/triage.mjs --commit
# 讀一筆的全文(HG13 的必經動作;唯讀,不碰 status/GitHub/archive)
node scripts/feedback/triage.mjs --show <feedback-id> # 可重複/逗號串
node scripts/feedback/triage.mjs --show-all # 這批全部
# 某筆不能開成公開 issue(例:指涉具名第三人的指控)→ 排除那筆但照樣跑完(HG13)
node scripts/feedback/triage.mjs --commit --exclude <feedback-id>
# 「這個距今算久嗎」——歷史最長到達間隔(唯讀;佇列空的那一輪會自動印)
node scripts/feedback/triage.mjs --intake-stats
# 「讀者送不送得進來」——站上表單的 backend + 金鑰可達性(唯讀 GET,不送假回報;
# 佇列空的那一輪會自動印)
node scripts/feedback/triage.mjs --intake-health未配置 Supabase(SUPABASE_URL/SUPABASE_SERVICE_KEY 缺)→ emit「feedback backend 未配置,skip」,不算 fail(escalation 只看 quality gate)。
triage.test.mjs regex 守,CI 必綠)security-review label + banner,不 auto-act,留人類 gate 處置。GH_TOKEN 必須是 App installation token(ghs_ 開頭)。
空值或缺失 = 停手,不要讓 gh 退回哲宇帳號把 issue 掛成維護者親開。docs/feedback/archive/(無 email),
issue 留言 sync 進 §溝通紀錄。收官前 git add docs/feedback/archive/(不進 git = 主權層失效)。archive-reconcile=N/M。⚠️ = 有 filed 但無 git 紀錄(triage 之外
補標 filed 會繞過主權層)→ 用 buildArchiveRecord() 補齊,不要手寫。印 unavailable
不等於對得起來。只看 archive-scanned=N 是 proxy signal(數存在的檔,量不出缺席)。comment-reconcile=N/M。三個方向意義不同:
⚠️ 漏收 = sync 沒收到(破口,要查)/⚠️ 抓不到留言 = gh/token 壞了(不准讀成對得起來)/
上游已刪留言…git 留著 = 留言在 GitHub 被刪、git 留住了(主權層正常,不是問題)。
只看 archive-comments-synced=N 是 proxy signal——0 分不出「沒有新留言」跟「一則都抓不到」。--show <id> 讀全文再判斷,攔一筆用 --exclude <id>,不要整條不跑:
報表只印標題/類型/id,不印內容——要判斷得先 --show 把全文拉出來讀(唯讀路徑,
打錯的 id 會出聲,不靜默印空清單)。判斷某筆不能開成公開 issue 時(指涉
具名私人、跟監細節、要求身份保密的檢舉信 — 三道 HARD gate 全會放行、分類器會判 file),
用 --exclude 排除後照樣 --commit,status 維持 new 留人類決定收尾,兩道對賬不受影響。
整條 --commit 不跑 = 保管那半跟著轉錄那半一起消失(LESSONS
zero-input-cycle-drops-the-reconciliation)。攔下後升 OBSERVER-QUEUE 等哲宇,不自己回覆回報者。預設 --limit 50、排序最舊優先,所以佇列長過 50 筆時新讀者永遠排在窗口外,
而 fetched 50 跟「佇列剛好有 50 筆」逐字相同。報表現在會自己說:
[triage] 取數窗口:讀進 50 筆已到 --limit 50 上限 · 佇列 status=new 共 81 筆 · ⚠️ 窗口外還有 31 筆這一輪沒看到印「佇列總數查不到」不等於窗口外沒東西(同 HG12b unavailable 紀律)。
這一行讓當班知道該撈,不代替當班去撈——下面那條加大 --limit 的零判斷動作照做。
--show 也被同一個窗口擋著(v1.18,2026-11-07):--show 跟 dry-run 共用 --limit,
所以窗口外的讀者 --show 讀不到,而 v1.17 以前它對這種情形說「根本沒查到這筆」——
跟 id 打錯逐字相同,處置相反。現在四種讀數分開,窗口滿且外面還有時會說
「這個 id 可能就排在外面,加大 --limit 再試一次」。
--show 窗口外的那幾筆記得帶 --limit:node scripts/feedback/triage.mjs --limit 200 --show <id>。
它不改預設值、不自己加大窗口:窗口該開多大是閾值,跟「那 80 筆怎麼收尾」同屬
OBSERVER-QUEUE #119 的 (b),留哲宇。
為什麼這條存在:第五輪(11-06)照交接加大 --limit 撈到窗口外第 82 位一位署名醫師
的勘誤,距今 6 小時。前一輪才寫「今天沒有新讀者被擋住,但那是運氣,不是機制」。
什麼叫「沒有東西要轉錄」(v1.16,2026-11-05 放寬):取數為空,或取數非空但整批都被
--exclude 攔掉。兩者對讀者的意義相同——今天沒有一筆讀者的話進得到 issue。觸發條件原本
只寫在「取數為空」上,於是 10-30 那批 80 筆攻擊填滿窗口時,fetched 變成大數字就讓三行
集體沉默,而那幾天正是最該問「真實讀者還送不送得進來」的時候。現在儀器自己會印,
不必當班手跑(手跑的入口 --intake-health/--intake-stats 照舊存在)。
讀取端兩行:最近一筆回報距今幾天(v1.9)+那個距今算不算久(v1.12)。
第二行拿全庫算歷史最長到達間隔——這把尺前四個 cycle 都是當班手寫的,其中兩次答案偏小且方向固定
(帶 limit 問極值只會往小的錯)。印 查不到 / 樣本不足 不等於間隔正常,跟 HG12b
unavailable 同一條紀律。兩行都刻意不印 ⚠️、不設閾值——閾值要 Full mode + 人類 gate。
寫入端健檢(v1.13,--intake-health,自動跑):讀取端那兩行只證明「我沒漏接」,
證明不了「讀者送得進來」。站上表單指向哪裡是 build 時由 repo Variables 注入的,
resolveBackendKind() 對「mode=supabase 但金鑰空」安靜降級成 github-only——讀者照樣
看到回報入口、Supabase 一筆不進,而這在讀取端跟「讀者沒話說」逐字相同。四層三態
(✅ 活著/⚠️ 確認壞了,讀者此刻送不進來/❔ 今天沒驗到,不等於沒事):
站上 bundle/表單的 backend/金鑰與資料表/登入這條路(2026-10-14 新增,GET
/auth/v1/settings 比對 server 端 provider 與 disable_signup)。
⚠️ 出現就是破口,當輪要查,不要當成噪音往下傳。
報表每次自己講它涵蓋不到 INSERT:未知是被縮小,不是被消掉。OAuth 那半由第四層收掉,
但只有真的量到才算收掉——該層回 ❔ 時 OAuth 自動回到未涵蓋清單。
這支尺的告警分支 2026-10-12(前三層)與 2026-10-14(第四層四條分支)各過了一次正控制,
讀數可引用。要再驗一次:
FEEDBACK_HEALTH_SITE="http://127.0.0.1:9/" node scripts/feedback/triage.mjs --intake-health
——指向刻意壞掉的目標,驗的是出貨的那份程式碼,不另外手寫邏輯(驗替身等於沒驗)。
/twmd-finale → memory 必含 BECOME ACK、file/reject/skip count、開的 issue #N、archive 檔數、
archive-reconcile=N/M(HG12b)+ comment-reconcile=N/M(HG12c)兩道對賬結果、Handoff 三態。
commit 前:git add docs/feedback/archive/(per HG12,讓回報+溝通紀錄落進 git)。
ARGUMENTS: (none — script 自己讀 Supabase status='new')
frank890417/taiwan-md
3f3766c
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.