Binary DB v0:payload、索引與編碼
展開每一類帶型別的 payload、可重建索引記錄、後設資料位分配、enum 以及保留值規則。
適用對象: 編解碼、校驗與遷移實作者
定長記錄經常指向帶型別的 payload 檔案,並使用緊湊的後設資料欄位。本章給出完整的位元組佈局、查詢記錄、位分配、列舉和校驗規則,讓你不必自行發明通用字串或 payload 格式就能解碼這些值。
帶型別的 Payload 檔案#
本格式沒有定義共享的 strings.bin、strings.idx 或 strings.hash。 變長位元組由某個帶型別的領域 payload 檔案持有。
TaskPayload — task_payload.bin:
u16 title_len
u8 title_bytes[title_len]
u8 intent_bytes[payload_len - 2 - title_len]
ChangePayload — change_payload.bin:
u8 title_bytes[payload_len]
PatchsetSummaryPayload — patchset_summary_payload.bin:
u8 summary_bytes[summary_len]
SnapshotPayload — snapshot_payload.bin:
u16 message_len
u8 message_bytes[message_len]
u8 line_name_bytes[payload_len - 2 - message_len]
TagPayload — tag_payload.bin:
u16 tag_name_len
u8 tag_name_bytes[tag_name_len]
u8 message_bytes[payload_len - 2 - tag_name_len]SnapshotLinkPayload — snapshot_link_payload.bin:
u16 worktree_name_len
u16 line_name_len
u16 task_id_len
u16 change_id_len
u16 author_mode_len
u8 worktree_name_bytes[worktree_name_len]
u8 line_name_bytes[line_name_len]
u8 task_id_bytes[task_id_len]
u8 change_id_bytes[change_id_len]
u8 author_mode_bytes[author_mode_len]
u8 model_name_bytes[
payload_len - 10 - worktree_name_len - line_name_len - task_id_len
- change_id_len - author_mode_len
]ActorPayload — actor_payload.bin:
u8 user_name_len
u8 user_id_len
u8 email_len
u8 user_name_bytes[user_name_len]
u8 user_id_bytes[user_id_len]
u8 email_bytes[email_len]
u8 memo_bytes[payload_len - 3 - user_name_len - user_id_len - email_len]
ReviewPayload — review_payload.bin:
u8 message_bytes[payload_len]
WaiverPayload — waiver_payload.bin:
u8 reason_bytes[payload_len]
PlanPayload — plan_payload.bin:
u8 title_bytes[payload_len]PlanRevisionPayload — plan_revision_payload.bin:
u16 title_snapshot_len
u16 summary_len
u16 artifact_path_len
u16 artifact_selector_len
u16 artifact_heading_len
u8 title_snapshot_bytes[title_snapshot_len]
u8 summary_bytes[summary_len]
u8 artifact_path_bytes[artifact_path_len]
u8 artifact_selector_bytes[artifact_selector_len]
u8 artifact_heading_bytes[artifact_heading_len]
u8 artifact_blob_id_bytes[
payload_len - 10 - title_snapshot_len - summary_len - artifact_path_len
- artifact_selector_len - artifact_heading_len
]PlanItemPayload — plan_item_payload.bin:
u16 plan_item_ref_len
u16 text_len
u8 plan_item_ref_bytes[plan_item_ref_len]
u8 text_bytes[text_len]
u8 heading_path_bytes[payload_len - 4 - plan_item_ref_len - text_len]GitRepositoryPayload — git_repository_payload.bin:
u8 identity_bytes[identity_len]
GitIdentityPayload — git_identity_payload.bin:
u32 raw_len
u32 name_len
u8 raw_identity_bytes[raw_len]
u8 name_bytes[name_len]
u8 email_bytes[payload_len - 8 - raw_len - name_len]
GitCommitMappingPayload — git_commit_mapping_payload.bin:
u32 message_len
u8 message_bytes[message_len]
u8 raw_commit_bytes[payload_len - 4 - message_len]
GitFileMappingPayload — git_file_mapping_payload.bin:
u8 path_bytes[path_len]
GitRefMappingPayload — git_ref_mapping_payload.bin:
u8 ref_name_bytes[ref_name_len]
GitTagMappingPayload — git_tag_mapping_payload.bin:
u32 message_len
u8 message_bytes[message_len]
u8 raw_tag_bytes[payload_len - 4 - message_len]heading_path_bytes 需要一種由 schema 定義的穩定編碼。佈局 v0 沒有 選定新的規範表示。因此寫入方必須保留已被接納的 layout-1 編碼, 否則就要 fail closed。
單欄位 payload 不會重複內層長度。它們的長度來自所屬記錄的 payload_len,只有 Patchset summary 例外,用的是 summary_len。多欄位 payload 為除最後一個之外的每個變長欄位儲存長度; 最後一個欄位的長度由所屬記錄的 payload_len 推導得出。下溢、必填文字欄位 為空,以及宣告為 UTF-8 的欄位中出現非法 UTF-8,都會被拒絕。明確宣告為 不透明 Git 位元組的欄位不做 UTF-8 解碼。
Actor、Task、Change、Snapshot、Snapshot Link、Tag、Review、Waiver 以及 Plan 家族的記錄使用 u16 payload_len,因此單個 payload 上限為 65535 位元組。 Patchset summary 使用 u16 summary_len,要求 1..65535 位元組,上界相同, 但並不因此變成通用的 Patchset payload。 Actor 各組成部分的長度和 Tree 路徑段長度使用 u8,因此各自上限為 255 位元組。 Git identity、commit 和 Tag 對映 payload 使用 u32 payload_len;Git repository identity、檔案路徑和 ref 名稱長度同樣是 u32。超出 u32 的值在寫入之前就會被拒絕。line_name_payload.bin、 tree_name_payload.bin 以及可選的 snapshot_path_payload.bin 存放所屬記錄 歸一化後的 UTF-8 位元組。
在目前命令契約下,AIT Tag 名稱/訊息、Git repository identity、Git identity 各組成部分、Git 檔案路徑和 Git ref 名稱必須是合法 UTF-8。Git commit 訊息、 原始 commit、Git Tag 訊息以及帶註解 Tag 的原始位元組都是有長度上界的不透明 位元組,在 Binary DB 中絕不做 Base64 編碼。由 AIT 生成的 identity 可以用 raw_len = 0;從 Git 保留下來的 identity 必須保留其原始位元組。輕量 Git Tag 的原始 Tag 位元組為空。
Attestation、Policy Decision 和 Land 記錄不持有 payload 檔案。Patchset 只持有 patchset_summary_payload.bin;patchset_payload.bin 不是 v0 的檔案。
可重建索引#
.idx 檔案是查詢加速器,絕不是身份或權威。它們可以缺失,也可以重建。 命中只有在比對過所引用的權威記錄或 payload 位元組之後才被接受。持久化的行 先按查詢鍵位元組排序,再按目標索引排序。
SNAPSHOT_ID_INDEX_RECORD_SIZE = 12
SnapshotIdIndexRecord — snapshot_id.idx:
u64 snapshot_hash48
u32 content_snapshot_index_plus1
SNAPSHOT_PARENT_CHILD_INDEX_RECORD_SIZE = 8
SnapshotParentChildIndexRecord — snapshot_parent_child.idx:
u32 child_snapshot_index
u32 parent_edge_index_plus1
TREE_ID_INDEX_RECORD_SIZE = 14
TreeIdIndexRecord — tree_id.idx:
u8 tree_hash80[10]
u32 tree_index_plus1
TREE_PACK_ID_INDEX_RECORD_SIZE = 12
TreePackIdIndexRecord — tree_pack_id.idx:
u64 pack_hash48
u32 tree_pack_index_plus1BLOB_ID_INDEX_RECORD_SIZE = 14
BlobIdIndexRecord — blob_id.idx:
u8 blob_hash80[10]
u32 blob_index_plus1
OBJECT_PACK_ID_INDEX_RECORD_SIZE = 12
ObjectPackIdIndexRecord — object_pack_id.idx:
u64 pack_hash48
u32 object_pack_index_plus1
MANIFEST_HASH_INDEX_RECORD_SIZE = 36
ManifestHashIndexRecord — manifest_hash.idx:
u8 manifest_hash[32]
u32 content_snapshot_index_plus1ACTOR_LOOKUP_INDEX_RECORD_SIZE = 12
ActorLookupIndexRecord — actor_lookup.idx:
u64 actor_key_hash
u32 actor_index_plus1
LINE_NAME_INDEX_RECORD_SIZE = 12
LineNameIndexRecord — line_name.idx:
u64 line_name_hash64
u32 line_index
TAG_NAME_INDEX_RECORD_SIZE = 12
TagNameIndexRecord — tag_name.idx:
u64 tag_name_hash64
u32 tag_indexGIT_REPOSITORY_FINGERPRINT_INDEX_RECORD_SIZE = 16
GitRepositoryFingerprintIndexRecord — git_repository_fingerprint.idx:
u8 fingerprint96[12]
u32 repository_index_plus1
GIT_GENERATION_ID_INDEX_RECORD_SIZE = 12
GitGenerationIdIndexRecord — git_generation_id.idx:
u8 generation_hash64[8]
u32 generation_index_plus1
GIT_COMMIT_OBJECT_INDEX_RECORD_SIZE = 28
GitCommitObjectIndexRecord — git_commit_object.idx:
u32 generation_index
u8 git_object_id[20]
u32 commit_mapping_index_plus1
GIT_COMMIT_SNAPSHOT_INDEX_RECORD_SIZE = 8
GitCommitSnapshotIndexRecord — git_commit_snapshot.idx:
u32 snapshot_index
u32 commit_mapping_index_plus1GIT_REF_LOOKUP_INDEX_RECORD_SIZE = 16
GitRefLookupIndexRecord — git_ref_lookup.idx:
u32 repository_index
u64 ref_name_hash64
u32 ref_mapping_index_plus1
GIT_TAG_REF_INDEX_RECORD_SIZE = 8
GitTagRefIndexRecord — git_tag_ref.idx:
u32 git_ref_mapping_index
u32 git_tag_mapping_index_plus1
GIT_OPERATION_ID_INDEX_RECORD_SIZE = 12
GitOperationIdIndexRecord — git_operation_id.idx:
u8 operation_hash64[8]
u32 checkpoint_index_plus1Snapshot 父子鍵允許出現重複候選,並按升序傳回邊索引;權威的邊序號在查詢 之後再做校驗。Git ref 查詢使用匯入源 repository 索引或匯出目標 repository 索引。Tag 名稱和 Git ref 名稱的雜湊命中,只有在做過精確的帶型別 payload 比對之後才被接受。按 Snapshot 查 commit 可能同時傳回匯入和匯出候選;由 generation 方向、對映標誌位、物件格式和記錄順序共同決定 landed 優先順序—— 未改動的匯入優先於確定性匯出。
Plan Item 的 ref 透過某個 revision 的條目區間加精確 payload 比對來解析。 佈局 v0 沒有定義持久化的 Plan Item ref 雜湊索引。
後設資料編碼#
下面未分配的所有位和值都是保留的,必須寫為零。
TaskRecord.task_meta:
bit 0 planned
bit 1 snapshotted
bit 2 review_pending
bit 3 validation_pending
bit 4 blocked
bit 5 ready_to_land
bit 6 completed
bit 7 canceled
LocalTaskRecord.local_meta:
bit 0 published
bit 1 abandoned
bit 2 later_promotion_excluded
Remote task/change/mirror remote_meta:
bit 0 tombstone
bit 1 partial
bit 2 conflict
bit 3 staleChangeRecord.change_meta:
bits 0..1 lifecycle: 00 draft, 01 active, 10 landed, 11 archived
bit 2 has_patchsets
bit 3 review_pending
bit 4 validation_pending
bit 5 ready_to_land
bit 6 blocked
bit 7 superseded; valid only with lifecycle 11
ChangeRecord.change_state:
bit 0 canceled; valid only with lifecycle 11
bits 1..7 reserved = 0
LocalChangeRecord.local_meta:
bit 0 published
WorktreeCursorRecord.cursor_meta:
bit 0 has_selected_change
bit 1 has_pending_pre_land_target_snapshot
bit 2 has_pending_landed_snapshot對於 Local Change,local_meta 的 bit 0 和 published_remote_change_ordinal_plus1 遵守 Change 記錄一節裡的存在性與 所屬 Task 不變式。這個四位元組的發布槽位絕不存放全域性 Remote Change 索引。
LineRecord.line_meta:
bit 0 archived
bit 1 tombstone
TagRecord.tag_meta:
bit 7 tombstone
StashRecord.stash_meta:
bit 0 workspace_cleared
bit 7 tombstone
LandRecord.land_meta:
bits 0..2 status_kind:
000 queued
001 running
010 succeeded
011 blocked
100 failed
101 canceled
110 updating
111 reserved
bit 3 has_pre_land_target_snapshot
bit 4 has_landed_snapshot
bits 5..6 mode_kind:
00 direct
01 merge
10 ff_only
11 reserved
bit 7 tombstone
LandRecord.failure_kind:
0 none
1 base_stale
2 policy_blocked
3 review_blocked
4 ci_blocked
5 conflict
6 target_update_failed
7 internal_errorContentSnapshotRecord.snapshot_meta:
bits 0..1 snapshot_kind: 00 line, 01 stash
bit 2 has_message
bit 3 has_line_name_payload
bit 4 parent_edges_authority
bit 5 has_root_locator
bit 7 tombstone
ContentSnapshotRecord.history_flags:
bit 0 remote_head_history_boundary
bits 1..7 reserved = 0
SnapshotLinkRecord.link_meta:
bit 0 has_change
bit 1 has_session
bit 2 has_checkpoint
bit 3 has_worktree_name
bit 4 has_line_name
bit 5 has_author_or_model
bit 7 tombstoneGitRepositoryRecord.repository_meta bits 0..1:
00 Git import source; public prefix GSR
01 Git export target; public prefix GTR
10 AIT export source; public prefix ASR
11 reserved
GitRepositoryRecord.object_format_kind:
0 not_applicable for an AIT repository
1 sha1
GitGenerationRecord.generation_meta bits 0..1:
00 import; public prefix GIT-IMP
01 export; public prefix GIT-EXP
10..11 reserved
GitIdentityRecord.identity_meta:
bit 0 has_raw_identity
GitCommitMappingRecord.mapping_meta:
bit 0 signed
bit 1 imported_unchanged
bit 2 deterministicGitRefMappingRecord.ref_meta:
bits 0..1 ref_kind: 00 branch, 01 tag, 10 symbolic_ref, 11 reserved
bit 2 has_snapshot
bit 3 has_target
bit 4 has_expected_previous_git_object_id
GitTagMappingRecord.tag_mapping_meta:
bit 0 signed
bit 1 deterministic
bit 2 has_raw_tag
GitOperationCheckpointRecord.checkpoint_meta bits 0..1:
00 running
01 completed
10..11 reserved
Git git_object_type_kind:
0 commit
1 tree
2 blob
3 tagPlanRecord.plan_meta:
bits 0..1 plan_state: 00 draft, 01 archived, 10 superseded
bit 2 published
bit 3 stale
bit 4 conflict
bit 5 tombstone
PlanRevisionRecord.revision_meta:
bit 0 published
bit 1 stale
bit 2 conflict
bit 3 has_items
bit 4 tombstone
PlanItemRecord.item_meta:
bits 0..1 checkbox_state: 00 none, 01 open, 10 done
bit 2 has_item_ref
bit 3 taskableTreePackRecord.pack_meta:
bit 0 ready
bit 1 corrupt
bit 2 sparse_physical_ordinals
bit 7 tombstone
TreePackRecord.pack_format_kind:
0 zip_deflate_tree_v1
1 zstd_chunked_tree_v1
TreeRecord.tree_meta:
bit 7 tombstone
TreeEntryRecord.entry_meta bits 0..1:
00 blob
01 treeObjectPackRecord.pack_meta:
bit 0 ready
bit 1 corrupt
bit 2 pruned
bit 7 tombstone
ObjectPackRecord.pack_format_kind:
0 zip_deflate_v2
1 zstd_chunked_v1
ObjectPackMemberRecord.member_meta:
bits 0..1 entry_kind: 00 full, 01 delta
bits 2..3 compression_kind: 00 none, 01 deflate, 10 zstd
bit 7 tombstone
BlobRecord.blob_meta:
bit 0 has_pack_member
bit 1 pruned
bit 7 tombstone
BlobRecord.hash_kind:
0 sha256PatchsetRecord.patchset_meta:
bit 0 withdrawn
bit 1 invalidated
bits 2..4 author_mode_kind:
000 human_only
001 human_with_ai_assist
010 ai_with_human_review
011 ai_only_experimental
100 agent (legacy conversion only)
101 codex (legacy conversion only)
110 xhigh (legacy conversion only)
111 reserved
bits 5..6 publish_state_kind:
00 published
01 reserved
10 superseded
11 reserved
bit 7 evaluation_pending
AttestationRecord.attest_meta:
bits 0..1 verification_state: 00 unknown, 01 pending, 10 pass, 11 fail
bit 2 revoked
bit 3 require_tests_pass
bit 4 require_human_review
bit 5 require_lint_pass
bit 6 ci_backed
bit 7 tombstone
ActorRecord.actor_meta:
bits 0..2 actor_kind:
000 user
001 team
010 bot
011 service_account
100 automation
101 unknown
bit 3 has_user_id
bit 4 has_email
bit 5 has_memo
bit 7 tombstone原生 v0 的 Patchset 寫入方只會寫出四種非遺留的 author mode。那三個遺留 編碼存在的唯一目的,是在轉換過程中原樣保留已被接納的源行;無法識別的 author 文字會 fail closed。原生 v0 的 Patchset 寫入方只會寫出 published 或 superseded 發布狀態。遺留源裡的 Patchset 狀態 selected_for_landing 是非權威投影,會歸一化為 published;它絕不會被寫成 01,不會被用來推斷選擇結果,也不允許覆蓋 RemoteChangeRecord.selected_patchset_index_plus1。如果一個有效的源 Change 選中指標與陳舊的 Patchset 投影不一致,以 Change 指標為準,轉換不會僅僅因為 這種投影不一致而失敗。但只要需要源端的選擇結果,缺失、無效或有歧義的源 Change 指標依然會導致失敗。只有當源 Change 指標明確這麼指、並且所有權和 存活規則也全部透過時,選中指標才可以引用 published 或 superseded 的 遺留行。
當 evaluation_pending 置位時,即便存在更早的 Policy Decision,對外暴露的 Patchset evaluation_state 也是 pending。當它清零時,必須有一條最新的、 存活的非 pending Policy Decision,由它提供確切的 pass、soft_fail、 hard_fail 或 waived 值。新建 Patchset,以及任何會讓快取策略失效的 review、attestation、waiver 或策略輸入變更,都會把這一位置位,作為狀態最後 提交的標記;一次完成的非 pending Policy 評估會先追加其決定,再清除該位。
ReviewRecord.review_meta:
bits 0..2 action_kind:
000 request
001 comment
010 approve
011 request_changes
100 dismiss
bit 3 blocking
bit 4 task_lane
bit 5 code_review_summary
bit 6 defer
bit 7 tombstone
PolicyDecisionRecord.policy_meta:
bits 0..2 decision_kind:
000 pending
001 pass
010 soft_fail
011 hard_fail
100 waived
bit 7 tombstone
WaiverRecord.waiver_meta:
bit 0 revoked
bit 7 tombstonePolicyCheckRecord.check_kind:
0 require_attestation
1 ai_provenance
2 code_review_summary
3 tests
4 lint
5 security_scan
6 license_scan
7 required_human_review
8 ci_rollout_phase
9 ci_patchset_suite
PolicyCheckRecord.check_status:
0 absent
1 not_required
2 pending
3 pass
4 hard_fail
5 soft_fail
6 waived
7 optional_fail