瀏覽 1.1.1 文件
1.1.1

Binary DB v0:身份、恢復與轉換

展開公開控制代碼的作用域、原子寫入與恢復邊界、轉換的接納條件、容量與排除項。

適用對象: 遷移、恢復與相容性實作者

schema 的最後一章把物理記錄同對外身份、崩潰恢復以及被接納的轉換連線 起來。它同時給出硬性容量上限、明確排除在外的領域和檔案,以及佈局 v0 的相容性邊界。

對外身份與緊湊控制代碼#

  • Task 身份以權威為作用域,由稠密的記錄序號推導得出。
  • Change 用 C-01..C-64 表示序號 0..63
  • 已發布 Local Change 的 Remote 身份,是所屬 Local Task 已發布的 Remote Task 索引,與所存的 Remote Change 序號配對而成; 它不是全域性 Remote Change 索引。
  • Land 在所屬 Change 內用 L-01..L-64 表示序號 0..63;它完整的 對外身份包含 Task 和 Change 身份。
  • Patchset 在所屬 Change 內用 P-01..P-64 表示序號 0..63;它完整的 對外身份包含 Task 和 Change 身份。
  • Attestation 用 A-01..A-64 表示序號 0..63
  • Review 在所屬 Patchset 內用 R-01..R-64 表示序號 0..63;它完整的 對外身份包含 Task、Change 和 Patchset 身份。
  • Policy Decision 在所屬 Patchset 內用 K-01..K-64 表示序號 0..63; 它完整的對外身份包含 Task、Change 和 Patchset 身份。
  • Waiver 用 W-01..W-64 表示序號 0..63
  • Task Snapshot Link 用 S-01..S-256 表示序號 0..255
  • Stash 身份由 stash_index 推導得出,例如 STH-000001
  • AIT Tag 的對外身份就是它的名字;穩定的內部引用使用稠密的 tag_index,從不需要文字形式的 Tag ID。
  • 規範的 Snapshot 身份是 SNP- 加一段 48 位十六進位制字尾。
  • Tree 和 Blob 的對外字尾是 80 位。
  • Tree Pack 和 Object Pack 的對外字尾是 48 位。
  • Git repository 指紋是 96 位字尾,匯入/匯出 generation 與 operation 身份是 64 位字尾,Plan 雜湊是 96 位字尾, Git 對映身份是推匯出的 80 位 GIM-* 字尾。

每個八位工作流程控制代碼,在其宣告的所屬作用域內都使用下面這套位模型:

程式碼 · text
bits 0..5 ordinal 0..63 within (owning identity, kind)
bit 6 tombstone/deleted
bit 7 indirect/extended

Change、Attestation 和 Waiver 保持各自宣告的、以 Task 為作用域的分配方式。 Patchset 和 Land 在所屬 Change 內分配。Review 和 Policy Decision 在所屬 Patchset 內分配。因此同一個 Task 裡不同 Change 之間, Patchset 或 Land 序號可以重複;不同 Patchset 之間,Review 或 Policy 序號也可以重複。完整的所屬身份能把每一個重複的數字字尾區分開。

佈局 v0 沒有指定擴充套件控制代碼的 payload 格式。寫入方一旦會超出宣告的序號 範圍,就必須在寫入之前失敗;它不得把 indirect 位當成自行發明一種格式的 許可。

多檔案寫入與恢復邊界#

佈局 v0 沒有定義工作流程層面的 wal.binjournal.bin、事務 ID 欄位、 按記錄的 WAL 序列,也沒有 Binary DB 啟用 generation 令牌。 GitGenerationRecord 標識的是匯入的 Git 源狀態或一份確定性的 匯出計劃;它不是資料庫事務令牌。寫入方的事務層負責單寫入方/按 Task 加鎖、依賴優先寫入、有序的 fsync、只追加的提交點,以及可修復的 head/索引投影。

追加進去的明細記錄,就是 Patchset、Review、 Policy Decision、Waiver、Attestation 和 Land 建立時的領域提交點。相關的 task、 change 或 patchset 頭部記錄都是可修復的投影。Land 狀態變更採用 status-last 協議:先寫入終態/重置資料並 fsync,再把 status_kind 作為 提交標記寫入並 fsync。

tree_entry_range.bin 是唯一按序號對齊的定長依賴檔案,它既不是 payload,也不是可重建索引。建立時會先寫入每一條必需的區間行並 fsync, 之後才寫所屬的 Tree 提交記錄。在穩定的啟用邊界上,它的條數等於 Tree 屬主檔案的條數;恢復時只能丟棄未提交的尾部依賴,遇到已提交依賴 缺失或中間序號不匹配則必須 fail closed。Task 關閉的變更完全發生在 task.bin 內部;Change 歸檔/重開的變更完全發生在 change.bin 內部。Land 建立會追加並持久提交一條完整的 land.bin 記錄。每一次變更都替換或追加它那一條完整的定長 記錄。若一次覆寫沒有抵達提交點,事務層會恢復其前像;單條記錄內部 欄位之間的順序對外不可觀測。

恢復過程會校驗每一個頭部和記錄對齊,遍歷已提交的明細 記錄,修復 latest_*_index_plus1、計數和 next 序號,重算 最新/目前 Patchset 索引,按所屬關係和存活性校驗每個 Remote Change 選中的 Patchset 指標(而不是從 Patchset 後設資料重建它),忽略孤立的依賴/payload 行, 並把每個宣告身份作用域內的重複序號判定為損壞而拒絕。Task 層面用於 Patchset、Review、Policy Decision 和 Land 的索引只重建物理 清單順序。它們的屬主索引則重建序號鏈和 next 序號分配:Patchset 和 Land 的屬主是 Change,Review 和 Policy Decision 的屬主是 Patchset。不同屬主作用域下出現相同的數字序號是合法的。

Snapshot 建立時會先追加每一條經過校驗的父邊並對邊檔案 fsync, 之後才追加帶 bit 4 置位的子 Snapshot 記錄。Snapshot 記錄 就是提交點;寫入被打斷可能只留下孤立的邊,恢復時會忽略它們。 恢復過程還會校驗:遠端 head 的歷史邊界沒有本地父級, 且零父級的非邊界 Snapshot 確實是真正的根。Tag payload 必須在 Tag 記錄追加/更新之前落盤持久化。

Tree 建立時先追加歸一化的 Tree entry 行和與之匹配的定長區間, 再寫 Tree 提交記錄。恢復過程會對照所屬 Tree 校驗歸一化區間,並按 Tree Pack 的稀疏序號位校驗每一個物理 pack 序號,然後才接納該 pack 投影。

Git repository、generation、identity、parent、file 以及帶型別的 payload 行都是 依賴。不可變的 Git commit/ref/Tag 對映記錄是其對映的 提交點,會先於可重建索引候選完成 fsync。恢復過程會 忽略從已提交對映不可達的依賴行,校驗全部 對映區間和數值形式的 AIT 引用,然後重建 Git 索引。Git operation checkpoint 會先寫入自己的遊標和時間,再寫入並 fsync checkpoint_meta;重放一個已完成的 checkpoint 是空操作,可從不可變對映 重建得出。

bin 到 bin 的轉換接納條件#

轉換器必須把每一個源欄位歸入以下幾類之一:精確的定長欄位/位 對映、唯一被接納的 Patchset summary payload、schema 定義的 推導,或明確的非權威投影。落在這幾類之外的欄位會 fail closed; 不得把它塞進通用 payload。

離線轉換器寫入的是一個獨立的目標 generation,可以分配新的 稠密物理目標記錄索引。它保留源端的 Task 順序,並且對其他 每一個權威檔案家族,在已寫出的行之間保留經過校驗的源記錄順序。 在寫記錄之前,它會為每個被接納的家族建立完整的源索引到目標索引的 對映。隨後透過這些對映改寫每一個屬主 索引、*_index*_index_plus1、前一條記錄的連結、selected/latest 指標、定長區間起點、按序號對齊的旁路行,以及重算後的 payload 偏移。可重建的 .idx 檔案是從完成後的目標權威生成的,而不是複製過來的。

物理重編號絕不改變 change_ordinalpatch_ordinalattest_ordinalreview_ordinalpolicy_ordinalwaiver_ordinalland_ordinalsnapshot_ordinal;它們的對外控制代碼在各自宣告的作用域內 保留與源端完全一致的序號。Patchset 序號在 Change 內保留, Review 序號在 Patchset 內保留,Policy Decision 序號在 Patchset 內保留,Land 序號在 Change 內保留。跨不同所屬 Change 或 Patchset 的重複是合法的,不會被重新編號。對 Policy Decision 而言, 被接納的遺留 .../P-##/POL-## 身份會把確切的 POL-## 字尾對映到 以 Patchset 為作用域的 K-##

同一個宣告屬主作用域內出現任何重複、同一種類在該屬主作用域內超過 64 行、所屬關係有歧義,或源 ID 與定長序列不一致,都會 fail closed。Task 層面的 Patchset、Review、Policy 和 Land 清單 連結按寫出的物理記錄順序重建。Change 的 Patchset 和 Land 連結,以及 Patchset 的 Review 和 Policy 連結,按確切序號重建。任何 在目標對映中沒有恰好一條對應項的源引用都會 fail closed。源 檔案保持不可變,完全透過校驗的目標 generation 會被原子啟用。 不會額外增加任何新舊對映的 bin 或 payload。

唯一被接納的 diff_stats 不一致情形,是顯式選中的 離線遺留 stale-zero 閘門。該閘門使用一份精確設定的、由完整 Patchset 身份組成的允許列表;禁止部分匹配、只按序號匹配或通配匹配。

對於列表中的每個 Patchset,提供的值必須是完整物件,其中 files_added = 0files_changed = 0files_deleted = 0files_modified = 0,並且 paths.addedpaths.deletedpaths.modified 陣列恰好為空。它規範的 base 和 revision Snapshot 引用 必須都能解析到存在且存活的 v0 Snapshot 權威,且對二者 完整 Tree 的精確比較必須成功併產生非空差異。轉換器隨後 只用這份重算出來的差異來校驗是否可接納; 目標端不儲存任何 diff-stat 值。

沒有顯式開啟該閘門時,任何不一致都會 fail closed。即便開啟了 閘門,未列入或僅部分匹配的身份、缺失/多餘/改名的 diff_stats 成員、提供的非零計數、提供的非空路徑 陣列、重算出的零差異、缺失/被墓碑標記/格式錯誤的 Snapshot、 不可讀或格式錯誤的 Tree,以及任何其他不一致,都會 fail closed。不接納任何 通配、只按序號匹配、兜底 Snapshot、重建出來的源值、 新欄位、新位、新 bin、新索引、新 payload、記錄寬度變更或 layout_id 變更。

唯一被接納的另一種源 Task 狀態寫法,是顯式 選中的、繫結到確切 repository 鍵和完整鎖定源清單摘要的離線閘門。 服務端編排器會在轉發該閘門之前校驗這兩個值。僅在該閘門下,源端的 status = "canceled" 對映到既有的 TaskRecord.task_meta bit 7, 與源端 status = "abandoned" 完全一致。遺留 payload 裡沒有 Task 關閉時間欄位,因此轉換後的終態 Task 會依據既有的"關閉時間未知"規則 保留 closed_at_s = 0

沒有顯式開啟該閘門時,源端 status = "canceled" 會 fail closed。即便 開啟了它,另一份清單、另一個 repository 鍵、部分或大小寫摺疊的 寫法,以及任何其他未知的 Task 狀態,都會 fail closed。該閘門不會 改變轉換報告,也不會新增任何欄位、位、bin、索引、payload、 記錄寬度變更、重建標記、推斷出的時間戳,或 layout_id 變更。

第一種引用缺失的例外,是針對某個 Patchset 的顯式選中離線 遺留搶救模式——該 Patchset 規範的 revision_snapshot_id 在同一份鎖定源 generation 的內容 Snapshot 權威中不存在。沒有開啟那個顯式模式時, 引用缺失會 fail closed。開啟之後,轉換器 不為該 Patchset 寫出任何行,也不寫出任何依賴被省略 Patchset 的 Review、 Policy Decision 或 Check、Attestation、Land。如果 被省略的 Patchset 是所屬 Change 權威的 current/latest 或 selected Patchset,轉換器就不為該 Change 及其任何 Patchset 和依賴項寫出行;它絕不會挑一個兜底的 current 或 selected Patchset。所屬的 Task 仍然保留。

這一例外不接納缺失的或哨兵值的 Patchset Snapshot 索引, 不會憑空造出或墓碑標記一個 Snapshot,也不會豁免缺失的 base Snapshot、格式錯誤的 Snapshot ID、已被墓碑標記或損壞的現存 Snapshot, 以及任何無關的權威缺失。目標端的 Change、Patchset、Review、Policy、 Attestation、Land 和 Actor 行在寫出的行之間保留源順序, 每一個存留下來的定長引用、鏈頭、計數、selected/latest 指標、 按序號對齊的旁路行和可重建索引都會被稠密地重對映。 轉換報告必須逐一列出被省略的 Change 和 Patchset 身份, 以及寫出/省略的依賴行計數;省略絕不靜默發生, 也絕不改動源位元組。

第二種省略例外,是針對某個確切設定的 Change 身份、需要單獨選中的 具名遺留搶救。那個源 Change 聲稱已 landed,但沒有存留下來的成功 Land, 也沒有完整的、可據以重建的已接受 Patchset/Snapshot 閉包。沒有那個確切具名選項時,轉換會 fail closed。開啟之後, 轉換器會省略該 Change、它擁有的每一個 Patchset 和依賴行,以及每一條引用它的 Land 行; 它不會憑空造出 Land、不會挑兜底 Patchset、不會推斷時間戳, 也不會影響任何其他 Change。報告中必須寫明所選中的 Change 及全部 依賴行計數。不允許任何通配、基於狀態或隱式的省略。

被接納的遺留 landed Change 歸一化,比上面幾種省略例外的範圍更窄。 對於 current_patchset_number = 0 的 Change,只有當它顯式的 selected 指標指向同一個 Patchset 時,才從它存留下來的最大 patch_ordinal 重建 latest/current。即便重複出現的 Change statuslanded_at 投影有出入,確切的 Land 行依然權威。每一次嘗試都會被保留, 只要有一次嘗試成功,Change 的生命週期就是 landed,且由最大的成功 land_ordinal 提供 landed 狀態——哪怕之後還有一次未成功的嘗試。目前 可變的 selected 指標不必等於任何歷史 Land 所接受的 Patchset。這些規則只丟棄重複的投影,絕不丟棄 權威行,也不新增任何欄位、位、bin、payload、兜底 Patchset 或 推斷出的時間戳。

在轉換之前,服務端編排器可以在不獲取也不建立源鎖的前提下,把源權威 複製到一個隔離的凍結 generation 中。凍結操作會在複製前 捕獲目前每一個權威資料檔案,複製這些捕獲到的檔案而不是信任 活躍 generation 那份可能已經過期的檔案列表,然後再次捕獲完整的 源清單,並要求按 relative_pathbyte_size 和完整 SHA-256 做到複製前/複製後/副本三者精確相等。它還要求源登錄檔清單的 確切位元組在整個操作過程中保持不變。任何漂移都會 fail closed,且不會留下 已發布的目標。新生成的凍結 generation 沿用既有的清單 schema,其檔案列表 和指紋恰好對應那些被複制的位元組。Repository 清單副本和執行期鎖檔案不計入資料檔案 列表。只有當每一個宣告的檔案都匹配、且不存在未宣告的權威資料檔案時, 轉換才會接受那個凍結 generation。

無論在選中的源裡還是在凍結副本裡,都不要求也不建立源鎖檔案。 只有當選中的源清單明確證明某個確切檔案或它整個宣告家族的記錄數為零, 或者該權威類別根本不包含那整個可選家族、並且沒有任何存留的源記錄 會引用它時,編排器才可以把缺失的遺留 .bin.idx 建立為只有頭部的檔案。家族只存在一部分、清單計數非零、 存在未解析的引用,或缺少證明,都會 fail closed。 絕不在選中的源根目錄裡做 頭部合成,且轉換報告會逐一列出每一個暫存的只有頭部的檔案。

新接納的時間缺失置零情形僅限於 RemoteTaskRecord.updated_at_sRemoteTaskRecord.fetched_at_sRemoteChangeRecord.fetched_at_s、已歸檔的 RemoteChangeRecord.archived_at_s,以及 ActorRecord.created_at_s/last_seen_at_s。它們只在所選 遺留源格式確實沒有對應時間欄位時才適用。 先前列舉的遺留 Task closed_at_s 和首次成功 Land 的 submitted_at_s 例外保持不變。除此之外,其他缺失或非法的時間都不會 變成零,且零值不授權任何合成時間或重建位。

源端的 identity_source 是註解,不是被儲存的身份。只有當它缺失, 或與從選中權威根和數值形式的記錄關係推匯出的規範身份一致時,才可以 省略它。非預設、衝突或無法解析的值會 fail closed。源端的 published_remote_name 同樣不被儲存。只有當它缺失/為空, 或與本次轉換顯式選定的那一個遠端權威完全相等時,才可以省略它; 不同的或有歧義的遠端名稱會 fail closed。

只有當源權威能證明某個源 Snapshot 確實沒有父級時,它才會成為真正的 v0 根。因此被證明為空的權威依然為空,兩個或更多被獨立證明的根,在同一片 DAG 森林中依然是各自獨立的連通分量。每一個存留的非邊界 Snapshot 都必須 能到達這樣一個根。如果源端證據反而表明它有祖先、只是那些父級沒有被 匯入,轉換器就會設定 remote_head_history_boundary;若證據不足、 無法區分這兩種情況,則 fail closed。轉換器絕不會僅憑位置、記錄順序、 連通分量大小、Line 歸屬或目前 head 狀態就推斷出一個根或歷史邊界。

文字形式的對外 ID 只按其宣告的緊湊序號或 雜湊規則解析,隨後再對照所屬的定長記錄做校驗。源端的快取 鍵、推匯出的標籤/訊息、重複的名稱、diff 統計和結果 投影,只有在本權威文件所列的顯式推導規則之下才可以被丟棄。未知的 列舉文字、溢位、不一致、權威缺失或解析有歧義,都會在啟用之前中止轉換。

容量與擴充套件#

在做任何部分追加之前,寫入方都會預檢可表示的計數和窄欄位:

程式碼 · text
current_count  = (file_size - BIN_HEADER_SIZE) / record_size
projected_count = current_count + records_to_append

超長的 u8/u16 文字屬於輸入校驗失敗,不是加寬佈局 v0 的 許可。除了明確列舉的 Task closed_at_s 尾部、Change 生命週期尾部、Land 目標 Line 尾部,以及 Patchset summary/Worker Job 定位符/時間寬度這幾項修正,加上列舉出的 Git 對映 時間欄位移除,以及單獨劃定作用域的執行期家族之外,真正的 記錄/索引容量擴充套件都需要顯式遷移到新的 layout_id,轉換完整的依賴引用閉包,寫入 獨立的新檔案,校驗它們,並執行原子切換。有界的 執行期轉換會遷移並收窄 Worker Job 記錄,廢止它的 全域性身份家族,只新增兩個宣告的本地索引,並只追加 宣告的 Patchset 定位符;更早的定長時間修正只收窄了具名的、 帶時間戳的那些記錄以及 ready 索引。隨後的 u64 秒轉換隻加寬 完整列舉出的普通時間欄位集合。這兩次轉換都不允許改動其他欄位或檔案。 即便持久化的佈局編號仍然是 1,同一個檔案裡混用不同記錄寬度依然是禁止的。

儘管 parent_countparent_ordinalu16,Snapshot 父級數量的上限仍是 1,024。AIT Tag payload 的上限由 u16 payload_len 決定。 Git payload 和單欄位長度值的上限由 u32 決定;Git SHA-1、 指紋、generation、operation 和 Plan 雜湊的位元組陣列,都採用上面宣告的確切 定長寬度。除了明確移除的 AIT 生成的對映時間戳之外,禁止收窄、截斷、用雜湊字首 替代,也禁止在這些 20 位元組欄位裡接受 SHA-256 的 Git Object ID。

剩下的那一個按序號對齊的旁路檔案家族,會在寫入前預檢其屬主計數和 所有 u32 索引。它是 layout-1 的 schema 擴充套件,不是 加寬既有記錄或把其欄位搬進 payload 的許可。

Task 尾部是一次性的 layout-1 轉換,不構成通用的 加寬先例。轉換必須顯式選中舊的本地 40 位元組或 遠端 36 位元組源佈局,把整個檔案改寫成修正後的本地 44 位元組或遠端 40 位元組佈局,並且只有在完整校驗之後才啟用。

Change 尾部同樣是一次性的 layout-1 轉換。 對緊鄰的前一種拆分表示做轉換時,必須顯式 選中 44 位元組的 Change 源佈局及其對齊的 8 位元組生命週期 源,改寫並校驗完整的 52 位元組 change.bin,在新 generation 中省略 change_lifecycle.bin,並且只有在每一處 base Line、歸檔時間、屬主和 Snapshot 關係都校驗透過之後才啟用。

Land 尾部同樣是一次性的 layout-1 轉換。 對緊鄰的前一種拆分表示做轉換時,必須顯式 選中 32 位元組的 Local 或 36 位元組的 Server Land 源佈局及其對齊的 4 位元組目標 Line 源,改寫並校驗完整的 36 位元組 Local 或 40 位元組 Server land.bin,在新 generation 中省略 land_target_line.bin, 並且只有在每一處目標 Line、屬主、存在時的 Patchset、 Snapshot、序號鏈、狀態和時間戳關係都校驗透過之後才啟用。

Patchset summary 定位符同樣是一次性的 layout-1 轉換。 轉換 47 位元組的源時,必須先構造並校驗宣告的 57 位元組字首加 patchset_summary_payload.bin。之後的 Worker Job 定位符修正再顯式選中那個確切的 57 位元組 字首,追加 ci_worker_job_index_plus1,在一個獨立 generation 中寫入完整的 61 位元組 patchset.bin,並且只有在每一處 summary 區間、同 Repository 的 Worker Job 目標以及 Patchset 關係都校驗透過之後才原子啟用。

Repository 內本地化的 Worker Job 身份變更也是一次性的 layout-1 轉換。轉換時必須在宣告的 100 位元組源記錄存在時顯式選中它,移除其中的 u64 job_id,改寫並 校驗完整的 92 位元組 worker_job.bin,用兩個宣告的 Repository 本地索引 替換被取代的全域性 Job 序列/索引檔案,並且 只有在每一個永久本地索引、帶型別 payload、Patchset 定位符、狀態和時間戳都校驗透過之後才啟用。

之後的 Worker Job 定長記錄變更是又一次一次性的 layout-1 轉換。轉換時必須顯式選中那個確切的 92 位元組源記錄及其四個帶型別 payload 家族,解析並校驗 它們的完整閉包,在一個獨立的非啟用 generation 中寫入宣告的 88 位元組 worker_job.binworker_job_input_payload.bin,並在目標中省略 worker_job_request_payload.binworker_job_result_payload.binworker_job_error_payload.binworker_job_lease_owner_payload.bin。 只有在每一個 Job kind、定長引用、歸一化輸入、結果、相關 Job、 錯誤、lease 雜湊、Patchset 定位符、狀態和時間戳都校驗透過之後,才會啟用。

取消 payload 並改用執行期 lease 的變更是又一次一次性的 layout-1 轉換。轉換時必須顯式選中那個確切的 88 位元組源記錄和 worker_job_input_payload.bin,解析並校驗 它們的完整閉包,在一個獨立的非啟用 generation 中寫入宣告的 60 位元組 worker_job.bin,並在目標中省略 worker_job_input_payload.bin。 只有在定長引用、源 payload 契約以及"已靜默、無執行中 Job"的 閘門都校驗透過之後,它才丟棄源輸入區間和 lease_owner_hash。 轉換不會寫入任何執行期 lease 副本。只有在 每一個 Job kind、定長引用、結果、相關 Job、錯誤、 Patchset 定位符、狀態和時間戳都校驗透過之後,才會啟用。

之後的 Worker Job 直接引用變更是又一次一次性的 layout-1 轉換。轉換會顯式選中那個確切的 60 位元組源記錄,並寫入宣告的 52 位元組 worker_job.bin。 對 land.process 而言,舊的主體 Land 必須解析為確切的 maindirect、同 Repository 的 Server Land,其已接受的 Patchset 成為 patchset_index_plus1。對 main-seed.refresh 而言,舊的主體 Patchset 和 輔助的先前 Snapshot 成為那兩個具名欄位;它舊的上下文 Line 必須恰好是 main,並被丟棄。Patchset 的 CI、聚合和 Policy 主體成為 patchset_index_plus1repo.ci 主體在其舊的上下文 Line 精確校驗為 main 之後成為 snapshot_index_plus1。 內容維護和 Repository 對賬要求那三個舊的領域引用全部為零。 舊的相關 Job 引用在存在時會對源端的 attachedsuperseded 結果做精確校驗,隨後被丟棄。 只有在每一個新的具名引用、Job kind、結果、 錯誤、Patchset 定位符、狀態和時間戳都校驗透過之後,才會啟用。這次歷史 改寫不會讓原生 v0 的入隊依賴於一個已存在的 Land。

定長時間變更是又一次一次性的 layout-1 轉換。它選中 確切的 33 位元組 Repository、52 位元組 Worker Job、 12 位元組 ready 索引和 61 位元組 Patchset 前身,並改寫出 宣告的 25 位元組、36 位元組、8 位元組和 57 位元組目標。被接納的 RFC 3339 執行期時間戳會按上面宣告的方式歸一化,並有意縮減到整秒。既有的 Patchset ci_completed_at_s 值必須放得進 u32;溢位會在寫入任何目標之前 失敗,而不是被截斷。Patchset 的改寫保留其前 28 位元組以及邏輯上的 CI、summary 和 Job 定位符值,同時把尾部移到 修正後的偏移上。

同一次修正會選中確切的 100 位元組 commit 對映、84 位元組 ref 對映 和 52 位元組 Tag 對映前身,並寫出它們宣告的 92 位元組、 76 位元組和 44 位元組形式,其中不含 recorded_at_unix_nanos。在丟棄 這個由 AIT 生成的值之前,轉換會核實物理記錄順序 能復現源端每一次"最新記錄"的選擇結果;不一致則 fail closed。 帶簽名的 Git identity 時間戳和時區仍然是逐位元組保留語義的 源資料。只有在非啟用 generation 中,記錄整除關係、每一條 時間戳區間與排序規則、所有索引以及完整的依賴 引用閉包都校驗透過之後,才會啟用。

u64 秒變更是又一次一次性的 layout-1 轉換。 它唯一被接納的前身選擇符是確切的 u32-time-v0;只選 layout_id = 1,或者從檔案整除關係去猜,都是不夠的。該選擇符指的是 緊鄰的前一個完整活躍 v0 表示,其普通 *_at_s 欄位和寬度已在上面的修正表中 列舉。缺少選擇符、換成別的選擇符、出現未宣告的檔案、某個原始檔 未精確對齊到其具名前身寬度,或者出現混合寬度的 檔案,都會在發布任何目標之前失敗。

轉換會凍結或讀鎖定完整的源權威,並記錄其 完整檔案清單和指紋。對每一條定長記錄,它會按確切的宣告順序 複製宣告時間欄位之前、之間和之後的全部位元組,並把每個小端 u32 秒值零擴充套件成對應的小端 u64。它不會解析、取整、重排、推斷或 替換任何時間戳。它會逐位元組精確複製每一個不受影響的 payload 和物件。 GitIdentityRecord.timestamp_s 不做轉換。Worker 的 worker_ready.idx 會從轉換後的權威 Job 記錄重建; 其餘所有可重建索引,要麼從轉換後的權威重建,要麼對照未改動的身份和序號 鍵做精確校驗。

轉換器寫出一個完整的非啟用 generation,用活躍的 v0 編解碼器校驗 每一條修正後的記錄,校驗完整的跨檔案引用和內容閉包, 並把仍處於鎖定狀態的源指紋與它捕獲的前置條件做比較。啟用要求 讀寫方都相容,會重新檢查那個源前置條件,並原子地只選中完整的 generation,同時保留一個可恢復的先前 generation 或直接 權威。轉換失敗或凍結後源發生變化,都不會動到活躍 權威。活躍檔案絕不會混用前身和修正後的 記錄寬度,且在轉換或啟用持有權威鎖期間,任何執行時都不得寫入其中任一表示。

排除在外的領域與檔案#

佈局 v0 不定義:

  • wal.binjournal.bin 或按領域劃分的事務欄位;宣告的 Git 匯入/匯出內容 generation 是 v0 中唯一的 generation ID 例外;
  • Local Patchset 檔案、Local Change 記錄中的 selected-Patchset 遊標,或 不可變 Patchset 後設資料中的 selected-for-landing 權威;
  • 通用的 ci.binjob.bin;執行期作業只使用帶型別的、 以 Repository 為作用域的 worker_job.bin 家族,而緊湊的 Patchset CI 證據 及其選中的本地 Job 定位符仍留在 Patchset 記錄裡;
  • 通用的 patchset_payload.binattest_payload.binpolicy_payload.binland_payload.bin;型別收得很窄的 patchset_summary_payload.bin 是 Patchset 唯一的例外;
  • 任何 payload 或旁路檔案中的 Task 關閉時間;所屬 Task 記錄的 closed_at_s 尾部欄位是其唯一權威;
  • 任何 payload 或旁路檔案中的 Change base Line/歸檔狀態;所屬 Change 記錄的定長尾部欄位是它們的唯一權威;
  • 任何 payload 檔案中的 Land 目標 Line 身份或歸一化的 Tree entry 區間; 上面宣告的所屬 Land 記錄尾部和定長 Tree 區間旁路記錄 是它們的唯一權威;
  • 服務端的 Stash 檔案;
  • 僅用於轉換的 Actor 檔案或通用 Actor payload;轉換使用 既有的 actor.binactor_payload.bin 權威;
  • 共享字串池;
  • object_pack_data.bin;物件位元組仍留在它們的 pack 容器中;
  • line.bin 裡全儲存庫範圍的 current-Line 欄位;
  • snapshot_payload.bin 裡的 Snapshot 父索引擴充套件;
  • LocalChangeRecord 裡的全域性已發布 Remote Change 索引;
  • Git mirror 對映、最後一次 mirror 的 head 狀態、mirror 方向/階段、 執行期結果 JSON,或通用的 Git 對映 payload;
  • Worker Job 的結果 JSON、完整錯誤文字、文字形式的 lease 屬主身份,或 worker_job_request_payload.binworker_job_result_payload.binworker_job_error_payload.binworker_job_lease_owner_payload.bin 的活躍定義;worker_job_input_payload.bininput_leninput_offsetlease_owner_hash 同樣從活躍 v0 中 廢止;
  • Worker Job 的 Land 索引、目標 Line 索引、相關 Job 索引,或第二個 Snapshot 引用欄位;活躍 v0 只儲存 worker_job.bin 中宣告的那些具名 Patchset 和單個 Snapshot 引用;
  • identity_sourcepublished_remote_name、Git 對映中重複的 AIT Line/Tag 名稱,或文字形式儲存的 Line ID;
  • 作為 Binary DB 權威的通用執行期 payload、服務端排程策略/設定 payload、指標/時序儲存、追蹤/日誌儲存、通知/outbox 儲存、軟體包製品位元組、外部提供方令牌保險庫,或臨時的 執行期 lease 副本;
  • 其他服務端全域性執行期領域;活躍的執行期 v0 只包含 全域性 Repository 登錄檔/名稱 payload/名稱空間索引,以及上面宣告的 以 Repository 為作用域的 Worker Job 家族;
  • 服務端全域性的 Worker Job 定長記錄、payload、公開序列,或 排程/身份索引;定長的 Job 權威和兩個可重建的 Job 索引都留在各個數值 Repository 權威內部;
  • 作為 Binary 權威的已廢止執行期/規劃會話,或 Test 清單/覆蓋率資料; 以及
  • 從服務端全域性指向儲存庫工作流程/內容/Plan 權威的數值引用。那些跨根引用仍然是上面宣告的、帶型別的確切對外身份 位元組。

遺留的 SQLite 可以由顯式的一次性匯入/匯出工具讀取,但它不是 權威的執行期兜底。已落地的 .ait/git-interop/v1 JSON 對映/checkpoint 儲存同樣只能被一次顯式的一次性轉換讀取,轉換成宣告的 Git 定長記錄和帶型別 payload;它不是 並行的執行期權威。可選快取和可重建索引,絕不能成為某個領域關係的 唯一來源。

版本權威

對照 1.1.1 原始碼逐條核對

這一頁是公開文件,不是第二份產品契約。要確認發布權威,請以確切的原始碼和分發契約為準。

所屬元件 Snapshot
  • ait-coreSNP-ED7593DBF982
  • ait-serverSNP-0CCD7DD2A077
  • ait-runnerSNP-35C9C133D2EE
  • ait-pythonSNP-756C731A4CC0
  • ait-nodeSNP-55E90D0A81F1