Skip to content

Releases: yama-learns/Spark2Groundwork

v1.4.4 — 升級前驗證可復原收據,policy/ 退役

Choose a tag to compare

@yama-learns yama-learns released this 02 Sep 21:16

v1.4.4 — 有一支程式從 v1.4.1 起就在替你簽名

A program had been signing your name since v1.4.1

🔴 v1.4.3 從未發布。 它在發布前的覆核中被找到五項缺陷,三項紅級。
⇒ 你不會在任何地方看到 v1.4.3,⛔ 那不是遺漏。

Upgrading now verifies a recoverable pre-image, and policy/ retires

這一版由一次外部稽核開始:有人用 v1.4.2 升級他的專案,然後把出問題的地方寫成報告。
This release started with an outside audit: someone upgraded a real project to v1.4.2 and wrote up what broke.


🔴 這一版最重要的一件事

v1.4.1 與 v1.4.2 有一個缺陷:按下升級之後,reviewed 標籤會被移到升級前的提交,
畫面上還會印「人工檢查點:我看過了」——⛔ 而你並沒有按下那個按鈕。

🔴 後果⛔ 不是標籤變了,是你的「還沒看過」被清空:
如果升級當下有 AI 做完、而你還沒審閱的工作,那些變更會從「查看變更」裡消失。

v1.4.4 已經修好。⛔ 但已經被移動過的標籤,程式修好也不會自己還原——
⇒ 請照「升級前必讀」的第 ④ 項檢查一次。


🔴 升級前必讀:四件要你動手的事

Before you upgrade: four things only you can do

① 你填的構想搬家了 / Your filled-in idea has moved

如果你曾經把構想填進 prompts/TEMPLATE_decompose.txt,它現在住在專案根目錄,改名叫
第一個想法.md(英文版 FIRST_IDEA.md),與 PROJECT.md 同層。

🔴 prompts/ 是升級時整包替換的資料夾——⛔ 你填的東西不該住在那裡。
升級工具現在會擋下來並列出檔名,⛔ 而不是換掉它。 照它說的搬,再重跑一次。

If you had filled in prompts/TEMPLATE_decompose.txt, it now belongs at the project root as
FIRST_IDEA.md, beside PROJECT.md. prompts/ is replaced wholesale on upgrade — your text
should never have lived there. The upgrader now stops and names the file instead of replacing it.

policy/ 退役了 / policy/ has retired

它的四份文件(SOURCES.mdMODEL_IDENTITY.mdHANDOFF.mdEXTERNAL_TOOLS.md
已經搬進 governance/

升級工具⛔ 不會刪掉你專案裡的 policy/——框架不刪使用者的檔案。
⚠️ 但它會在 checkdiff 與每一次成功的 apply 之後把它列出來:

⚠️ 這幾個資料夾已經退役,⛔ 而升級工具⛔ 不會刪掉你的東西:
      ⛔ `policy/`(於 v1.4.4 併入 `governance/`)——內容已經在 `governance/` 了;
         確認之後這個資料夾可以自己刪掉

🔴 為什麼要講這件事:一個沒有人告訴你的孤兒資料夾,與一份過期的框架文件完全一樣——
它看起來還是框架的一部分,而⛔ 再也不會有任何東西更新它。

③ 框架第一次修訂了一條既有規則 / A shipped rule was revised for the first time

R-34 補了一句:「權威敘述的效力範圍,本身也是需要被查的東西。」

升級完 governance/ 之後跑:

python3 scripts/harness/tool_sync_my_rules.py

它會印出逐行差異,+ 開頭的就是新增的句子。
🔴 把那幾行逐字貼進 my/MY_RULES.mdR-34 的正文,然後再跑一次確認。

⛔ 沒有工具會替你做這一步,這是刻意的。
⚠️ ⛔ 也不要整份取代 MY_RULES.md——那會刪掉你的 P-xx 與覆寫紀錄。
標了 [本專案覆寫] 的條目工具一律不碰,並且會逐條印出來。

R-34 gained a clause. After replacing governance/, run the rule-sync tool: it prints a
line-by-line difference, and the + lines are the new sentences. Paste them verbatim into
R-34's body in my/MY_RULES.md, then run it again to confirm. ⛔ No tool does this for you,
and that is deliberate — a tool that overwrote your rules file was found, in this version's own
review, to still write when its safety check had failed.

④ 🔴 檢查你的 reviewed 基準 / Check your reviewed baseline

⛔ 這一項⛔ 不是「跑一行指令就知道」——SETUP.md §9 有完整的三步,請照那裡做。
這裡只講為什麼它需要三步:

git log --oneline -1 reviewed

🔴 ⛔ 「訊息開頭是不是 snapshot …」⛔ 不能當判準。
⚠️ 在乾淨工作區升級時(最常見的情形),舊版升級是把標籤移到一個既有的 auto: 提交上——
⛔ 而那也正是「你在 AI 做完之後按了一次記錄快照」的樣子。⇒ 兩者長得一模一樣。

⇒ 第二步是查 git-checkpoint.logmode=human 的時間,與你自己的記憶對照。
⇒ 第三步:兩步都判不出來時,⛔ 不猜、⛔ 不重設——退回一個你確定看過的提交重看一次。
⚠️ ⛔ 這一段不要用「查看變更」按鈕做:那個按鈕的基準就是 reviewed,⛔ 而它正是被懷疑的東西。

⛔ 不建議放著不管——一個指向你沒看過的地方的「我看過了」,比沒有標籤更糟:
沒有標籤時「查看變更」會拿 HEAD 當基準並明說,⚠️ 而錯的標籤不會說。

SETUP.md §9 walks three steps. ⛔ The commit message alone is not a criterion: on a clean
working tree — the common case — the old upgrader moved the tag onto an existing auto:
commit, which is also what a legitimate human review looks like. Step 2 reads the
mode=human timestamps in git-checkpoint.log against what you remember; step 3, when
neither can tell, is ⛔ do not guess and do not reset — drop back to a commit you are certain
about and read forward. ⛔ Not with the review-changes button: its baseline is the very tag
under suspicion.


這一版做的事 / What this release does

🔴 升級會在整包替換前證明既有內容可依 Git 語意取回

整包替換仍然是整包替換——⛔ 沒有改成逐檔合併。
⚠️ 但在覆蓋之前,如果那一包裡有新版來源沒有的檔案,程式會先停下來、逐一列名,
⛔ 而且不建立檢查點、不動任何東西。

[FAIL] 「scripts」內有新版來源沒有的檔案,⛔ 尚未建立檢查點,也沒有替換任何東西。
       這些檔案可能屬於專案;請先逐一搬到整包替換範圍外,再重跑:
      ⛔ scripts/my_tool.py

🔴 它⛔ 不猜所有權。 你自己寫的工具請搬到 my/tools/——那裡升級永遠不會碰。

新增第十支感測器:這幾包是不是同一版

觸發個案: 有一個專案的 policy/ 停在 v1.3.0,而 governance/profiles/docs/
已經是 v1.4.2。九支感測器全綠、自測全過。
🔴 ⛔ 沒有任何一支在看「這幾包是不是同一版」——那個狀態是靜默的,靠一次外部稽核才被發現。

它不宣稱的事: 版本標記只回答「這個資料夾自稱哪一版」。
同一個專案還有另一半:prompts/_VERSION 寫 v1.4.2,而裡面的內容仍是 v1.3.0。
⇒ 這支抓得到「自稱不一致」,⛔ 抓不到「自稱一致而內容不同」——那件事要跑 upgrade.py diff

修掉一個會冤枉你的假警報

根目錄的 *.command 這類樣式,掃描目錄被算成了專案的「父目錄」。
🔴 於是隔壁專案的一個檔案,就能讓你這個健康的專案被判成「查不了」。
⚠️ 而第二層檢查又忽略了排除清單,所以 _upgrade/(升級說明叫你建的那個資料夾)
裡的檔案會重現同一個假警報。

⇒ 兩處都修了,並補了三組成對樣本:父目錄一例、_upgrade/ 一例,
加上一個「真的覆蓋崩潰仍然必須報」的正例。

🔴 第三例不能省——只加排除很容易把真正的警報一起關掉。

中文版的 讀我 改叫 說明書

「讀我」是 README 的直譯,⛔ 不是中文說法。 英文版的 READ_ME 也統一成 README

🔴 規則同步工具⛔ 不會覆蓋你的檔案

v1.4.3 曾經有一個 --adopt 會替你把漂移的規則換成公版原句。⛔ 那一版沒有發布,
而那個功能已經被整個退回。

現在這一支只做兩件事:把缺少的規則附加進去、把不同的地方逐行印出來。
它永遠不會覆蓋 MY_RULES.md 裡任何一個既有的字。
⚠️ 那份逐行差異就是告訴你「要手動貼哪幾行」的東西。

🔴 升級之後想把手動改動找回來:使用持久收據

升級在覆蓋之前一定會先建立還原點。⛔ 而 v1.4.4 之前,完成訊息叫你用「查看變更」把改動找回來
——那是假的:
那個按鈕以 reviewed 為基準,⛔ 而工具建立的還原點刻意不移動 reviewed
🔴 ⇒ 你的 pre-image 確實還在,卻落在那個按鈕的視野之外。

第一版修正只印出提交編號,⛔ 仍有缺口: ignored、assume-unchanged
skip-worktree 可能讓 checkpoint commit 與即將被覆蓋的工作檔不同。
Windows 實測曾出現「checkpoint exit 0、提交內沒有手改檔、apply 仍覆蓋」;手改內容隨即消失。

現在 apply 會在替換前逐檔核對: 每個即將被同路徑覆蓋的既有非暫存檔都必須受 Git
追蹤,且依 Git 自己的 attributes/EOL 語意與 checkpoint tree 完全相符;任一項不成立就
列出路徑、exit 2、零替換。

驗證後會建立專案本地持久收據:Git 私有 ref 同時固定 checkpoint 與權威 manifest,可讀 JSON
鏡像放在 Git 自己的目錄。它能在同一個 Git 倉庫內抵抗一般垃圾回收,⛔ 但一般 git clone
或只備份工作檔案不會自動帶走這些私有 ref;它不是跨倉庫備份。

同語言、同版本且完整的 v1.4.4 套件中,使用者不需要輸入 raw Git 指令:

列出收據:      python3 scripts/harness/upgrade.py receipts
查看單檔差異:  python3 scripts/harness/upgrade.py receipt-diff <收據> <檔案路徑>
還原一個檔案:  python3 scripts/harness/upgrade.py restore <收據> <檔案路徑>

restore 一次只還原一個目前存在的一般檔案,動手前會先建立反向收據,只改 working tree,
且⛔ 不移動 reviewedapplyrestore 都先找執行中升級器同目錄、具有相符 tool API
標記的 checkpoint.py,再考慮專案內版本;兩者都不相符時零寫入,並要求重新下載完整同版套件。
讀不回或驗不過收據時,程式不會開始覆蓋或還原。

🔴 中文/英文套件不能再互相覆蓋

v1.4.2 沒有 edition 檢查;中文專案若誤放英文下載包,apply governance 會 exit 0 並把治理文件
整包換成英文。v1.4.4 先用既有三個語言專屬啟動器辨認來源與專案:Windows 可只有 .bat
macOS 可只有 .command,也可兩套都有。兩邊必須都能唯一辨認且語言相同;跨語言、混合或缺漏
都在檢查點、收據與替換之前拒絕。
🔴 ⚠️ 判定只讀這六個框架啟動器的檔名,⛔ 不看是誰放的——其他名字的
.bat.command 不參與判定,⛔ 而專案若自己建了一個與它們同名的檔案
(例如自己寫的 snapshot.bat),會被算成另一個語言版本,整次升級被擋下。

🔴 ⇒ 發布前的覆核抓到這件事,所以訊息已經改掉:它現在會逐一列出兩側實際看到的啟動器與所屬版本,
⇒ 你一眼就看得到是哪一個檔案。⇒ 規定動作:把它改名(或搬進 my/),再跑一次。

⚠️ 判定只讀下列十二個框架啟動器檔名,⛔ 不看是誰放的。實際看到的是:
  升級來源:查看變更.bat[中]、檢查更新.bat[中]、記錄快照.bat[中]……
  目前專案:查看變更.bat[中]、檢查更新.bat[中]、記錄快照.bat[中]、snapshot.bat[英]

⚠️ 缺了自己這一版的任何一個啟動器,也會被判成不完整而整次拒絕——同樣是零寫入。

The gate reads only these six framework launcher names and ⛔ not who put them there, so a
project file that happens to carry one — your own snapshot.bat, say — counts as the other
edition and blocks the whole upgrade. Pre-release review caught this, so the refusal now
lists the launchers found on each side with their edition: rename the offending file (or move
it under my/) and run again. A missing launcher from your own edition is likewise refused,
with zero writes.

🔴 同一道閘門帶來另一項行為變更:_upgrade/ 裡⛔ 不能再只放一個資料夾。
v1.4.2 以前,只把 governance/ 丟進 _upgrade/ 就能升級那一包;
v1.4.4 要在來源端也看到完整的語言啟動器,⇒ 只放單一套件會被判成不完整並 exit 1(零寫入)。
⇒ 請解壓完整套件。

One more behaviour change from the same gate: _upgrade/ can no longer hold a single package.
Dropping just governance/ in there worked before v1.4.2; v1.4.4 needs the source side to show
a complete launcher set, so a single-package source is now rejected as incomplete with exit 1
and no writes. Unpack the complete package.

⚠️ 這是 v1.4.4 的相容性修補;正式 machine-readable edition 欄位排入 v1.5.0 套件 schema。

🔴 語料庫的雜湊會在「換一台機器」時整片變紅——⛔ 而內容沒有被動過

如果你曾在 Windows 上跑過 tool_pdf_to_md.py,這一項與你有關。

提取工具寫檔時沒有固定行尾,⇒ Windows 上檔案以 CRLF 落地,
_manifest.json 記的就是 CRLF 的雜湊。⛔ 而框架的 .gitattributes 會把倉庫內正規化成 LF。

🔴 ⇒ 下一次乾淨簽出(clone 到第二台機器、git checkout、或照 SETUP.md §9 復原)
工作區變成 LF,每一個提取物的雜湊都對不上 → CORPUS_MD_MODIFIED 整片 FAIL。
⚠️ ⛔ 而你的內容一個字都沒有被動過。

v1.4.4 已修(newline="\n")。⇒ 規定動作:重跑一次提取工具
manifest 與檔案會一起變成 LF,⇒ 自洽。

If you have ever run tool_pdf_to_md.py on Windows, this affects you. The extractor did not
fix its line ending, so files landed as CRLF while .gitattributes normalises the repository
copy to LF. On the next clean checkout every recorded hash mismatches and the corpus goes red
with nothing actually changed. Fixed in v1.4.4; run the extractor once more so the
manifest and the files agree again.

感測器現在會說出它比對了幾份

主張台帳感測器一直在逐檔重算語料庫的雜湊,⛔ 而它從來沒有說過。
🔴 兩位不同的稽核者、隔了七天,各自得到「找不到哪一支感測器在做這件事」的結論——⛔ 而它一直都在。
⇒ 統計欄現在印「逐檔比對雜湊:N 份」;語料庫是空的時候印 0,⛔ 不是省略。

事故登記簿新增三個失效家族

⑨ 批次編輯成功了、⛔ 而它做的不是你要的事(🔴 讀 diff 抓不到它);
⑩ 為一個環境調好的常數,原封不動搬到另一個(🔴 兩邊逐字相同,⇒「一致」正是它的偽裝);
⑪ 兩個寫入者共用一個編號空間,而各自看來都配號成功(碰撞只在合併後出現)。
另加「索引當權威」的兩個新變體。⚠️ 三個新家族都標 [框架自身]——它們發生在維護這套框架的過程中。

其他

  • tool_sync_my_rules.py 以前會忽略 --root,可能寫到你沒有指名的那個專案,而且退出碼 0。

  • tool_my_index.py --help 以前會覆寫你的索引。 兩支現在都先驗參數再動檔案。

  • 可替換清單的數字從說明文字裡全部拿掉了。 那個數字已經漂過三次(九 → 16 → 15)。
    🔴 清單才是權威;一個複述它的數字只是第二份拷貝,而它會過期。

  • 🔴 框架自己的原始碼引用了一條不存在的規則。 anchor_norm.py 兩處寫 R-43
    ⛔ 而 RULES.md 只到 R-35;那兩句其實都是 R-27⛔ 沒有任何一支感測器在查規則 ID 引用
    (一支查檔案存不存在、一支查章節解不解析得出來),⇒ 它在每一次全綠中存活。
    ⚠️ 英文版⛔ 從來沒有這兩處引用。⇒ 補上感測器留給 v1.5.0 的保證地圖。

  • CITATION.cff 曾經連續三個版本停在 1.1.0,因為它不在 _VERSION 機制裡、也沒有感測器看它。
    已對齊為 1.4.4,並在維護側加了一道發版閘門。

  • 人工檢查點以前會在標籤建不起來時謊報成功。 專案裡只要先有一個 reviewed/<某某> 標籤,
    Git 就再也放不下 reviewed,⛔ 而程式照樣印「基準已移到最新的檢查點」並回 0。
    🔴 **現在它檢查退出碼、把標籤讀回來與...

Read more

[1.4.2] — 2026-08-28

Choose a tag to compare

@yama-learns yama-learns released this 28 Aug 15:05

[1.4.2] — 2026-08-28

🔴 The change / 這一版做的事

One defect, found by releasing v1.4.1: the file index was sorted by platform, not by name.
🔴 索引的排序取決於作業系統,⛔ 而不是檔名。

Fixed / 修正

  • 🔴 tool_my_index.py sorted Path objects. ⚠️ WindowsPath comparison casefolds
    first; PosixPath does not
    — so PROJECT.md sorts before corpus/ on Linux and after it
    on Windows.
    The index shipped with v1.4.1 was generated on Linux, so sensor_my_index.py reported
    MY_INDEX_STALE on the first run on a Windows machine.

    ⚠️ What it reported was ⛔ not "the index is stale" but "your operating system is not the
    one that generated it" — and it had already forced a manual workaround mid-release.

    🔴 A criterion that fires on a correct state teaches people to ignore it (R-19).
    The sort key is now the relative posix string. ⛔ Never the Path object.

Self-tests / 自測

78 → 79. ⚠️ The new sample is honest about its reach: it only lights up on a
case-insensitive filesystem (Windows, macOS). ⛔ On Linux the old and new code agree, so it
cannot fire there
— it is kept because the release procedure runs the self-test on Windows.

⛔ This release does not claim / 本版不宣稱

  • That every generated artefact is now reproducible across platforms. ⚠️ Only this one
    was examined. The general shape — "sorted() on a type whose ordering is platform-dependent" —
    ⛔ has not been swept for.

[1.4.1] — 2026-08-27

Choose a tag to compare

@yama-learns yama-learns released this 28 Aug 14:49

[1.4.1] — 2026-08-27

🔴 The change / 這一版做的事

Six defects where a document and the code disagreed, or where one of them was inert.
🔴 The most consequential: an upgrade deleted the rules a project had accumulated,
while PROFILE_solo.md was actively telling users to accumulate them.

🔴 升級會刪掉專案自己累積的規則,而說明書正在鼓勵使用者去累積。

Added / 新增

  • 🔴 my/ — everything in it belongs to the project and is ⛔ never touched by an upgrade:
    MY_RULES.md (project rules P-xx, with the framework's rules copied verbatim into §1),
    MY_INCIDENTS.md (moved from incidents/, now also holds the project's own failure
    families 專-①), and tools/ for scripts the project writes itself.
    ⚠️ tools/ exists because a self-written script placed in scripts/ is deleted by the
    next upgrade — observed in a live downstream project.
  • 🔴 scripts/harness/sensor_my_rules.py — checks that my/MY_RULES.md covers every
    framework rule (RULE_MISSING_IN_MY / RULE_TEXT_DRIFT / OVERRIDE_WITHOUT_REASON).
  • scripts/harness/tool_sync_my_rules.py — copies newly added framework rules in verbatim.
  • 🔴 governance_config.json now ships at the project root with the permission settings.
    ⚠️ It is on the upgrade tool's never-replace list — the settings finally live somewhere
    an upgrade cannot erase.
  • governance/CLAIM_LEDGER_SPEC.md, governance/CONJECTURE_LEDGER_SPEC.md — the ledger
    specifications, moved out of ledgers/.
  • handoffs/ now ships. ⚠️ It never did, while the whole handoff ritual pointed at it.
  • Constitution §6.4 — "a file may have exactly one owner", with the criterion for
    deciding which of the three treatments a document gets.
  • 🔴 my/MY_INDEX.md — an index of everything in the project that is yours, generated by
    scripts/harness/tool_my_index.py and watched by sensor_my_index.py; the descriptions
    live in my/MY_INDEX_notes.json and are AI-maintained.
    ⚠️ Why: a project that adopted v1.3.0 stopped maintaining its own file index — its
    file_index.md holds not one research-related entry. 🔴 file_index.md began as a
    predecessor project's table for research documents; the contents became the framework's own
    and the name did not change, so the framework displaced a mechanism that already existed.

    The criterion is "everything the framework does not own", never a list of what to
    include — a list of what to include is a whitelist (R-21).

Fixed / 修正

  • 🔴 An upgrade deleted a project's accumulated rules (governance/ is replaced
    wholesale). ⚠️ Verified by experiment, ⛔ not by reading the code.
  • 🔴 t0_docs was folded into denied in code, so no configuration could turn T0
    protection off — while the config comment said the opposite. T0 is now listed in the
    deny default instead. ✅ "Clear deny and you have full authorisation" is true for the
    first time.
  • 🔴 The permission check was skipped entirely when write_scopes was empty — and
    PROFILE_solo.md tells solo projects to leave it empty. So deny had never been in
    effect in a solo project.
    Now a solo project gets a WARN listing the files.
  • 🔴 An unrecognised key in governance_config.json was silently absorbed. Now a FAIL
    that names the closest valid key.
  • 🔴 Framework updates to the ledger specifications could never reach an existing project
    (ledgers/ is on the never-replace list). The specs moved to governance/.
  • Two dangling citations to PROFILE_multi_agent.md §4.3, a section that no longer
    exists, plus "four attack points" where there are five. ⚠️ The sensor had been reporting
    this every round and nobody read the output.
  • attribution_globs / artifact_globs pointed at outputs/ and reports/, two
    directories that never existed.
    ⚠️ They are ⛔ not being created — where research output
    lands is defined in v1.5.0. MODEL_IDENTITY.md §3.4 now states the resulting gap.

Documentation / 說明

  • 🔴 Both figures redrawn for v1.4.1, in both editions: my/ replaces incidents/,
    the ledger specs appear on the framework side, handoffs/ and governance_config.json
    are shown as shipped, and an arrow now shows what an upgrade does to your rules.
  • 🔴 The figures are now produced by a generator, ⛔ no longer hand-edited SVG.
    ⚠️ Every box width is computed from its own text, so the generator fails loudly instead of
    producing an overflowing box
    the v1.3.0 defect where one pill width was copied
    verbatim between editions and the English line was 306px wide cannot recur by construction.

    ⛔ The generator is a maintainer tool and does not ship (decision 42).
  • All three READMEs: the file list is now split into "yours" and "the framework's",
    with the reason (§6.4) stated where the reader meets it.

⚠️ Verified with Chromium getBBox(): 0 overflows and 0 overlaps across all four figures.
🔴 That measurement found two defects the eye did not: a 2px text collision present only in
the Chinese edition, and a blind spot in the measurement itself
— a band's left column could
run into the boxes beside it without being flagged, because the band rectangle was too wide to
count as "the containing box". The criterion moved into the generator.

Self-tests / 自測

57 → 78 paired samples. Both editions pass. Sensors 7 → 9.

Fixed after the principal ran it on their own machine / 主持人實跑後修正

  • 🔴 sensor_scope_and_t0.py crashed with AttributeError when git returned exit 0
    with stdout set to None. ⚠️ The code path had been there since v1.0.0 and had never
    once run
    , because the old code skipped the whole block when write_scopes was empty and
    PROFILE_solo.md tells solo projects to leave it empty. Making deny effective did not
    cause the crash; it revealed it.
    🔴 Cause, established by a diagnostic run on that machine (⛔ not guessed):
    with text=True and no encoding, Python decodes the child's output with the locale
    encoding — cp950 on Traditional-Chinese Windows — and git prints paths in UTF-8.
    The decode fails inside subprocess's reader thread, that thread dies, the exception
    never propagates, and communicate() returns None.
    The standard library turned an
    error into a silent empty value.
  • 🔴 The same fix already existed in two files in the same folder and had never been carried
    to the third
    : checkpoint.py and review_changes.py both state
    encoding="utf-8", errors="replace". ⚠️ _common._force_utf8() fixes what the harness
    prints, ⛔ not what it reads — a true fix whose scope did not cover the other channel
    (R-34). Its docstring now says what it does not cover.
  • New static self-test: any subprocess.run in the harness that decodes without naming
    an encoding is a FAIL, named as file:line.
  • 🔴 docs/ and the six launcher buttons were never on the upgrade tool's replaceable list,
    so the seven figure-layout fixes shipped in v1.3.0 reach no existing project. They are on
    the list now. ⚠️ This was caught by tool_my_index.py on its first run, because they
    appeared in the list of "things the framework does not own".
    .gitignore and .gitattributes are deliberately left off — mixed ownership, per §6.4.
  • 🔴 A project sitting in a subdirectory of a repository no longer refuses to report.
    The report is narrowed to that subtree, with paths outside it dropped. ⚠️ The framework's
    own repository has that shape, and so does any project dropped into an existing notes repo —
    the old behaviour was a light that is always on (R-19).

⛔ This release does not claim / 本版不宣稱

  • The permission model is not rebuilt. ⚠️ Seven separate mechanisms still express
    permission; ⚠️ this release fixes the ones that were false or inert. The single table is
    v1.6.0.
  • Research-side document management does not exist yet. ⚠️ research/ is v1.5.0;
    the main text still has nothing watching its author field.
  • sensor_my_rules.py does not judge the quality of a P-xx, nor whether an
    override's reason is sound — only that the line has text.

[1.4.0] — 2026-08-26

🔴 ⛔ 1.4.0 was never released on its own: it carries no git tag.
It was prepared, then folded into 1.4.1 and pushed as one release.
⚠️ This note exists because a changelog entry with no tag behind it is
"the document says it shipped" with nothing under it.

🔴 ⛔ 1.4.0 沒有單獨發布,也沒有 tag。 它備妥之後併入 1.4.1 一起推。

🔴 The change / 這一版做的事

Three start-up prompts for the multi-agent setup, a prior-art template that actually
works out of the box
, and scratch/ finally explained.
多角色情境現在有三份可以直接貼的開工指令。

Added / 新增

  • 🔴 prompts/START_governance_AI.md, START_research_AI.md, START_audit_AI.md
    (START_治理AI.md / START_研究AI.md / START_審計AI.md in the Chinese edition).
    ⚠️ PROFILE_multi_agent.md told you to set up three roles and to "put this in the
    governance role's standing instructions" — ⛔ while no such document existed anywhere.

    Each file is self-contained: model declaration, write scope, the tools that already exist,
    verification tags, the academic bottom lines, decision rights, what to do when an
    instruction conflicts with a rule, the closing packet, and how that particular role helps
    the framework grow.

    ⚠️ A solo setup does not need theseINITIALIZE_PROMPT.md still covers it.
  • A title-accuracy clause in _COMMON_BLOCKS.md block A. ⚠️ Found because an assembled
    prior-art prompt still failed the deep-research check
    — the clause was simply not in the
    parts bin.

Changed / 變更

  • 🔴 TEMPLATE_prior_art.txt now ships assembled. It used to be 24 lines, six of them
    <<<paste block X>>>, ⛔ ...
Read more

1.3.0 — 2026-08-26

Choose a tag to compare

@yama-learns yama-learns released this 26 Aug 14:53

[1.3.0] — 2026-08-26

🔴 The change / 這一版的主要變更

Short-form section citations are now checked. sensor_governance_text.py resolved only the
long `<file>.md` §N form, while the framework itself writes "constitution §N" in 68 places
(Chinese) and 58 (English)
— and its scan never reached scripts/**/*.py at all.
Three dangling citations had been living there, found by hand at v1.2.0 release time.
短式章節引用現在查得到了。

Added / 新增

  • 🔴 corpus/ and corpus_md/ now ship with the framework, each with a short note inside
    saying what belongs there. corpus/ also contains a blank BIBLIOGRAPHY.docx
    export your references from Zotero or EndNote into it, and from then on every citation in
    the project follows that file, ⛔ not what the AI says.

    ⚠️ Why: a model will get DOIs, page numbers and years wrong, and a wrong one reads
    exactly like a right one.
    A bibliography you maintain yourself is something to check against.
  • CORPUS_EMPTY (WARN) — the extraction folder exists but holds nothing yet.
    Not the same as "could not check" (see Fixed).
  • Config key section_ref_aliases{anchor word: target file}. ⛔ Not hard-coded:
    R-21 forbids a whitelist as the definition of scan scope, and a downstream project's short
    name for its constitution will not be this one's. Absent key → the check simply does not run
    for that project, ⛔ and the statistic says so.
  • ALIAS_TARGET_MISSING (INCOMPLETE) — an anchor is configured but its target file is not in
    the tree. ⛔ Not a silent skip (R-33).
  • A "section citations checked" statistic. ⛔ Silence is not a pass.
  • Four paired fixtures, ⛔ two of them the "must not false-alarm" half:
    secref_alias_bad / secref_alias_ok / secref_py (the citation lives in a .py header) /
    secref_fence. Self-tests 50 → 54.

Changed / 變更

  • The section-citation check now runs over code_globs + launcher_globs + governance_globs
    the same scope as sensor_reference_integrity. ⚠️ That sensor exists because .py headers
    were never scanned; ⛔ it fixed file references and not section references.
    The same hole was half-fixed, and the half that was fixed made it look closed.

Fixed / 修正

  • Three dangling constitution citations — already fixed in the v1.2.0 release commit;
    this version is what stops the next one.
  • 🔴 A heading inside a fenced block was counted as a heading. The first run after the scope
    widened reported HANDOFF.md as having two ## 3. sections; one was a line inside the fenced
    template. ⚠️ The defect was already in the long-form check and had simply never been
    reached. ⛔ Fixed by stripping fenced blocks, not by an exemption list (R-20/R-21).
    Stated cost: a real heading inside a fenced block becomes invisible. ⛔ Nobody writes that.
  • 🔴 "Which folders does an upgrade touch" is now a measured fact, not a sentence in a guide.
    ⚠️ The behaviour was already right — the tool recognises five framework folders and four
    framework files and refuses every other target, so a folder a user invented was never a
    candidate.
    The documentation was what read backwards: it described protection as a
    list of protected items, and a list reads as "only these are safe".
    Rewritten everywhere to state the guarantee the other way round, and
    upgrade_case() in the self-test now proves it: a folder the tool has never heard of is
    refused and left byte-identical, even when the upgrade source contains one by the same
    name.
    ⛔ The "your data" list is documented as what it is — a better error message, not
    the defence.
    Self-tests 56 → 57.
  • Constitution §6.2 gained a clause on folders the user creates, saying plainly that
    no registration is required, and naming the two mechanical reasons they are safe.
  • profiles/PROFILE_external_tools.md corrected: it said external/ was "not on the
    protected list", which ⚠️ was true and read as a warning about something that was never at
    risk.
  • 🔴 A brand-new project reported INCOMPLETE on its very first run. Shipping an empty
    corpus_md/ tripped a check that knew only two states — no directory and directory
    without a manifest
    . It had no third state for "a directory with nothing in it yet".
    ⚠️ With nothing to protect, there is no "could not protect it" — and ⛔ a first run
    that cries wolf is what teaches people to ignore the output.

    Fixed structurally, not with an exemption: the criterion now keys on whether
    extractions exist. Self-tests 54 → 56.
  • 🔴 The figures overflowed and collided — in both editions. The divider pill in
    fig1_architecture.svg carried width="260", identical in both files: the Chinese
    sentence fits, the English one is 306px wide, so the dashed line ran straight through the
    text.
    ⚠️ The same shape as the sentence-length constant in SENSOR_CHANGELOG pre-history
    #2 — a constant tuned for Chinese, ported unchanged — ⛔ this time in SVG coordinates.

    Seven overflows and collisions were found and fixed across the four figures.
    ⚠️ Found by rendering each SVG and reading every element's getBBox(), ⛔ not by eye:
    the Chinese constitution box was 1.5px inside its padding — invisible to a reader,
    and still wrong.
  • Drifting counts removed from the figures (7 sensors, 8 failure families,
    policy/ × 4, profiles/ × 4, three templates). ⚠️ All five were correct at the time.
    🔴 The README deliberately carries no counts (R-16) while the figures did — and a figure
    is read as authority more often than the README is.
    R-01R-35 is kept: that is an id
    range, ⛔ not a count. Exit codes and "three buttons" are kept: design constants.

Changed: the three guides / 三份說明文件

🔴 README.md at the root, and README.md + SETUP.md in both editions, were rewritten for
readers with no programming background.

  • git clone is gone. Getting started is now: Download ZIP → unzip → copy the folder
    for your language → rename it to your project.
    ⚠️ Anyone who prefers git clone already
    knows how, and did not need the instruction.
  • A new section on pointing your AI at the folder, with the actual steps for
    Claude (Cowork), Gemini (Antigravity) and ChatGPT (Projects).
    ⚠️ Stated plainly: a ChatGPT project has a file limit and cannot see your folder
    profiles/PROFILE_chat_only.md is written for that case.
  • The root README is now written in English throughout (the two opening lines stay in
    Chinese), because both editions are linked at the top. ⚠️ Two languages interleaved in one
    document made it harder to read in either.
  • Plainer wording, and notes written for the AI rather than the reader were removed.
    These are documents for people.
  • 🔴 A section on the framework growing with you, in all three READMEs:
    there is no perfect framework — only one that gets better as you use it.
    You say "log that" when something goes wrong; the AI finds the repeating pattern;
    ⛔ you decide whether it becomes a rule.
    After a while your copy stops looking like anyone
    else's, and that is the point.
  • profiles/ rewritten, all four, in both editions. Each now says how the framework keeps
    improving in that particular setup⚠️ including the chat-only one, where the growth
    goes into the text you paste at the start of every conversation.

    Arguments are self-contained rather than pointing at rule numbers, and the file lists match
    the v1.3.0 layout (corpus/, corpus_md/, incidents/).
  • ChatGPT is now documented as Work mode in the desktop app, which links a live local
    folder and is the equivalent of the other two. ⚠️ Web ChatGPT is described separately,
    since it holds uploaded copies with a file limit.
    Claude Code and Codex are named as working too — ⛔ without steps, because they have
    not been tested here
    , and with the warning that a coding agent will not pause for the
    snapshot habit on your behalf.

⚠️ Upgrade notes / 升級注意

  • A project that was green on v1.2.0 can go WARN on v1.3.0. That is the point.
    Set section_ref_aliases to your own short name, or leave it unset and the check does not run.
  • No rule IDs changed. R-01R-35 are unchanged.

⛔ What this release does not claim / 這一版不宣稱什麼

  • It does not claim every citation form is now checked. One anchor is configured.
    R-35: that is the result of taking stock — ⚠️ and nobody has taken stock of whether a
    third form exists.
  • It does not claim a citation points at the right content — only that the section exists
    and is unique.
  • Nothing compares the two editions. Still true, and still done by hand.
  • Nothing checks the figures. No sensor reads .svg. The layout defects above were
    reported by a human and measured with a throwaway script that is ⛔ deliberately not
    shipped
    a known and accepted gap, not an overlooked one.

1.2.0 — 2026-08-26

Choose a tag to compare

@yama-learns yama-learns released this 26 Aug 00:05

[1.2.0] — 2026-08-26

🔴 The headline changes / 這一版最重要的三件事

  1. One file to fill in. Everything a user must author now lives in PROJECT.md at the root;
    every other governance document is AI-maintained. 使用者只需要填一個檔案。
  2. Buttons, on both platforms. snapshot / review changes / check update ship as
    .bat and .command; the logic behind them lived in 8 near-duplicate files
    (four batch scripts of 203–246 lines, plus four shell scripts) and now lives in 2 Python
    files
    per edition — the six launchers are 40–43-line shells. macOS is supported for the
    first time. 兩個平台都有按鈕。
  3. Folder-level upgrades. Framework folders can be replaced wholesale from GitHub while
    PROJECT.md, ledgers, corpus, handoffs and incidents/ are never touched.
    框架可以整包升級,你的資料不會被碰。

Theme: the two editions are now actually equivalent, and the harness now fails loudly
instead of quietly passing.

主題:兩個版本這次真的對等了;檢查工具不再「靜靜地通過」,而是會出聲。

⚠️ Why this release exists / 這個版本為什麼存在

v1.0.0 shipped two editions described as "independent and equivalent". They were not.
The English edition was missing one sensor outright and three checks inside another; the two
prompt sensors were two different programs; thresholds differed between editions with the
divergence registered nowhere. A weaker sensor reads as a cleaner document — which is the
failure this release is mostly about.

v1.0.0 宣稱兩個版本「各自獨立且對等」。它們並不對等。
英文版整支少了一個感測器,另一支少了三項檢查;兩版的 prompt 感測器根本是兩支不同的程式;
門檻不一樣而且沒有登記在任何地方。一支較弱的感測器,會被讀成一份較乾淨的文件——
這一版修的主要就是這件事。

Added / 新增

  • sensor_reference_integrity.py — whether a referenced file actually exists, including
    .py / .sh file headers, which had never been scanned.
    被引用的檔案存不存在(含從未被掃過的 .py.sh 檔頭)。
  • sensor_clause_sync.py — whether a clause list copied into a prompt still matches its
    home. Exists because R-24 (prompts must be self-contained) and constitution §3.2 (one home
    per rule) exclude each other, and the product of that exclusion is silent drift.
    被抄到 prompt 裡的條款清單是否仍與定義處相同。
  • tool_extract_compare.py — strict / loose / gap columns, so "normalisation does not cover
    this" and "the extraction is poor" stop looking the same.
  • R-33 ⛔ "nothing to do" must not be the default branch after a failed operation.
  • R-34 capability boundaries are read off the tool list, ⛔ not asserted from memory.
  • R-35 "none" must be the result of taking stock, ⛔ never an omission. Raised to a rule
    because the same sentence appeared verbatim in four places across two documents, each
    with a complete context of its own — one higher-order principle instanced in four settings.
    All four sites now cite it. ⛔ Not reworded to dodge the sensor.
    「無」必須是盤點的結果——同一句話原本逐字散在四處,現在四處都引用 R-35
  • Constitution §4.1.1 — an exit-code disposition table (0 / 1 / 2).
  • Audit_Protocol.md §6 — cross-family is not independence (with verified source anchors).
  • Claim_Ledger.md §1.1 rule 5 — ⛔ an anchor must not span a page break.
  • Conjecture_Ledger.md §0.2 — an optional "why I could not fill this" field, so a
    deliberate blank stops looking like a forgotten one.
  • A new failure family: "text about a defect, and the defect itself, are indistinguishable to
    string matching"
    — with two forms running in opposite directions and taking opposite
    dispositions: mentioning it commits it (reword into description, add no exemption), and
    mentioning it is mistaken for committing it (quotation detection, ⛔ not an exemption list).
    Tagged [framework's own], a new provenance tag: it happened while maintaining this
    framework
    , not to somebody else.
  • Two cross-cutting axes named above the family table. Axis one: two states carrying very
    different information look identical on screen
    (four families sit on it). Axis two: one fact
    has two copies and only one gets updated
    . ⛔ The families on an axis are deliberately not
    merged
    — a family covering five families recognises no shape at all.
  • Constitution §6.2 defines the operational directories (scratch/, archive/,
    _to_delete/). They appeared in .gitignore, in excluded_dirs, in the constitution and in
    the audit protocol — four places using them, none defining them, the same shape "output
    area" was in before §6.1. Nothing in scratch/ may be cited: it is not version-controlled,
    so a citation into it reads exactly like a well-founded one and resolves to nothing.
  • HANDOFF.md §3.3: section 4 must carry the raw output of git diff --stat. It is the one
    part of a handoff packet that can become a mechanical fact at zero cost. What it blocks is
    not lying but under-reporting
    — a file list written from memory comes up short, and the
    missing entries look exactly like files that were never touched.
  • A root CHANGELOG.md — this file.

Changed / 變更

  • Failure families are now cited by name, never by number, across every document and
    source comment. The number is the table's ordinal; the name is the identifier.

  • The "fixed one layer, missed another" family gained two forms — the second copy living on
    a carrier that evaporates (a conversation, screen output, memory), and a number written into
    prose
    . The "index as authority" family gained a third variant: treating "this looks like a
    known family" as "this is that family" — 🔴 a failure the family table itself induces.

  • Predicted failure families moved to their own P1P6 namespace. They used to share one
    run of circled numbers with families that had actually occurred, so the next number for a new
    occurred family was ⑭ — and if a predicted family were ever removed or promoted, its number
    would fall free and be reused, silently retargeting every citation that used it.
    預測家族改用獨立的 P1P6 命名空間——兩套命名空間結構性地不可能相撞。

  • R-10 no longer cites an incident-log case. A downstream project's incident log is its
    own; inserting a case ahead of the cited one shifts the numbering while the citation still
    resolves. A citation that silently retargets is worse than one that dangles, because it
    stays green.
    The rule now carries the mechanism and the reason; the log carries the
    verbatim evidence.

  • Both editions brought into equivalence. The English edition gained
    sensor_model_attribution.py (absent entirely), three checks inside
    sensor_conjecture_ledger.py, and English text for three changelog sections that had been
    left in Chinese.

  • sensor_model_attribution.py rewritten. Hard-coded filenames 25 → 0; dangling
    references 9 → 0. The old whitelist existed only to suppress alarms a wrong scan scope
    had created.

  • sensor_prompt_self_contained.py split into two layers — self-containment always;
    the deep-research clause table only under --profile deep-research. Previously all three
    templates the framework ships came out FAIL
    , and prompts/README.md had written the
    excuse for it.

  • tool_pdf_to_md.py — PyMuPDF primary with a pypdf fallback, and the backend is
    recorded
    . Degrading is fine; degrading silently is not.

  • ai_checkpoint.sh — role + model + topic mandatory, UTC timestamps, sweeps every stale
    git lock, falls back to mv where deletion is denied, and checks git add's exit status.

  • framework_config.pyload() now takes the scanned root, so --root no longer reads
    another project's configuration in silence.

  • Self-tests: 12 → 50, over 43 paired fixtures.

  • Both T0 documents rewritten and trimmed, and one contradiction between them removed.
    The six academic bottom lines now have one home, AGENTS.md §3; RULES.md §A carries
    R-01R-04 as four one-line pointers naming the item each maps to.
    The four rows are deliberately not collapsed into the range R-01R-04: the mapping
    is not contiguous (R-03 → item 5, R-04 → item 6), and a range would state something true
    while losing which rule is which. Items 3 and 4 carry no R-xx — that is the result of
    taking stock, ⛔ not an omission, and has been so since v1.0.0.

Fixed / 修正

  • 🔴 INCOMPLETE could be swallowed by a later FAIL. Exit codes [2, 1] aggregated to 1,
    so "a sensor never managed to check" disappeared behind a fixable failure.
    一支感測器根本沒查成,會被後面一支 FAIL 蓋掉。
  • 🔴 "Must not false-alarm" tests were checking nothing. WARN-level findings do not change
    the exit code, so any number of WARN-level false alarms printed ✅.
    「不得誤報」那一半的測試,對任意多筆 WARN 級誤報一律印 ✅。
  • 🔴 A glob that matches nothing is not automatically fine. When the directory holds files
    of that extension and the glob still sees none, that is coverage collapse → INCOMPLETE.
  • 🔴 sensor_self_certification.py returned PASS on a real audit report containing six
    phrases its own protocol bans.
  • sensor_governance_text.py — a character-count threshold is systematically weaker for
    Chinese; the sentence splitter knew only and newlines, so the English edition was
    comparing whole lines only.
  • tool_pdf_to_md.py created an empty output directory before checking whether there were
    any PDFs
    — flipping a clean harness from 0 to 2, invisibly, because git does not track
    empty directories.
  • Numerous dangling file and section references across both editions, including ones the
    framework itself promised and did not ship.
  • 🔴 policy/MODEL_IDENTITY.md: the English edition was a 62-line abridgement of a 201-line
    document.
    Missing: the platform-mechanism comparison, every rule §3.1–§3.7, and the
    mechanical-defence table — including the two sections sensor_model_attribution.py names as
    its own rule source.
    ⚠️ Both editions' sensors ran green throughout: nothing in the...
Read more

v1.0.0 — first public release

Choose a tag to compare

@yama-learns yama-learns released this 12 Aug 15:17

First public release. Two independent, equivalent editions (English / 繁體中文).

What it does: makes three questions answerable at any point in a research project —
which page a sentence rests on, what would refute an idea, and what the AI just changed.

What it does not do: it does not guarantee your research is correct. It guarantees
that when it is wrong, the error leaves a trace.

  • 5 sensors, 12 paired seeded-defect self-tests, cross-platform Python runners
  • 32 permanent-ID working rules; 7 failure families
  • 4 usage profiles: solo / multi-agent / chat-only / external tools

Distilled from two research projects in actual use.
Every sensor and hard rule carries the case that triggered it.