1.2.0 — 2026-08-26
[1.2.0] — 2026-08-26
🔴 The headline changes / 這一版最重要的三件事
- One file to fill in. Everything a user must author now lives in
PROJECT.mdat the root;
every other governance document is AI-maintained. 使用者只需要填一個檔案。 - Buttons, on both platforms.
snapshot/review changes/check updateship as
.batand.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. 兩個平台都有按鈕。 - Folder-level upgrades. Framework folders can be replaced wholesale from GitHub while
PROJECT.md, ledgers, corpus, handoffs andincidents/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/.shfile 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 becauseR-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-34capability 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, inexcluded_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 inscratch/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 ofgit 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
P1–P6namespace. 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.
預測家族改用獨立的P1~P6命名空間——兩套命名空間結構性地不可能相撞。 -
R-10no 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.pyrewritten. 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.pysplit 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, andprompts/README.mdhad 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 tomvwhere deletion is denied, and checksgit add's exit status. -
framework_config.py—load()now takes the scanned root, so--rootno 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-01–R-04as four one-line pointers naming the item each maps to.
⛔ The four rows are deliberately not collapsed into the rangeR-01–R-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 noR-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 to1,
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.pyreturned 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.pycreated 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 sectionssensor_model_attribution.pynames as
its own rule source.⚠️ Both editions' sensors ran green throughout: nothing in the
framework compares the two editions, and a reference sensor can only say "the file you cited
exists", ⛔ never "this edition is missing three sections". The editions are now equivalent
section for section. - Chinese edition, same file: two different sections were both numbered
3.6— and the
sensor's citation pointed at the second one;§3.7sat after§4and§5; the tier line
still used a superseded scheme. Merged, reordered, and renumbered to3.6.1–3.6.3
⛔ without changing the number anything cites. - Three dangling constitution citations (
§5.11in both editions'sensor_model_attribution.py,
§8.1in both editions'Audit_Protocol.md,§5.8in the ChineseMODEL_IDENTITY.md).
🔴 The§5.11one was a defect description that instantiated the defect it described —
two lines above it, the same comment explains why the filenames were deliberately not
written out. SENSOR_CHANGELOG.mdcarried two#nseries in one namespace (undated pre-history and
dated maintenance), so#1meant two different things. ⛔ Not renumbered — the file is
append-only. Divider headings and a citation rule were added instead: cite a maintenance
entry with its date.
Removed / 移除
enable_reference_authenticityandenable_bat_checksconfig keys — ⛔ nothing in the
project ever read them. A switch that looks like it turns something on, and does not.
⛔ 全專案沒有任何程式讀過它們——看起來有一個功能可以打開,其實打開了不會發生任何事。
⚠️ Upgrade notes / 升級注意
- If you carry a
governance_config.json, dropenable_reference_authenticityand
enable_bat_checks; addsynced_lists/sync_scan_globsif you want the new clause-sync
sensor to do anything. Absent keys fall back to the defaults. - Exit code 2 now happens where it used to be 0. That is deliberate: incomplete is not a
pass. Constitution §4.1.1 says what to do with it. - ⛔ Rule IDs are permanent and append-only.
R-01–R-32are unchanged; nothing was
renumbered.
⛔ What this release does not claim / 這一版不宣稱什麼
- Links ⑥ and ⑦ of the evidence chain — does the passage support the claim, and may you
generalise — remain deliberately unmechanised. Green covers only what is mechanised. - Cross-model adversarial audit is still untested by anything other than a human.
- ⛔ Short-form section citations are not mechanised. The sensor resolves the
`file.md` §Nform; the shorter "constitution §N" form used in 68 places (Chinese) and
58 (English) is checked by nobody. The three dangling citations fixed in this release were
found by hand, ⛔ not by a sensor. Until that is mechanised, "green" does not cover them. - ⛔ Nothing compares the two editions. The equivalence stated above was established by a
one-off comparison of heading structure, section numbers and language-neutral code tokens —
⚠️ not of meaning, and ⛔ not by anything that will run again. ⚠️ One true positive is known and open: a duplicated sentence between
Incident_Log.mdandRULES.md, where the right fix depends on an unresolved question —
whether a rule may cite an incident-log case number at all, given that each downstream
project's incident log is its own and does not inherit. A citation that silently retargets
is worse than one that dangles, because it stays green.
It is reported as WARN rather than hidden. A known open finding is not a bug fixed.