雲端第一則 prompt 的主線是現在這條:兩份主線檔都不在時 refresh 去 Gitea 讀 InkStoneCo main 那份一次(inkstone/ISEP#140)
薄殼 SessionStart 跑在 bootstrap.sh 之前,InkStoneCo/ 還沒 clone、家目錄空 ⇒ 兩份都不在 ⇒ countdown.py 退到「期限最近的 milestone」⇒ 第一則 prompt 印逾期 341 小時的舊線。機制沒壞,是順序。 - hooks/lib/mainline.py:第三個來源 fetch_gitea()(本檔唯一會打網路的函式,只有 SessionStart 的 `mainline refresh` 叫它;load()/line() 照舊零網路)。優先序寫進檔頭:家目錄 > repo 那份 > Gitea 那份。 匿名優先,匿名被拒(401/403/404)且拿得到 token 才帶 token 再問一次;讀不到回 None,逾時有上限。 - scripts/mainline refresh:兩份都不在 ⇒ fetch_gitea 一次、只寫家目錄(不 mirror);token 拿不到不炸、不抱怨。 - hooks/tests/mainline-gitea-fallback.test.sh:31 條,假 Gitea 有 public/private/500/garbage/notitle/hang 六種回法。 假設(票上紅線寫「一律匿名不帶 token」,其前提「Gitea 匿名讀得到」實測為假): inkstone/InkStoneCo 在 Gitea 是 private——匿名打 raw/contents/repo API 都 404,ISEP 同端點 200。 ⇒ 照字面做這張票在真環境永遠讀不到。改成匿名優先、被拒才帶 token(同一條 SessionStart 鏈上 countdown-milestone-refresh.sh 本來就帶 GITEA_TOKEN_CLAUDE_CODE 打 Gitea;D20 管的是 GitHub)。 真跑:帶 token 2.06s 讀到 inkstone/Arcrun#48;拔 token rc 0、零檔案、「現在沒有主線」。 版本:待總管定版。 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0178ef1fGw3XeZtpN7LaZrm4
This commit is contained in:
+39
-4
@@ -24,7 +24,9 @@ leo 2026-08-27:「**14 個里程碑同時亮著卻不知道該看哪個**」
|
||||
── 答案為什麼唯一 ─────────────────────────────────────────────────
|
||||
主線住在一個檔裡(`~/.claude/isep-countdown/mainline.json`),那個檔**放得下一條**。
|
||||
(inkstone/ISEP#130 起它有一份隨 repo 走的鏡像:`InkStoneCo/system-dev/mainline.json`——
|
||||
雲端沒有家目錄那份,讀的就是它;`set`/`adopt`/`clear` 兩份一起寫,`refresh` 只寫家目錄。)
|
||||
雲端沒有家目錄那份,讀的就是它;`set`/`adopt`/`clear` 兩份一起寫,`refresh` 只寫家目錄。
|
||||
inkstone/ISEP#140 起:兩份都不在時(雲端薄殼 bootstrap 之前的形狀),`refresh` 會去 Gitea
|
||||
讀 `inkstone/InkStoneCo` main 上那份一次、寫進家目錄——優先序寫在 `hooks/lib/mainline.py` 檔頭。)
|
||||
沒有清單、沒有優先序、沒有「前三名」——`set` 覆蓋掉的那條就不再是主線。
|
||||
⇒ 問一次只會拿到 0 或 1 個答案,不會拿到 14 個。
|
||||
|
||||
@@ -144,6 +146,8 @@ def cmd_show(argv):
|
||||
print(" 要標一條:`scripts/mainline list` 看有哪些 → `scripts/mainline set <owner/repo#id>`")
|
||||
print()
|
||||
print("📌 在標之前,每回合的 🎯 那一行也會照樣講「現在沒有主線」,不會編一條出來。")
|
||||
print(" 雲端:SessionStart 的 `mainline refresh` 會先去 Gitea 讀 inkstone/InkStoneCo main 的")
|
||||
print(" system-dev/mainline.json;還是沒有 ⇒ 那份不存在,或這台拿不到 Gitea(inkstone/ISEP#140)。")
|
||||
return
|
||||
c, total, pct = ML.progress(ms)
|
||||
print("🎯 現在的主線:%s「%s」" % (ML.ref_of(ms), ms.get("title")))
|
||||
@@ -247,12 +251,43 @@ def cmd_clear(argv):
|
||||
|
||||
|
||||
# ── refresh ──────────────────────────────────────────────────────────────
|
||||
def soft_token():
|
||||
"""拿得到就給,拿不到回空字串。`refresh` 跑在 SessionStart,**不准因為沒 token 就整支炸**
|
||||
——雲端薄殼的 remote 是 GitHub、家目錄是空的,那正是它最需要活著的時候。"""
|
||||
if T is None:
|
||||
return ""
|
||||
import contextlib
|
||||
import io
|
||||
try:
|
||||
with contextlib.redirect_stderr(io.StringIO()): # token() 拿不到會先抱怨再 exit:兩個都吞掉
|
||||
return T.token() or ""
|
||||
except (SystemExit, Exception):
|
||||
return ""
|
||||
|
||||
|
||||
def cmd_refresh(argv):
|
||||
"""SessionStart 跑一次。**拿不到就原封不動**——寧可資料舊,不要把主線弄丟。"""
|
||||
"""SessionStart 跑一次。**拿不到就原封不動**——寧可資料舊,不要把主線弄丟。
|
||||
|
||||
inkstone/ISEP#140:家目錄與 repo 那份都不在(雲端薄殼跑 SessionStart 時 `InkStoneCo/`
|
||||
還沒 clone)⇒ 去 Gitea 讀 `inkstone/InkStoneCo` main 上那份**一次**,寫進家目錄。
|
||||
之後每一則 UserPromptSubmit 讀的是家目錄,路徑上照舊沒有網路。
|
||||
讀不到 ⇒ 什麼都不寫,退回現行行為(`countdown.py` 的第二基準)。
|
||||
"""
|
||||
ms = ML.load()
|
||||
if not ms:
|
||||
return # 沒有主線就沒有東西要更新,安靜結束
|
||||
d = T.api_soft("/repos/%s/%s/milestones/%s" % (ms["owner"], ms["repo"], ms["id"]))
|
||||
got = ML.fetch_gitea(token=soft_token) # 傳函式:匿名讀得到就不去碰 token
|
||||
if not got:
|
||||
return # 兩份都沒有、Gitea 也問不到 ⇒ 真的沒有主線,安靜結束
|
||||
ML.save(got) # 只寫家目錄:雲端沒有 InkStoneCo/ 可寫,本機不弄髒工作樹
|
||||
ms = ML.load()
|
||||
if not ms:
|
||||
return
|
||||
if T is None:
|
||||
return
|
||||
try:
|
||||
d = T.api_soft("/repos/%s/%s/milestones/%s" % (ms["owner"], ms["repo"], ms["id"]))
|
||||
except SystemExit:
|
||||
return # 拿不到 token:主線已經在了,進度晚點再更新,不炸
|
||||
if not isinstance(d, dict) or not d.get("title"):
|
||||
return # 讀不到 ≠ 主線不存在
|
||||
ms.update({
|
||||
|
||||
Reference in New Issue
Block a user