Skip to content

三個名字分類的判定面都不留 judgement——authorize-names/add_variant/authorize 一次裁;#553 合併端能否把 authorized 升成拒絕條件繫於此 #564

Open

Description

@kiki830621

Problem

三個「名字分類」的判定寫入面都不留 judgement:

面 寫的是什麼判定 留記錄?
person authorize-names --apply(#81) 「這個名字是此人的對外形」 ✗(Commands.swift 只有 --apply,無 judgement)
venue update-venue --add-variant(#471) 「這個名字是本刊的異寫」 ✗
venue update-venue --authorize(#554) 「這個名字是本刊的對外形」 ✗

同一個 updateVenue 裡的 paginated(#406)卻要 judgement+rests-on、寫一筆 ProvenanceReference。two-kinds-of-edits 對 AI 編輯欄的義務是「留 verdict/judgement,必附理由,可回溯、可逆轉」——三個面都是 AI 編輯(判定型),三個都沒做到這一格。

Type

feature

Expected

一次裁三面,不在各張 issue 各說各話:

  1. 留不留。若裁「不留」,two-kinds-of-edits 三列各註明「不留 judgement 是有記錄的裁決」(venue 的 authorized 只有 bootstrap 寫得到——479/479 筆是 [names[0]],而合併會單向降級它 #554 R2 已先對 authorize 那列這樣寫,等本張改)。
  2. 留什麼形狀。store 驗證層已收 venue.references(field: authorized, value: X) 與 field: names(Provenance.swift),但空 rests-on 的 judgement 走不進——authorized 不在 firstOrderRulingFields(只有 resolution verdict 欄位對+authors)。要裁:authorized/variant 進不進 firstOrderRulingFields(一階裁決、允許空 rests-on),還是同 paginated 要求證據 digest。
  3. 確認既有值也要留。venue 的 authorized 只有 bootstrap 寫得到——479/479 筆是 [names[0]],而合併會單向降級它 #554 verify DA 席實測:對既有 authorized 呼叫 --authorize 同名 → 報告空、檔案 byte-level 無 diff。470/470 筆 authorized 都是 bootstrap 的 [names[0]],一輪查證對它們最可能的結論就是「bootstrap 選對了」——而那個結論今天零寫入零記錄。

Actual

後果在 #553 的合併端:authorizedDemotedByMerging 對被併者的 authorized 只提醒不擋,理由是「今天不承載判定」。#554 之後面有了,但因為不留記錄,合併端仍然分不出「人確認過的 names[0]」與「機械 names[0]」——issue 自提的量測 authorized != [names[0]] 對「已確認」永遠回 0。

#554 R2 把 DivergenceResolve.swift 那格的重開觸發條件改成綁本張:本張裁「留」且落地後,合併端對「有 judgement 的 authorized」升成拒絕條件、對機械值維持提醒。

Impact


Source: surfaced during /idd-verify #554 follow-up triage (Step 5b) — 第 4 列+第 2 列的裁決重開,使用者 2026-09-12 拍板「開 follow-up 一次裁三面」;verify report:#554 (comment)

Current Status

Phase: verified(b42 verify R7:HIGH 0、MEDIUM 0;### Blocking 的使用者裁決待處理)
Last updated: 2026-10-20 by idd-update

Blocking

  • 使用者裁決:附了 --judgement 而沒有名字進出 authorized 時整批拒絕(比 2026-10-05 裁決 2、3 嚴),維持拒絕,還是改成放行並回報「理由沒有寫進任何記錄」?(裁決後維持現狀,或改 update-person 的拒絕與 CLI/MCP 說明)
  • 使用者裁決:issue Expected 3(確認既有的值留記錄)對 person 不再成立,要另給 person 一個確認面,還是把 Expected 3 對 person 標成不適用?(裁決後開實作,或改 issue 的 Expected)
  • 使用者裁決:報告的 attested 截在 20 個、以最後一項文字說出省略數、讀取面全列,維持,還是另加回應鍵、或讀取面也截?(裁決後改 nameSegmentFieldsDict 與 MCP 說明,或維持)
  • 使用者裁決:akashic-verify-person、akashic-promote-literals 叫 agent 整份讀回 names 再寫、沒提醒要保留 authorized,要不要補一行提醒?(裁決後改兩支 skill 文字,或維持)
  • 使用者確認(b39 的讀法):合併只在「被併者自己不一致」時拒絕,而倖存者已有同一個矛盾時不擋——「同一個矛盾」我讀成同(分割, 名字)而且同方向;「會不會把記錄搬進倖存者」以(分割, 名字)為單位算,所以被併者會搬這個名字的某幾筆、而它不一致的最後一筆因倖存者已有而不搬時,照樣拒絕。b40 的 devil's advocate 實測:載入時就會隔離錨不到 names 的記錄,而方向等於成員資格,所以「同方向」這一條在任何載入得了的 store 上都不改變結果,要確認的實際上只剩第二個讀法。這兩個讀法對嗎?(對就維持;不對就改 heldTailContradictions 與 doomedTailConflicts)
  • 使用者裁決(b40):兩筆攣生都持有同一個矛盾(例如名字仍在 authorized、最後一筆是撤回)時,合併照裁決放行,但仍會重搬被併者較早的記錄,倖存者的最後一筆因此被翻成「指定」。要改成被豁免的(分割, 名字)不重搬(行為改動),還是維持並把文件寫成實情?(b41 先把文件與測試寫成實情;裁決後才動行為)
  • 使用者裁決(b40):organization remove_names 的 MCP 報告在名字層級省略時新增 detailsTruncated/detailsListed 兩個回應鍵(沿用 venue 家族既有的鍵)。這在 2026-10-05「不新增回應鍵」的範圍之外嗎?(在範圍外就維持;在範圍內就改成不新增鍵的揭露方式)
  • 使用者裁決(b40 INFO 22):在攣生豁免的範圍內,合併後倖存者的最後一筆由被併者 key 的字典序決定——同樣的歷史換個 key 拼法,倖存者原有的矛盾可能被保留,也可能被「修好」(是否拒絕不受 key 影響)。要維持(並把文件寫成實情),還是改成與 key 無關的結果?(裁決後動合併的搬運順序,或維持)
  • 使用者裁決(b42):帶時間的名字、variant 欄矛盾時,合併拒絕訊息說「工具面沒有出口、只能手改」。名字只有一段時其實有一條工具路徑(先用 --edit-name-segment 清掉時間、走三步、再補回時間),多段同名沿革時才走不通。要把訊息收窄成「沒有直接的工具出口」並寫出那條路徑,還是維持只建議手改?(裁決後改 tailConflictExits 的訊息、store-format §3.5 與 spec delta,或維持)

Commits

Activity

  1. kiki830621 commented on Sep 30, 2026

    @kiki830621
    MemberAuthor

    Decision(2026-10-01,使用者)

    留,含「確認既有值」

    裁決:名字分類的判定面一律留 judgement 記錄。涵蓋五個面:person authorize-names、venue --add-variant、venue --authorize,以及同日裁決新增的 org --authorize(#557)與 venue --unauthorize(#559)。

    代價(使用者看過):需要升 store format,舊 binary 讀不到這種記錄。

    Phase:待實作。排在 #557/#559/#563 落地之後。

  2. kiki830621 commented on Oct 2, 2026

    @kiki830621
    MemberAuthor

    Decision(2026-10-02,使用者):R1 verify 提出的四件

    R1 verify(b26 F1/F2,2026-10-01)發現四件不屬於程式錯誤、要裁決的事。使用者四件都選建議方案:

    # 問題 裁決
    1 update-person 的 fields.names 整組替換時,可以改 authorized/variant,不附理由、不留記錄 names 那條腿只要動到 authorized/variant 就要 --judgement(MCP judgement),並比照 venue 寫指定/撤回記錄。person 從此有單筆的名字分類面
    2 記錄綁在名字上而且刪不掉:用 --authorize 時打錯字的名字(或 authorize-names 採用的錯拼法)沒有工具能修 名字最後一筆記錄是「撤回」時,名字可以連同它的記錄一起刪。比照移除面一族的裁決:理由必填、只進報告,檔案要先 commit 乾淨,歷史留在 git
    3 兩筆 person 攣生各跑過一次 authorize-names(理由不同)後,合併被拒,也沒有工具能把記錄帶過去 分類一致時,被併者的名字分類記錄逐位元組帶到倖存者,比照 venue 合併的 venueReferenceCarry
    4 一次 --add-variant 帶上千個名字,會把同一句理由複製成上千筆記錄(實測 1,500 筆撐到 6 MB),沒有工具能移除 名字分類的寫入面每次呼叫至多 200 個名字,比照其他寫入腿的一次上限;超過就整批拒絕、零寫入

    這四件與同輪的程式錯誤(撤回後用同一句理由再指定時記錄被去重丟掉、合併時位元組去重早於分類檢查、開頭是組合字元的理由)一起在修正輪處理。

  3. 7 remaining items

  4. kiki830621 commented on Oct 4, 2026

    @kiki830621
    MemberAuthor

    Decision(2026-10-05,使用者):b33 verify 之後的五件

    # 問題 裁決
    1 person 用 fields.names 整份替換,把沒有分類記錄的對外名稱移出(例如改正拼錯的對外名稱) 要 store format ≥ 22,並替被移出的名字寫一筆「撤回:理由」。理由入庫、可追溯,與有記錄的名字同一套規則;format < 22 時與其他分類寫入一樣被閘擋下
    2 附了理由的整份替換,仍留在 authorized 的其他名字要不要寫「確認」 只替有變動的名字寫記錄:進入 authorized 的寫「指定」、離開的寫「撤回」,留下沒動的不寫
    3 只動 variant、不動 authorized 的替換要不要理由 不必理由(person 的 variant 沒有分類記錄可寫)
    4 update-person/update-organization 的 --remove-name 要不要過目標 store 確認閘 過閘(會刪判定記錄的面一律過閘)
    5 organization 的 remove_names 要不要保留 保留

    另:合法的「指定 → 撤回 → 指定」歷史被 #582 的重複 reference 掃描誤報(b33 X1),屬程式缺陷,下一輪修正處理。

  5. kiki830621 commented on Oct 4, 2026

    @kiki830621
    MemberAuthor

    Verify R1–R3(2026-10-01~10-04):R3 HIGH 0、MEDIUM 14,進修正輪

    三輪都是六席交叉驗證(四個 Claude lens、devil's advocate、Codex 跨模型)。R1 由同一棵樹上的兩批驗證組成,其中一批只有一則 #564 的 LOW。表中是 findings 的原始筆數(INFO 不列),標題沒有 issue 編號的 finding 依內容歸屬(R2 的兩則 MEDIUM 與九則 LOW、R3 的兩則 LOW 屬這一類);下面把同一件事被多席提出的合併成一條,括號是席數。

    輪 HIGH MEDIUM LOW 之後的修正
    R1 0 12 20 c979c4f1、69ac4ea6
    R2 0 7 16 4f301e3d、e1ac28b5
    R3 0 14 14 —

    R1 的 MEDIUM

    使用者 2026-10-02 對其中四件事選了建議方案(#564 的 Decision 留言),修正輪與 R1 的程式錯誤一起落地。

    • update-person 的 fields.names 全量替換能不附理由、不留記錄地改 authorized,是第六個名字分類面(codex、requirements、logic、devil's advocate 列為 MEDIUM,security 在 LOW,共 5 席;requirements 席用真 binary 重現:authorize-names 之後替換把名字從 authorized 移到 variant,rc=0、零記錄,先前那筆「指定」留著過期)。devil's advocate 校正:三個名字分類的判定面都不留 judgement——authorize-names/add_variant/authorize 一次裁;#553 合併端能否把 authorized 升成拒絕條件繫於此 #564 的 Decision 只列五個面,不算需求沒覆蓋,降為文件問題,但 mcp-cli-parity 那句「person 的單筆名字分類面不存在」為假——裁決:替換讓名字進或出 authorized 時 --judgement 必填,比照 venue 寫指定、確認、撤回;替換拿掉有記錄的名字、或讓對外形整個離開 names,具名拒絕並指出口;mcp-cli-parity 那句劃掉(c979c4f1)。
    • 名字有記錄之後沒有任何工具能改它:venue 用 --authorize 打錯字的名字、person 在 authorize-names 之後要改的拼法,記錄錨定 names 而且刪不掉,拒絕訊息沒給出口(logic、regression、devil's advocate,3 席;devil's advocate 校正:venue 側的訊息有給出口,只有 person 側沒有)——裁決:最後一筆記錄是「撤回」的名字連同記錄一起刪,venue 擴充 --edit-name-segment 的 remove,organization 與 person 各多一條 --remove-name '<名字>=<理由>'(MCP remove_names),理由必填、只進報告,檔案要先 commit 乾淨;最後一筆不是撤回的拒絕,出口是先撤回再刪(c979c4f1)。
    • 兩筆 person 攣生各跑過一次 authorize-names(理由不同)之後合併被拒,而訊息建議的「先把記錄搬到倖存者」沒有任何工具做得到(regression、devil's advocate,2 席,真 binary 重現)——裁決:分類一致時被併者的名字分類記錄逐位元組搬到倖存者(personReferenceCarry,比照 venue 的 venueReferenceCarry),preview 與實跑同一份 referencesCarried,不一致時拒絕並指出口(c979c4f1)。
    • 追加式去重比的是整份歷史:「指定 R → 撤回 S → 再以 R 指定」的第三筆與第一筆相同而被丟掉,回報 judgementsRecorded: 0,記錄以撤回結尾而名字已是 authorized(logic 席,真 binary 重現;同一個缺陷在 organization 的 authorized 零寫入面——13 筆全空,doctor 報得出來卻修不了 #557、venue 的 authorized 只能替換不能撤回——回不到誠實的未判定狀態(#500 clear_paginated/#418 demote 的同一格) #559 的 R2 另有三席提)——改成只比同一個名字、同一個分割的最後一筆(c979c4f1)。
    • venueReferenceCarry 的位元組早退排在分類一致性檢查之前:兩邊各持一筆位元組相同的「variant 指定:R」,倖存者之後把名字抬進 authorized 又撤回,被併者的 variant 分類被合併安靜地拿掉(codex 席)——分類檢查移到前面,preview 與實跑都拒絕(c979c4f1)。
    • 理由以 Grapheme_Extend 字元(U+0301、ZWNJ、CGJ)開頭時,String.hasPrefix 在 Character 上比、與全形冒號併成同一個字,前綴比不上;帶 --rests-on 時寫成一筆一般 reference,--remove-reference 刪得掉、合併端看不見,回報卻說寫了記錄(security 席,真 binary 重現;devil's advocate 校正:只有帶 --rests-on 時才安靜變成一般 reference)——parse 改在 scalar 上比,入口另以 NameClassificationRecord.reasonIssue 拒收開頭是組合符號、格式或不可見字元、或沒有任何字母數字的理由(c979c4f1)。
    • 一次呼叫可以寫上千筆 4 KB 的記錄,而沒有工具能移除(security 席,實測:--add-variant 帶 1,500 個名字,理由 4,000 字元,回 judgementsRecorded: 1500,venue 檔 6,167,788 位元組)——名字分類的寫入面一次至多 200 個名字(venue 三條腿合計、organization authorize、person fields.names 兩個分割合計、remove_names),超過整批拒絕、零寫入(c979c4f1)。
    • 為了舊預算縮短的 MCP 說明,在預算調到 60,000 之後仍沒補回,被刪掉的拒絕類別,CLI help 也沒有逐項帶(regression 席列為 MEDIUM;requirements、logic、security、devil's advocate 在 LOW 提同一件事,共 5 席)——寫回 resolve-people/resolve-venues/resolve-organizations 的 undecided、drop_venue(4,096 位元組、一次 200 條)、repoint、update_venue 的 unauthorize、remove_reference,CLI help 補上同樣缺的;真 binary 量 tools/list 一行 57,213 位元組,預算 60,000(c979c4f1、69ac4ea6)。

    R1 的 LOW 另處理:authorize-names --apply 沒寫任何名字時不再印「已寫入」、resolve-divergence --dry-run 印出 referencesCarried、update-venue 報告多 variantConfirmed、名字分類附著檢查的名字集合在迴圈外建一次、#600 的 authorize campaign 的殘句改成按需判定。

    R2 的 MEDIUM

    • 合併搬名字分類記錄仍以倖存者整份歷史的位元組集合去重(codex、logic,2 席列為 MEDIUM;devil's advocate 席的同一則標題沒有編號,不計入表):被併者「指定 R → 撤回 S → 指定 R」併進已有「指定 R」的倖存者,兩筆「指定 R」都被丟、只搬「撤回 S」,倖存者的名字仍是對外形,最後一筆卻是撤回;修正輪自己寫「只可能是手改」的狀態由工具造出,之後刪名字閘與寫入面的去重按位置讀,會得出與分類相反的結論(devil's advocate:K 與 D 都已撤回、合併後 K 以「指定」結尾而名字在 variant,--remove-name 叫人「把它從 authorized 移到 variant」,做不到)——被併者的記錄按它自己的順序逐筆接到倖存者後面,每一筆只與那個名字那個分割此刻的最後一筆比位元組(新的 NameClassificationRecord.appendCollecting,與寫入面同一個規則);合併後倖存者上若有名字的最後一筆與它的分類矛盾,而那是這次合併帶進來的,preview 與實跑都拒絕(wouldContradictClassificationTail);刪名字閘的出口改成「先把它指定回去再撤回」;規則寫進 docs/store-format.md §3.5 與 Spectra change(4f301e3d)。
    • venue 的 variant 名字被拒時,訊息說「只能手改 YAML」,其實工具面有一條路(requirements 席列為 MEDIUM;logic、regression、devil's advocate 在 LOW 提同一件事,共 4 席;真 binary 實測刪掉名字與 4 筆記錄)——訊息、CLI help 與 docs/store-format.md 改成那條路與它的代價(--authorize 抬出 variant、--unauthorize,兩次附理由、commit、再 remove;同書寫系統原本的對外形會被換下),akashic-verify-venue 補一段「標錯異寫沒有單獨的撤回腿」(e1ac28b5)。
    • person 合併的乾跑說可以、實跑被拒(security 席,標題沒有編號、不計入表;logic 在 LOW 提同一件事):personReferenceCarry 不查記錄的名字在不在合併後的 names,被併者的「Foo Bar」(雙空白)遇到倖存者的「Foo Bar」不會併入,記錄卻被搬,實跑在寫入閘以「value 不是這筆記錄的名字」失敗——記錄的名字要在合併後倖存者的 names 裡,否則歸 lost,由 fieldsLostByMerging 在 preview 與實跑同時以 wouldLoseFields 拒絕;分類的相等改看 canonical(4f301e3d)。
    • person 一次整份替換就能改正對外形拼寫的既有用法,修正輪之後被拒,變成三步:移到 variant 寫撤回、commit、--remove-name(regression 席)——離開 authorized 也離開 names、沒有任何名字分類記錄的名字放行,理由照樣必填、寫在進入的名字上,離開的名字列在回應的 authorizedRemovedWithoutRecord;有記錄的名字被整份替換拿掉仍拒絕(e1ac28b5)。
    • store format 低於 22(live store 是 18)時 person 的 authorized 完全改不了,沒附理由的拒絕只說「judgement 必填」,照做之後才吃到第二次拒絕(regression 席)——第一則拒絕另說這個 store 是 format N、附了理由仍會被寫入閘擋下,以及升級路徑;行為不放寬(e1ac28b5)。

    R2 的 LOW 另有十六條,主要的處置:「同一句理由連送兩次是 no-op」的說明改成實話(指定之後的第一次重送寫一筆確認)、理由開頭的檢查改以性質判(Emoji_Modifier 與 SpacingMark 的 Lo 也拒收)、刪名字的記錄刪除改成線性、person 的 remove_names 不刪到零個名字、organization 的 remove_names 報告多 segments、合併預覽印出每筆記錄的 statement。未改、交給使用者的:只動 variant 的 person 名字替換不必附理由的讀法、附理由的替換對仍在 authorized 的每個名字寫確認、--remove-name 要不要過目標 store 確認閘、organization 刪名字面的範圍。

    R3 的 MEDIUM

    • person 無記錄的對外形一步刪除(fields.names 把沒有記錄的 authorized 名字整個拿掉,R2 新放行的路徑)有三個缺口(codex、requirements ×2、logic、regression、devil's advocate,共六則,5 席):理由沒有存進 store 也沒有回報——沒有名字進入或留下時 judgementsRecorded: 0,authorizedRemovedWithoutRecord 只列名字,理由連「只進報告」那一層都沒有;另有名字留下時,理由被寫成對不相干名字的「確認」(例:刪「Latin Name」的理由寫在王小明的確認記錄上);這條路不經 format 22 的寫入閘,也不要求 person 檔已 commit,與 changelog 的「format < 22 行為不放寬」相反(真 binary,format 18 的 store 上成功,doctor 隨後印 no authorized name: 1 person,要回復 authorized 又被閘擋下);fields.names {"authorized":[],"variant":[]} 還能把 person 清到沒有名字。live store 的 4,571 個 person 的 authorized 全是無記錄的,所以這條新放行的路徑就是 fields.names 對現有資料唯一生效的行為。建議的方向:把理由回進 authorizedRemovedWithoutRecord(每項 {name, reason})、要求檔案已 commit 乾淨(同 remove_names)、更正 changelog 與 design 的說法。
    • 合併搬記錄只比最後一筆,兩筆攣生各有相同的多筆歷史時合併後歷史翻倍(logic、regression,2 席,真 binary 重現):兩個 person 各有 [指定 R、確認 S],D 的「指定 R」與 K 的最後一筆「確認 S」不同而被接上,D 的「確認 S」又與新的最後一筆不同,結果 K 有四筆,validate 印兩則「重複的 reference」,而且沒有工具面可處理;regression 另量到:兩邊都走過同一個批次流程的一般攣生,修正輪之前搬 0 筆,現在搬 2 筆、resolve-divergence 回報「2 筆」。三路攣生翻倍兩次。建議:被併者某個名字的整段歷史已是倖存者歷史的相同尾段時跳過。
    • validate 的重複 reference 掃描(非 verdict reference 的位元組變體重複(paginated/identifier retrieval 只差 NFC/NFD)沒有任何掃描面 #582)把合法的追加式分類歷史當重複,處置「留一筆」會弄壞尾端(logic、regression,2 席,真 binary 重現):「指定 R → 撤回 S → 指定 R」是 §3.5 與新 spec 定義的合法歷史,掃描報「同一個動作做了兩次」,處置寫「確認說的是同一件事後留一筆(目前沒有工具面,手改 YAML)」;刪掉第三筆,尾端回到撤回而名字仍 authorized,正是 wouldContradictClassificationTail 拒絕合併、nameRemovalRefusal 稱為不一致的狀態。R2 的合併修正自己產出的正確結果也會觸發這個永久 warning;doctor、MCP 的 duplicateReferences 計數與 App 側欄計數都因此非零,零實例表第 35 列寫「應恆為 0」。建議:掃描略過名字分類記錄,或改成位置感知、只報相鄰位元組相同的記錄。
    • person 的出口「先放進 authorized、再移回 variant」在同書寫系統已有 authorized 名字時走不通(logic 席,真 binary 重現:兩個 authorized 並存被擋「在書寫系統 latn 有 2 個 authorized」)。devil's advocate 校正:用交換做得到(authorized 與 variant 對調、附理由,再對調回來,合併與 --remove-name 都通過),所以不是做不到,而是出口句沒說要交換、交換會讓另一個對外形多一對撤回與指定;同一個出口句也寫在 remove-name 的拒絕裡,同樣不完整。venue 的訊息有寫這個代價,person 的沒有。
    • 合併拒絕訊息對 variant 欄位的尾端矛盾給的出口不解決它(logic 席,真 binary 重現:照訊息做完,同一則拒絕逐字回來,且多兩筆記錄)。devil's advocate 校正:只有「名字不在 variant、field: variant 最後一筆是指定或確認」這一半無效,因為 --authorize 對不在 variant 的名字只寫 authorized 欄位的記錄;正確的出口是先 --add-variant、再 --authorize、再 --unauthorize。validate 對這兩種狀態都全綠,沒有掃描面能先看到。
    • 合併的尾端矛盾檢查把每一筆被併者的中間狀態當基準,而不是原本的倖存者(codex 席,靜態審查):三筆 person 都有名字 X,倖存者 K 的最後一筆本來就是撤回、已有矛盾;被併者 A 以指定結尾而暫時消掉它,B 以撤回結尾而把它還原,B 的 before 看不到這個矛盾,合併被拒;B 先於 A 處理則通過,結果取決於順序。建議:先記下原本倖存者的矛盾集合,搬完全部再比差集。
    • 合併搬記錄的 appendCollecting 是 O(搬的筆數 × 全部 references)(security 席,真 binary 量測):每筆都倒著掃整份 references 並做 parse 與 canonical,兩個 person 各有 N 個互異名字、每個名字一筆撤回時,N=500 用 1.71 秒、1,000 用 5.72 秒、2,000 用 23.4 秒、4,000 用 89 秒(debug build,平方成長;同一個名字交替 8,001 筆只要 2.0 秒);dry-run 經 preflight 與 preview 各算一次,實跑再算。update_person 的名字替換每次可寫 200 筆記錄,所以不只手改 store 才有。這一處是修正輪新引入的退步(先前整份歷史的位元組集合是 O(R))。建議:一次建好「名字加分割 → 最後一筆」的索引,每接一筆更新。

    進下一輪修正(2026-10-05 開始)。

    逐則處置見 changelog:changelog/2026-10-02-name-classification-correction.md、changelog/2026-10-04-b30-h1-fixes-564.md。

  6. kiki830621 commented on Oct 5, 2026

    @kiki830621
    MemberAuthor

    Decision(2026-10-05,使用者):b34 修正輪留下的三項

    # 問題 裁決
    1 裁決 1「替被移出的名字寫撤回」實作成「對外形整個離開 names 一律拒絕,出口是留在 variant 並附 --judgement 寫撤回」,程式不自動替人留在 variant 對,維持現狀
    2 organization remove_names 回應的 segments 少列時分不出空段或截斷,要不要加區分的回應鍵 不加(零實例;tools/list 預算只剩約 1KB)
    3 update-venue --edit-name-segment 一條腿兩種動作,裁決表只能記一格(實際只閘 remove) 維持一條腿,裁決表那一格註明只閘 remove,由真 binary 測試釘住
  7. kiki830621 commented on Oct 9, 2026

    @kiki830621
    MemberAuthor

    Verify R4(2026-10-05):HIGH 0、MEDIUM 4,進修正輪

    R4 是六席交叉驗證(四個 Claude lens、devil's advocate、Codex 跨模型),驗的是 R3 的修正 9af49326(03b9e10b 只改零實例表的列號)。表中是 findings 的原始筆數(INFO 不列),標題沒有 issue 編號的 finding 依內容歸屬(兩則 MEDIUM、七則 LOW 屬這一類);下面把同一件事被多席提出的合併成一條,括號是席數。

    輪 HIGH MEDIUM LOW 之後的修正
    R4 0 4 12 —

    R3 的 MEDIUM 怎麼修的

    R3 的 14 條 MEDIUM 與使用者 2026-10-05 的五點裁決(#564 的 Decision 留言)一起處理。

    • person 用 fields.names 整份替換:對外形不得整個離開 names,有沒有記錄都一樣;移出 authorized 的名字要留在 variant 並附 --judgement 寫一筆「撤回」。只替進出 authorized 的名字寫記錄,留下沒動的不寫確認,替換不會把 person 刪到沒有名字。這是裁決 1、2、3,authorizedRemovedWithoutRecord 隨之退場。
    • 合併搬名字分類記錄:被併者依 key 排序,以原始倖存者為基準、全部接完才算一次尾端矛盾的差集;倖存者歷史裡已有相同記錄而尾端一致時不重搬;索引一次建好、逐筆更新,改成線性。
    • 非 verdict reference 的位元組變體重複(paginated/identifier retrieval 只差 NFC/NFD)沒有任何掃描面 #582 的重複 reference 掃描:名字分類記錄另算,只報同一個名字同一個分割裡相鄰而相等的,合法的「指定 → 撤回 → 指定」不再誤報。
    • 刪名字與合併的拒絕訊息說出「與同書寫系統的對外形交換」和它的代價,variant 欄位的矛盾另給出口。
    • 裁決 4:update-person、update-organization 的 --remove-name,update-venue 的 --remove-issn、--remove-reference、--edit-name-segment(帶 remove)一律過目標 store 確認閘,update-venue 改成逐腿裁決;MCP 面照既有政策不閘。裁決 5 保留 organization 的 remove_names,沒有動。

    使用者 2026-10-05 第二批裁決對修正輪留下的三項:維持「對外形整個離開一律拒絕」、organization remove_names 少列 segments 時不加回應鍵、--edit-name-segment 維持一條腿並在裁決表註明只閘 remove。三項都不改程式,文件還沒跟上(見 LOW)。

    R4 的 MEDIUM

    • organization 的 remove_names 回應仍受 store 內容控制、沒有上限(codex、logic,2 席列為 MEDIUM;devil's advocate 在 LOW 校正為偏高)。b34 只把 segments 截在 20 段(segmentsListedCap),共用的 nameSegmentFieldsDict 對每段的 attested 仍整列迴送;logic 席用真 binary 造一個名字、一段、20,000 個 attested,update-organization --remove-name 單次輸出 460,506 位元組,devil's advocate 造 60,000 個得 1,380,503 位元組。零實例表第 96 列自己寫「段數與每段的 attested 項數都不封頂」,修了一半;MCP 面沒有位元組預算,直接進 LLM context。devil's advocate 的校正:live store 的 organization 與 venue 名字段 attested 最大為 0,要手造;那個函式是 venue 的 edit_name_segment 與讀取面共用、不是 b34 引入;使用者 2026-10-05 第二批裁決「不加回應鍵」只涵蓋 segments 少列。
    • update-person --fields(names 加 judgement)對重複 person key 不查「無法唯一定位」(security 席,1 席;devil's advocate 在 LOW 校正為偏高)。真 binary 手造兩筆 key 同為 dup 的 person,validate 報 error,--remove-name 整批拒絕,但 --fields 的 names 替換附 --judgement 成功、judgementsRecorded: 1,指定記錄落在載入順序任選的那一檔。devil's advocate 校正:--fields {"note":"x"} 同樣寫進任選的檔,是 updatePerson 的 fields 路徑整體缺這項檢查,不是名字分類專屬、b34 沒碰,歸 venue/organization 的重複 key 沒有任何檢查:export-bib 會崩潰(uniqueKeysWithValues),其他面安靜地選一筆 #669、venue/organization 的 key 重複時,以 key 定位的寫入面仍安靜地寫進第一筆 #670 那一族。
    • MCP akashic_update_person 的 inputSchema 屬性 judgement 還寫「動到 authorized 時必填;仍是對外形的寫確認」(devil's advocate,1 席)。工具的 description 已改成「只替進出的名字寫指定/撤回」,真 binary 的 tools/list(58,949 位元組)回的屬性說明卻沒改;照屬性說明呼叫,對沒動的名字附理由,會被「沒有讓任何名字進出 authorized」擋下(CLI 重現:rc=1、零寫入)。CLI help、store-format §3.5、design 都改了,只有這個機器可讀的契約漏了,也沒有測試守屬性文字;改一句位元組持平,在約 1,050 位元組的餘裕內。

    進下一輪修正(2026-10-09 開始)。

    逐則處置見 changelog:changelog/2026-10-05-b34-k1-fixes-564.md(R3 的處置)。

  8. kiki830621 commented on Oct 14, 2026

    @kiki830621
    MemberAuthor

    Verify R5(2026-10-15):HIGH 0、MEDIUM 3,進修正輪

    R5 是六席交叉驗證(四個 Claude lens、devil's advocate、Codex 跨模型),驗的是 R4 的修正 0071c0af(b37 修正輪,2026-10-10 推上 main f2a321e4)。六席都完成:第一次啟動(2026-10-10)撞到帳號用量上限,2026-10-12 與 2026-10-14 續跑。表中是 findings 的原始筆數(INFO 不列);下面把同一件事被多席提出的合併成一條,括號是席數。Codex 這一席沒有提出 finding。

    輪 HIGH MEDIUM LOW 之後的修正
    R5 0 3 12 —

    R4 的 MEDIUM 怎麼修的

    b36 的 4 個 MEDIUM(其中兩則經 devil's advocate 校正為 LOW),0071c0af 的處置:

    • organization remove_names 與 venue edit_name_segment 的報告把每段 attested 截在 20 個,最後一項用文字說出省略數(不新增回應鍵),讀取面全列;真 binary 單段 20,000 個觀測點的回應從 460,506 位元組降到 1,095。
    • update-person --fields 遇到兩筆不同 person 共用同一個 key 時拒絕(乾跑同),先前寫進先載入的那一筆。
    • MCP akashic_update_person 的 judgement 屬性說明改成「名字進出 authorized 時必填,否則拒收」,新測試走真 binary 的 tools/list。
    • 被併者自己的最後一筆與分類矛盾就拒絕,結論不再取決於被併者 key 的拼法。
      使用者 2026-10-05 對修正輪三的三項裁決已照辦;changelog 另留五項待使用者回答的事,這一輪補進 ### Blocking(見下)。

    R5 的 MEDIUM

    • 被併者自己不一致的拒絕,範圍比描述的寬,連「被併者什麼都不搬」的合併也擋,訊息還說錯(regression、devil's advocate 列為 MEDIUM;logic、requirements 在 LOW 提同一件事,共 4 席;真 binary 重現)。doomedTailConflicts 看的是候選佇列,不是 carryCollecting 真的搬進去的記錄,也沒套用倖存者那邊的 old.contains(g) 豁免。重現一:倖存者與被併者逐位元組持有同一個矛盾(名字在 variant、最後一筆是「指定」),b37 前合併通過,現在 dry-run 拒絕,訊息一邊寫「倖存者合併前就有的矛盾不擋」,一邊說矛盾是被併者「帶來」的。重現二:倖存者完全一致、被併者只是它歷史的前綴,合併什麼都不搬,base 通過、現在拒絕,訊息的「合併後最後一筆是「指定」」為假。重現三:照拒絕訊息的出口做(對被併者把名字移進再移回 authorized,附兩筆為了過守衛編的 --judgement),合併後倖存者的 references 多出 4 筆永久歷史。另外,openspec 同一條 Requirement 的兩個 SHALL 在這兩個形狀上結論相反;NameClassificationMergeOrderTests 的被併者 fixture 由 .withdraw 改成 .confirm,剛好避開原本鎖住這個形狀的案例;changelog 的「交給使用者」第 3 點只描述了「先前一致的記錄排在後面就放行」那一種變嚴。方向:把檢查限縮在真的會搬進去的記錄,或對倖存者原始歷史已持有位元組相同記錄的群組豁免(不能綁處理順序)。
    • organization remove_names 的回應總量仍無上限(devil's advocate 列為 MEDIUM;security 在 LOW 提同一件事,共 2 席)。b37 只封了每段的 attested;一個名字最多 20 段、一次最多 200 個名字,兩個維度都不封頂。devil's advocate 造 200 個已撤回的名字、各 20 段(帶 300 字元的 source、note),MCP 單次回應 3,011,093 位元組;security 造 200 名 × 21 段 × 21 個 attested,4,699,784 位元組(org 檔 3.7 MB,低於 4 MiB 的 warning 門檻)。venue 的 edit_name_segment 有 detailLimit(超過 20 項只列名稱、動作、理由,以 detailsTruncated 揭露),org 沒有對應物;repo 其他進 LLM context 的列表都受 candidateByteBudget(48 KiB)約束。單段 60,000 個觀測點的形狀確實達標(CLI 1,095、MCP 1,293 位元組)。

    值得記的 LOW

    • update-person --fields --dry-run 對 legacy 同 id 拷貝說 wouldChange,實跑拒絕(requirements、logic;devil's advocate 校正:base 的 binary 對同一個 store 同樣回 wouldChange,不是這個 diff 引入,新 guard 是淨改善)。
    • judgement 屬性說明「必填,否則拒收」讀起來像「沒附就拒」,真正新增的限制是「沒有名字進出卻附了就拒」(logic、regression);測試只釘三個詞各出現一次。
    • 合併拒絕的出口句:venue 名字是 authorized 時,variant 方向的兩條支線第一步 --add-variant 都被 store 擋下;authorized 方向照做三步後還要第四步才通過(requirements、devil's advocate)。
    • MCP 工具說明沒寫 attested 最後一項是文字、也沒寫重複 key 拒絕(logic);tools/list 是 59,173/60,000 位元組。

    待使用者裁決

    已裁決(使用者 2026-10-15):合併時「被併者自己不一致就拒絕」收窄:只在被併者真的會把記錄搬進倖存者、且原始倖存者沒有同一個矛盾時才拒絕。下一輪恢復被改掉的測試資料,補上 twin 與「什麼都不搬」兩種情形的測試,拒絕訊息另寫被併者自己矛盾時的措辭。

    仍待裁決的四項:issue 的 ### Blocking 原本只有「下一輪 verify」(devil's advocate LOW),現在各自列進 Blocking。

    1. 附了 --judgement 而沒有名字進出 authorized 時整批拒絕(比 2026-10-05 裁決 2、3 嚴):維持拒絕,還是改成放行並回報「理由沒有寫進任何記錄」?
    2. issue Expected 3(確認既有的值留記錄)對 person 不再成立(live store 4,575 個對外形都是機械值):另給 person 一個確認面,還是把 Expected 3 對 person 標成不適用?
    3. 報告的 attested 截在 20 個、以最後一項文字說出省略數、讀取面全列:維持,還是另加回應鍵、或讀取面也截?
    4. akashic-verify-person、akashic-promote-literals 叫 agent 整份讀回 names 再寫,沒提醒要保留 authorized:要不要補一行提醒?

    進下一輪修正。

    逐則處置見 changelog:changelog/2026-10-09-b37-n1-fixes-564.md(R4 的處置)。

  9. kiki830621 commented on Oct 14, 2026

    @kiki830621
    MemberAuthor

    Decision(2026-10-15,使用者):「被併者自己不一致就拒絕」收窄

    b38 verify(R5)有兩席獨立實測:b37 新加的「被併者自己的分類紀錄不一致就拒絕合併」也會擋下兩種合併。一種是被併者什麼都不搬的合併,另一種是被併者只重複了倖存者原本就有的矛盾。這和同一條 Requirement 的「倖存者合併前就有的矛盾不擋」互相衝突。原本鎖住這個情形的測試,資料被改掉了。

    # 問題 裁決
    1 doomedTailConflicts 判的是被併者自己的記錄尾端,沒有看這次是否真的搬了記錄,也沒有看倖存者原本是否已有同一個矛盾 收窄:只在被併者真的會把記錄搬進倖存者、而且原始倖存者沒有同一個矛盾時才拒絕(豁免條件綁原始倖存者的歷史,不綁處理順序)。下一輪恢復被改掉的測試資料,補上 twin 與「什麼都不搬」兩種情形的測試,拒絕訊息另寫被併者自己矛盾時的措辭
  10. kiki830621 commented on Oct 18, 2026

    @kiki830621
    MemberAuthor

    Verify R6(2026-10-19):HIGH 0、MEDIUM 1,進修正輪

    R6 是六席交叉驗證(四個 Claude lens、devil's advocate、Codex 跨模型),驗的是 R5 的修正 a3aeaf32(b39 修正輪,2026-10-18 推上 main 04131a49)。六席都完成。表中是 findings 的原始筆數(INFO 不列)。

    輪 HIGH MEDIUM LOW 之後的修正
    R5 0 3 12 a3aeaf32
    R6 0 1 11 —

    R5 的 MEDIUM 怎麼修的

    照使用者 2026-10-15 的收窄裁決:被併者自己的名字分類記錄與分類不一致時,只有在「被併者單獨併進原始倖存者會把那個(分割, 名字)的記錄搬進去」而且「原始倖存者沒有同一個矛盾」時才拒絕;organization remove_names 的 MCP 報告合計至多 20 段,以 detailsTruncated/detailsListed 揭露;update-person 的乾跑跑 #631 的前置,legacy 同 id 拷貝在乾跑與實跑以同一句拒絕。devil's advocate 逐字比對了整合時移植到 PR #736 字串結構上的拒絕訊息,與 b39 分支相同。

    R6 的 MEDIUM

    • 拒絕訊息給的出口(Codex,未重現):名字在 authorized、而名字段帶時間欄位時,出口的三步裡第一步 --unauthorize 會寫入,第二步 --add-variant 卻會被「異寫不得帶時間」的不變式拒絕,名字卡在中間。修正輪先以真 binary 重現再修。

    值得記的 LOW

    • 攣生豁免的實際效果(logic,真 binary 重現):兩筆攣生都持有「仍在 authorized、最後一筆是撤回」時,合併放行,但仍重搬被併者較早的「指定」,倖存者的最後一筆被翻成指定。spec、changelog 與測試說的「什麼都不搬、倖存者記錄不變」只對單筆指定的形狀成立。
    • organization remove_names 的 MCP 報告只限段數不限位元組(security、devil's advocate):20 段之內,控制字元逃脫後實測 141–326 KB;「小於 48 KiB」只對測試用的那份 fixture 成立。
    • update-person 的乾跑只補了 writeEntry/rename 在 entities 佈局下留下 legacy 拷貝,自己造出同 id 的重複(sister concern from #627) #631 前置(logic、regression,真 binary):寫出位元組上限(寫入路徑的 2 倍寬限讓一次寫入就能產出讀不回來的檔——judge/refute 理由無上限、預警擋不住單步跳躍 #648)仍是乾跑回 wouldChange、實跑被拒。
    • 「同一個方向」(devil's advocate):載入時就會隔離錨不到 names 的名字分類記錄,而方向其實等於成員資格,所以這個條件在任何載入得了的 store 上都不改變結果;changelog 等處「手改、載入不驗」的說法為假。
    • 裁決表文字(requirements、logic、regression):docs/rulings/zero-instance-guards.md 第 96、98 列與「各列共通」段自相矛盾;docs/rulings/mcp-cli-parity.md CLI-only 表的 resolve-divergence 列沒有 b39 的重新確認;spec delta 沒有寫出程式的收緊。

    待使用者裁決

    ### Blocking 原有的四項不動。b39 讀法確認那一項補上 devil's advocate 的實測(兩種讀法在真實 store 上給出同一個答案)。另新增兩項:攣生豁免下合併重搬較早記錄要不要改成不重搬(行為改動);名字層級的省略新增 detailsTruncated/detailsListed 兩個回應鍵,是否在 2026-10-05「不新增回應鍵」的範圍之外。

    進下一輪修正。

  11. kiki830621 commented on Oct 19, 2026

    @kiki830621
    MemberAuthor

    Verify R7(2026-10-20):HIGH 0、MEDIUM 0,verified

    R7 用六席交叉驗證 R6 的修正 a5ff5093(b41 修正輪,2026-10-19 推上 main 7ba4d695):四個 Claude lens、devil's advocate、Codex 跨模型,六席都完成。表中是 findings 的原始筆數,不含 INFO。

    輪 HIGH MEDIUM LOW 之後的修正
    R5 0 3 12 a3aeaf32
    R6 0 1 11 a5ff5093
    R7 0 0 16 —

    R6 的 MEDIUM 怎麼修的

    狀況:名字段帶時間欄位,variant 欄不在 variant、卻以指定或確認結尾。這時合併的拒絕訊息一開頭就說明工具面的步驟走不通,只能手改,並寫出要改什麼。舊的三步出口不再給,因為第一步寫入之後,第二步一定被拒。

    devil's advocate 用真 binary 照新訊息手改,之後合併通過。

    值得記的 LOW(都不擋 verified)

    • 「工具面沒有出口」說得太滿(requirements、logic、devil's advocate 三席,真 binary 重現):
      • 名字只有一段時,有一條工具路徑走得通:先用 --edit-name-segment 清掉時間,做完三步,最後補回時間。
      • 名字有兩段同名、不相交的沿革時,這條路才會被近重複的檢查擋下。
      • 訊息、store-format §3.5 與 spec 新句把多段的情形寫成了全稱。
    • MCP update_person 的 dry_run 說明過度承諾(requirements、logic、regression、devil's advocate 四席):
      • 說明寫「實跑會拒的也拒」。實際上 format 閘、名字分類閘與驗證錯誤,乾跑都以成功回應加 blockedBy* 鍵回報,而 tools/list 完全沒有提到這些鍵。
      • 修正要把說明加長約 60 位元組。tools/list 目前 59,159,預算 60,000。
    • 兄弟面 akashic_update_venue.edit_name_segment 有同形的回應放大(requirements、regression、devil's advocate 三席實測 221–401 KB):b41 的 changelog 寫「可另案」,但沒有 issue 號。追蹤開在 akashic_update_venue 的 edit_name_segment/remove_reference 回應沒有位元組上限:控制字元逃脫後實測 22–40 萬位元組(#564 follow-up) #739。
    • spec delta 有兩處和現況不合(requirements、regression):
      • 新 Requirement 寫「不得點名工具步驟」,訊息與測試卻點名了 --unauthorize/--add-variant。
      • 待使用者裁決的「攣生豁免時重搬較早的記錄」被寫成 SHALL Scenario。
    • 出口句的「它」指涉兩個東西(logic、devil's advocate):「第四步再 --authorize 它補回」照字面讀,會把剛撤掉的名字又指定回去。
    • 乾跑的 blockedBy* 只回第一道之後的那一道(regression,真 binary):format 9 加上巢狀 names 時,乾跑報 format 22 閘,實跑卻停在 format 10 閘,兩邊給的補救步驟不同。這個 store 狀態很罕見。

    待使用者裁決

    ### Blocking 原有的裁決項不動。新增一項:上面那句「工具面沒有出口」要收窄成「沒有直接的工具出口」,還是保留「只建議手改」?這牽涉工具路徑要不要先改寫時間資料。

    HIGH 與 MEDIUM 都是 0,標為 verified。LOW 不擋,但其中三則(dry_run 說明、出口用詞、spec delta)若之後有修正輪會一起處理。關閉 issue 前,先處理 ### Blocking 裡的裁決項,再跑 /idd-close。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureNew capability

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions