feat(88): 版本線判別器從「有沒有 v」換成 DAEMON_LINE,產生端才吐得出裸號
leo 2026-08-17:「對外號就是三個數字,不要 v」。
08-18 第一次改失敗的理由要先講清楚:那個 `v` **兼任版本線判別器**
(daemon `v0.18.x` vs 雲端引擎 `1.4.x`),有四處在讀它。天真拿掉之後那些閘
**不報錯**,而是往下比對到更舊的 `## v0.18.29(…)` ⇒ 打包出 0.18.30 的執行檔、
manifest 卻宣稱是 v0.18.29。**靜默,21 站全綠。**
── 四處讀取點,各自靠什麼分辨(換掉之後)──────────────────────────
① `daemon-notes.DAEMON_RELEASED_RE`(daemon-in-bundle-gate 與 ship.mjs daemon-sync
共用的那一份,第一輪已從四份拷貝收攏成一份)
舊:`^## (v\d+\.\d+\.\d+)(` ——「有 v = daemon」
新:`daemonReleasedReFor(repoRoot)` 由 `collector/DAEMON_LINE` 產生
`^## (v?0\.18\.\d+)(` ——「在宣告的那條線上 = daemon」
② `daemon-in-bundle-gate.collectFacts/judge`(同上那份的使用端)
新增一項 `daemon-line-declared` 排在**所有檢查最前面**:
讀不出 DAEMON_LINE = 沒有判別器 ⇒ 當場斷,不給預設值。
另記一個**只給錯誤訊息用**的 `changelogTopAny`,讓「沒中」時說得出
「你指到的是 1.4.47,那是雲端那條線」——判斷與診斷分開。
③ `ship.mjs` daemon-sync 站:同 ①,並在丟例外時附上量到的事實。
④ `daemon-notes.changelogRelFor()`
舊:`/^v/.test(version)` ⇒ 裸號時代會把 daemon 的 0.18.31 指去雲端的
CHANGELOG.md(叫人去錯的檔補說明)。新:比對版本線。
⇒ 判別依據換成**宣告出來的事實**,不是外觀 ⇒ 產生端這才拿得掉那個 `v`:
`daemon-version.py` 升版路徑 `"v%d.%d.%d"` → `"%d.%d.%d"`。
「重打同一版」路徑刻意**不動**(沿用 prev_prefix):selfupdate.go 的
newerThanCurrent() 用字串不等於判斷更新,重打時換寫法會讓每一台已安裝的機器
看到一個內容一模一樣、卻宣稱是新版的假更新。
── 測試(+7 支,每支都附反向對照)──────────────────────────────────
故意製造「版本線判別會出錯」的情境,並證明**新的會擋、舊的會靜默放行**:
· 產生端吐裸號 → 閘讀到最新那一版(反向對照:舊判別式讀到更舊的一版)
· 源碼樹 0.18.31/bundle 停在 v0.18.30 → 擋(舊判別式在此判「相符」⇒ 放行)
· DAEMON_LINE 換 0.19 而 changelog 還是 0.18.x → 擋(舊做法看不出線換了)
· DAEMON_LINE 缺席/寫壞 → 擋,且擋在第一項
只有「新的怎麼跑」而沒有「舊的怎麼跑」的話,這些測試就只是回音,不是閘
(wiki/mistakes.md「測試複製了實作邏輯就不再是閘」)。
installer 262/262(+5)、collector daemon-version 11/11(+2)。
inkstone/arcrun-rag#88
This commit is contained in:
@@ -357,28 +357,31 @@ def main():
|
||||
nxt = (major, minor, 0)
|
||||
else:
|
||||
nxt = (prev[0], prev[1], prev[2] + 1)
|
||||
# 🔴 這裡**還是吐 `v`**,而 leo 2026-08-17 要的是「不要 v」。這不是漏掉,是**擋住了**:
|
||||
# 🔴 **裸號就是從這一行開始的**(leo 2026-08-17「對外號就是三個數字,不要 v」)。
|
||||
#
|
||||
# 這一行往下走 `heading` 寫進 changelog、`print(version)` 餵給 build-*.sh 的
|
||||
# `${VERSION}` ⇒ 檔名(`Arcrun-v0.18.x.dmg`)與 `manifest.daemon.version`
|
||||
# `${VERSION}` ⇒ 檔名(`Arcrun-0.18.x.dmg`)與 `manifest.daemon.version`
|
||||
# ⇒ `install.arcrun.dev/api/latest` 的 `daemon.version`。
|
||||
# **leo 看到並質問的那個 `v`,就是從這一行長出去的。**
|
||||
# **leo 看到並質問的那個 `v`,就是從這一行長出去的**,所以也只能從這一行拿掉。
|
||||
#
|
||||
# 2026-08-18 實際試著改成裸號,當場撞到:**那個 `v` 目前身兼「哪一條版本線」的
|
||||
# 判別器**。三支閘(daemon-freshness/daemon-in-bundle-gate/ship.mjs 的
|
||||
# daemon-sync)+`daemon-notes.changelogRelFor()` 都靠「有沒有 v」認出
|
||||
# 「這份 changelog 到底是不是 daemon 的」。一改裸號,daemon 的閘就開始把雲端那條
|
||||
# `## 1.4.47(…)` 當成 daemon 版本撈走 ⇒ `daemon-in-bundle-gate.test.mjs`
|
||||
# 的 ①⑮⑯ 三支轉紅,而它們釘的正是 D95 第二輪剛修好的病
|
||||
# (出貨線指到錯的 changelog 卻**安靜放行**)。
|
||||
# ── 為什麼 2026-08-18 第一次改失敗,第二次才成立 ─────────────────────
|
||||
# 第一次天真地把 `v` 拿掉,當場撞到:**那個 `v` 身兼「哪一條版本線」的判別器**。
|
||||
# 出貨線那幾道閘(daemon-in-bundle-gate/ship.mjs 的 daemon-sync/
|
||||
# `daemon-notes.changelogRelFor()`)全靠「有沒有 v」認出「這份 changelog 是不是
|
||||
# daemon 的」。一改裸號,它們**不報錯**,而是往下比對到更舊的 `## v0.18.29(…)`
|
||||
# ⇒ 打包出 0.18.30 的執行檔、manifest 卻宣稱是 v0.18.29。靜默,21 站全綠。
|
||||
#
|
||||
# ⇒ 要落到產生端,得**先給那三支閘一個替代判別器**(建議拿 `DAEMON_LINE`
|
||||
# 宣告的線去比對,例 `^## v?0\.18\.\d+(`——同時擋掉「錯的檔」與「錯的線」,
|
||||
# 且不依賴外觀)。那會動到 `topReleasedVersion()` 等對外簽章、要跨 installer/
|
||||
# 與 collector/ 一起改,與正在進行的 collector 拆 repo 相衝。
|
||||
# ⇒ 交接說明見 `inkstone/arcrun-rag#88`。**在那之前不要單獨把這一行改裸**,
|
||||
# 單獨改的下場是「打包出新版執行檔,manifest 卻宣稱是舊版」——靜默、且 21 站全綠。
|
||||
version = "v%d.%d.%d" % nxt
|
||||
# 第二輪(本次)先換掉判別的承載:改用 `DAEMON_LINE` 宣告的那條線比對
|
||||
# (`^## v?0\.18\.\d+(`,見 `collector/cmd/arcrun-app/daemon-notes.mjs`
|
||||
# 的 `daemonReleasedRe`)。它同時擋掉「錯的檔」與「錯的線」,且**不依賴外觀**
|
||||
# ⇒ 裸號與既有的帶 v 舊版都認得。判別器換好之後,這一行才拿得掉。
|
||||
#
|
||||
# ⚠️ 「重打同一版」那條路徑**不走這裡**(見上面 `has_unreleased` 為假的分支),
|
||||
# 它沿用 `prev_prefix` ⇒ 重打 `v0.18.30` 還是叫 `v0.18.30`。
|
||||
# 那不是漏改,是必要的:`selfupdate.go` 的 `newerThanCurrent()` 用字串不等於
|
||||
# 判斷有沒有新版,重打時換寫法會讓每一台已安裝的機器看到一個**內容一模一樣、
|
||||
# 卻宣稱是新版**的假更新。⇒ 只有**真的升版**才吐裸號,而那正是這一行。
|
||||
version = "%d.%d.%d" % nxt
|
||||
|
||||
if stamp:
|
||||
# 🔴 2026-08-18(inkstone/arcrun-rag#88):**順序反過來了,這是第二個自鎖。**
|
||||
@@ -387,7 +390,7 @@ def main():
|
||||
# 那棵樹底下(D95 第一輪搬進 collector/),所以記下來的是**還沒戳版**那一刻的
|
||||
# 指紋——它描述的那棵樹,從寫完宣告的那一刻起就不存在了。
|
||||
#
|
||||
# 實撞(A/B 重現,見 daemon-version.test.mjs ⑦):build-mac.sh 戳完版打好 dmg,
|
||||
# 實撞(A/B 重現,見 daemon-version.test.mjs ⑨):build-mac.sh 戳完版打好 dmg,
|
||||
# 同一輪接著跑 build-win.sh ⇒ 沒有草稿段 ⇒ 走「重打同一版」路徑 ⇒ 現在的指紋
|
||||
# (含已戳版的 changelog)≠ 帳本裡那個(戳版前的)⇒ 而 dist/ 已經有 dmg
|
||||
# ⇒ 判「版號已對應另一份原始碼」⇒ **第二個平台永遠打不出來**。
|
||||
|
||||
Reference in New Issue
Block a user