Community程式設計與開發github.com

zheref/en

驅動一個開放中的 Pull Request,在強制執行的行動週期上限內達到 verified Ready 狀態。當 $mukai 移交其 PR,或當維護者對 <CODE>#<N> 呼叫 $en 以處理一個開放中的 PR 時使用。CI 或審查擱置中則保持運行;靜態輪詢不消耗週期。處於 Ready 狀態時,僅合併一個透過 Nen 的受保護守衛記錄的 Futon 擁有的堆疊交付;將其他 PR 移交給維護者。永遠不投審查票。此輪運行結束後,呼叫者提供結束流程 — 必須的 $cleanup,以及可選的 $third-hand — En 不負責此結束流程。

en 是什麼?

En 是一個複合操控型技能,專注於將單一 Pull Request 驅動至 verified Ready 狀態。它透過一個由 Izanagi 語法強制執行的行動週期上限來運作,預設為 20 次迭代,防止無限制的觀察。此技能在 Codex、Claude Code 和 Cursor 等平台上運行,並與 Mukai、Sharingan、Hanten、Murasaki 和 Spiritual Message 等其他技能協作。En 透過一個結構化流程引導 PR:初始登陸報告、基於當前樹狀證據的動態驅動、與 CI 狀態同步的觀察輪詢、監控 Copilot 審查輪次、以及最終準備好合併的守衛。它透過共享的 .nen/loop 分類帳來維持跨會話的狀態堅持,確保即使原始工作樹已清理,相同的週期上限也會在各次調用中持續存在。

相容平台✓Claude Code✓Codex CLI~Cursor✓Antigravity
npx skills add https://github.com/zheref/hatsu/tree/HEAD/surfaces/codex/en

Installed? Explore more 程式設計與開發 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

共用政策位置: docs/DISCOVERY.md、docs/WORKFLOW.md、 docs/LAUNCH-MIGRATION.md、docs/STANDALONE-ENTRY.md、docs/PROCESS.md、docs/using/README.md 和 docs/using/mirrors.md 屬於已解析的 Hatsu 插件根目錄,而非消費存放庫。在已安裝的表面上,使用 ten 列印的絕對根目錄來讀取這些檔案(如果無法取得,則透過該技能重新解析)。下方的相對連結標識原始位置;缺少的消費者 docs/ 副本並非缺少政策,且不得觸發重複提交。切勿在目標存放庫中複製或發明第二份政策。

En — 環繞一個 PR 直到它 Ready

性質:操控者。 En 所做的一切都是面向看板的 — 驅動、報告、通知、觀察。Kurapika 在執行它時這麼說。當一個週期將他送回變更本身 — 審查者的發現需要程式碼修改 — 該修復的模式是變更自身的模式(強化者、具現化者、變化者),在該週期中明確命名,然後交還。

專注於這個 PR:報告它,觀察每次當前頭部檢查和審查,將它驅動到 verified Ready,在其人類門檻處響鈴一次 — 然後在至多 N 個行動週期後停止。

En 是本地平面的最後一個複合技能,也是唯一可能需要 在 PR 被打開之後持續保持關注 的技能。$mukai 透過提供這個交接來結束 — 僅在 nen/workflow.json → mukai.autoEn(ruling 2026-09-28)下自行啟動;從那裡 PR 屬於 En — 且僅在 autoEn 路徑上,活躍的使用者回合是來自交接的輸入啟動,這本身就是它自己的回合 — 直到 Sharingan 證明它 Ready,或一個具體的阻擋者/上限/終端狀態/取消結束 En 的運行。合併是維護者後續的行為,除非是 § 5 中記錄的 Futon 交付例外。此運行不會收割,也不會清理。 當 En 完成時,呼叫者透過選擇器(cleanup § 2,row wrap-up;ruling 2026-10-13)提供 結束流程 — 僅在 cleanup § 2 的兩個先決條件下(HR-366);§ 5 提示下的 Ready PR 不符合任一條件:$cleanup(必須)和 $third-hand(可選)— 獨立的技能,在此檔案的協議返回後啟動,絕不作為 En 的一個步驟。

此檔案進行組合。它不會重新指定。 下方的每個步驟都是另一個已命名和連結的技能的,其程序、其退出碼反應、其拒絕和其殘留物都在那裡。如果你在這裡找到一個實際上屬於該技能的規則,那它就在錯誤的檔案中 — 去閱讀它被撰寫的地方,因為一個在兩個地方重複陳述的規則會在其中之一發生偏離。

真正屬於 En 自身的是上限、觀察的形狀以及會話結束時的邊界。 這三點是 § 2、§ 6 和 § 7,它們是此檔案唯一斷言任何事物的位置。Third-Hand 不在那個邊界內。


1. 調用

P1 — 此輪運行以 $ten en 開頭(ten § 6 用自己的名義追上此階段缺少的先決條件;此輪運行呼叫的各階段跳過它們自己的)。

$en [on <CODE>#<N>]

由 $mukai 在 mukai.autoEn 下啟動,不帶子句 — PR 就是步驟 8 剛剛打開的那個 — 由 $getsuga § 3 為其剛剛打開的發布提案啟動(那裡 en 運行步驟 1–5 並將其引用的裁決返回給 getsuga;步驟 6 的鈴聲不會響起,因為 getsuga § 3a 就是那個 PR 的合併),由 futon 的每個問題鏈為其努力打開的 PR 啟動,或為其 integration→main PR 啟動(futon § 5 不打開 PR 到其 integration 分支;它在本地合併),或由維護者啟動,命名一個已經打開的 PR(mukai 的優惠行)。每個會話打開或導致打開的 PR 都透過此輪運行或引用裁決到達維護者的規則是 docs/PROCESS.md § Reporting a phase(zheref/hatsu#103)引用的,而非重述:

nen parse en --grammar "on [<ref>]" --line "<the invocation, minus the $en prefix>"

在 v0.3.0(docs/ab/en.md § 2.1)進行即時驗證:on HA#41 → ref: HA#41 退出碼 0,而一個裸的 on 在子句不存在時也能解析,同樣退出碼 0。該子句在字面量後錨定,原因如 $spiritual-message § 1 所記錄 — 一個孤立的括號位置會在模板處被拒絕。

空行被拒絕,這就是複合技能根本無法解析的原因。 即時驗證:--line "" 退出碼 2,並顯示 "the line must open with the literal 'on' — it is what introduces <ref>"。一個錨定的可選子句需要其錨點;"no clause" 和 "empty line" 是不同的輸入,只有第一個能解析。所以 mukai 在 autoEn 下直接移交 PR,並且 根本不呼叫 nen parse en — 回顯一個沒人輸入的行的解析結果是徒勞的,而將 "" 餵給它會產生一個毫無意義的拒絕。解析僅在維護者鍵入了一個子句 時 運行。

缺少的參數或配置項目會被詢問並內聯設定(missing-argument、missing-configuration;WORKFLOW.md § 4 Ask, set up, continue):維護者的行退出碼 2,或在會話未持有任何 PR 時未指定 PR,這是觸發條件,會在選擇器中提供會話的開放 PR 並在得到答案後繼續,這絕不是運行的結束。

一次性提前解析程式碼,並為後續每次呼叫保留 slug — 永遠不以第二種方式重新推導它(claude/agents/kurapika.md § How you work):

nen repo resolve <CODE> --repo <path to the target repo's own checkout>
nen ref format --code <CODE> --kind PR --number <N>

一個已關閉或已合併的 PR 會立即結束運行,並告知其發生什麼。沒有什麼可降落的。

一個頭部已經發布的開放 PR 在每次延續時都留在 En 中。 當其分支落後於 PR base,或審查修復需要發布時,執行 En 的當前樹狀證據步驟和 $murasaki 的有防護的快進推送(§ 3 和 murasaki § 6)。不要將已發布的分支送過 $aka 的 squash。首次發布遵循其調用工作流程已攜帶的授權,無論是直接的 Aka 呼叫還是像 Futon 這樣的複合。En 仍然在 § 5 的單獨人類合併門檻處停止。例如,當 #273 推進了 main 時,PR #274 已經在 b5fddea 發布;其追趕合併保留了那個已發布的祖先,而 Murasaki 推送了驗證過的後代 5de39c5。

此複合呼叫的各階段跳過其自己的 ## 0. Standalone entry 部分。docs/STANDALONE-ENTRY.md 是手動鍵入任意 checkout 的階段的合約;從這裡到達的階段繼承此運行的 P1–P4 — 預熱、方向、變更集和每個衍生參數 — 重新推導它們會產生對一個此複合已解決的問題的第二個答案。每個階段會說哪個複合正在持有它。

2. 上限 — 語法,而非預設值

En 會行動。 步驟 2 和 4 進行驅動;一個發現新審查發現的週期會回到變更中並推送修復。這使得 en 成為迴圈對的 突變 半部,且 $izanagi 的整個紀律都約束著:一個會寫入的迴圈需要一個會讀取的迴圈所沒有的邊界,而將邊界作為語法的一部分意味著它永遠不會被預設、繼承或遺忘。

鍵檔案用途當鍵(或檔案)不存在時的預設值
monitor.maxCyclesnen/workflow.json上限 — 行動 週期的計數(§ 6)20
monitor.pollSecondsnen/workflow.json觀察之間的時間間隔,作為 --interval-ms300(→ --interval-ms 300000)
branch.basenen/workflow.json§ 5 提示的基礎。步驟 3 從中追趕,而 "behind" 是相對於 PR 自身的 baseRefName(gh pr view <N> --json baseRefName)測量的,這是 en 提示的每個 PR 的 branch.basemain
reports.dir / .sections / .retainnen/workflow.json步驟 7 的檔案 — backlog-board § 3 的鍵Reports / 必需,無預設(WORKFLOW § 2 → reports) / final-only
notifications.rungs / .soundnen/workflow.json步驟 6 的階梯 — $jutaisho 的鍵["push","os","sound"] / Glass

在週期 1 之前,上限透過拒絕缺少上限的動詞來明確說明:

nen parse izanagi "take <CODE>-PR-#<N> to its human gate until it is Ready up to <monitor.maxCycles>"

在 v0.3.0(docs/ab/en.md § 2.2)進行即時驗證,兩種方式:

$ nen parse izanagi "take HA-PR-#41 to its human gate until it is Ready up to 20"
task: take HA-PR-#41 to its human gate
until: it is Ready
cap: 20
exit=0

$ nen parse izanagi "take HA-PR-#41 to its human gate until it is Ready"
nen: no 'up to <N>'. Izanagi is the MUTATING half of the loop pair and the cap is required grammar,
never defaulted or inferred -- an invocation without it is refused rather than run once 'to see'.
  try: take HA-PR-#41 to its human gate until it is Ready up to <N>
exit=2

數值來自 monitor.maxCycles;要求來自語法。 這是兩個不同的東西,而這個區別就是關鍵:檔案提供一個數字,動詞拒絕在沒有數字的情況下運行。一個缺少 monitor 區塊的存放庫會得到明確說明的 20 — 它不會得到一個無界觀察,因為 "the file said nothing" 正是繼承且被遺忘的預設值具有危險性的情況。

在 nen 0.7 已退休:手動計數行動週期

每個行動週期在行動之前被 CLAIMED,而上限透過拒絕該 claim 來強制執行 — izanagi § 3 的退休,整體繼承:

git rev-parse --path-format=absolute --git-common-dir   # <common>,在 effort 工作樹中
nen loop iterate --id en-<CODE>-<N> \
  --line "take <CODE>-PR-#<N> to its human gate until it is Ready up to <monitor.maxCycles>" \
  --repo <common>

退出碼 0 會列印 iteration <n>/<cap> 以及剩餘多少 — 動詞自身的詞是 iteration,而 en 的週期就是它所 claim 的;退出碼 1 就是上限,並在 § 6 的 cap-out 行結束運行,並在 nen 自身的拒絕中命名調用。--line 是與上面 nen parse izanagi 回顯的相同字串,在每次 claim 時重述,所以 monitor.maxCycles 不能在運行中被悄悄提高:一個攜帶不同 N 的 claim 會退出碼 2,並命名兩行(針對此確切形狀進行即時驗證 — up to 3 正在運行,up to 20 被 claim — docs/ab/izanagi.md § Retired at nen 0.7)。

--id 是 PULL REQUEST,而非會話,這是一個值得陳述其後果的決定:分類帳是 .nen/loop/en-<CODE>-<N>.json,位於 git common 目錄 下,所以它比會話(§ 7)和 effort 工作樹(cleanup 會移除它)存活得更久(docs/ab/en.md § The cap outlives the worktree),所以 重新調用同一個 PR 的 $en 會恢復同一個上限,而不是從週期 1 重新開始。這是 "twenty acting cycles to ready this PR" 的誠實解讀 — 一個會話邊界重置的上限將是一個無人擁有的上限。當 readiness 驅動真正結束時 — Ready、關閉或在門檻移交給維護者 — 使用 nen loop iterate --id en-<CODE>-<N> --line "<same line>" --release "<why>" --repo <common> 關閉分類帳;一個在其上限的迴圈總是仍然可以被釋放,而之後一個新的上限是一個 新的 --id,被刻意選擇並大聲說出,絕非重新輸入一行。

上限是上限,而非目標。 達到它表示未能達到 Ready,並被報告為失敗:還不是什麼的事實,以及下一個週期本會做什麼。izanagi § 4 的規則,未變。審查者輪次政策是 $sharingan § 6 的,在那裡陳述一次並在這裡引用,從不重述:

  • 在 $hanten 解決之後請求一輪 Copilot 審查,從不在此之前。
  • 到達的問題會進行補救,並且僅在 sharingan § 6 的兩個界限內(round_policy.maxRounds 請求,round_policy.minRounds 已解決;row cap-reached),一個欠下的輪次會被重新請求而不需詢問,然後 en 繼續觀察;任一界限達到即為 § 6 的第五個停止點。
  • 在任何重新請求之前,nen wake verify --repo-slug <owner/name> --now <ISO> --author-pattern <the maintainer login> --run 會重新驅動一個被吞沒的運行一次(action_required 或 startup_failure 從未執行過的);Copilot bot 的 action_required 運行無法重試,並被如實報告。然後是無操作同步保護:計算領先於最後審查頭部的提交數量(git rev-list --count <reviewed-head>..HEAD,唯讀)以及 diff stat;零個可審查變更意味著不請求。
  • Copilot 會自動審查每個推送,所以上限管理的是請求,而非到達;一個超過上限的到達仍然會被補救並解決其執行緒。

超過上限時,運行以未就緒狀態結束,並附帶看板。兩者都不是 G5。nen/workflow.json → monitor.maxCycles 是 en 的行動週期上限,一個不同的數字。

3. 執行順序中的運行

#步驟擁有該步驟的技能何時
1登陸報告$spiritual-message as landing一次性,在開始時 — 00–07 加上 08 PR 主體 和 09 Readiness。如果此 En 是由 mukai(autoEn)啟動的,或在同一會話中從其優惠輸入且沒有更新的人類請求,00 仍然回答該 mukai 請求
2驅動$sharingan第一個阻塞條件觸發。在 § 5 的合併門檻處停止,除非是 Futon 的堆疊交付例外。注意: 在 docs/ab/en.md § 3 中驗證 — Sharingan 在 § 5 的提示處停止;§ 6 的鈴聲僅由 En 的觀察階段響起,而不是由驅動階段。

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

相關技能