|
|
… |
1 unchanged lines |
| 2 |
2 |
|
|
| 3 |
3 |
|
| | | |
| 4 |
4 |
|
|---|---| |
| 5 |
|
- |
| **Status** | Draft 0.4 | |
|
5 |
+ |
| **Status** | Draft 0.4b | |
| 6 |
6 |
|
| **Format version** | 1 | |
| 7 |
7 |
|
| **Date** | 2026-09-26 | |
| 8 |
8 |
|
| **Audience** | Implementers, security reviewers, and contributors | |
|
|
… |
162 unchanged lines |
| 171 |
171 |
|
|
| 172 |
172 |
|
Adding a signature, re-signing, or attaching a seal (§14.4) therefore never changes an ObjectRef. |
| 173 |
173 |
|
|
|
174 |
+ |
### 5.5 Encoding conventions |
|
175 |
+ |
|
|
176 |
+ |
The field tables in this document give each map key in brackets. Where a structure is a choice between variants, or a compact reference, the following encodings apply: |
|
177 |
+ |
|
|
178 |
+ |
| Item | Encoding | |
|
179 |
+ |
|---|---| |
|
180 |
+ |
| `TreeOp` | Map with key 0 = variant tag: 0 `AddNode`, 1 `RemoveNode`, 2 `Move`, 3 `SetMode`; key 1 = node id; `AddNode` adds 2 kind, 3 mode, 4 parent, 5 name; `RemoveNode` adds 2 placement ref; `Move` adds 2 old placement ref, 4 parent, 5 name; `SetMode` adds 2 old mode ref, 3 mode. | |
|
181 |
+ |
| `Edit` | Map with key 0 = variant tag: 0 `Insert`, 1 `Delete`, 2 `Replace`; key 1 = node id; `Insert` adds 2 after, 3 before, 4 lines (array of byte strings) or 5 `lines_blob`; `Delete` adds 2 atom ranges; `Replace` adds 2 old (bytes or null), 3 new (bytes or null). | |
|
182 |
+ |
| `NodeKind` | Unsigned integer: 0 file, 1 dir, 2 symlink. | |
|
183 |
+ |
| `Mode` | Unsigned integer bit field: bit 0 executable, bit 1 opaque content mode. Directories carry 0. | |
|
184 |
+ |
| `OpRef` (placement or mode reference) | `[bytes(32) change hash, uint index]`; the all-zero hash means this change. | |
|
185 |
+ |
| `AtomRef` | `0` for `START`, `1` for `END`, otherwise `[bytes(32) change hash, uint index]` with the all-zero hash meaning this change. | |
|
186 |
+ |
| `AtomRange` | `[bytes(32) change hash, uint from, uint to]`, half-open, non-empty. | |
|
187 |
+ |
| `View` (in `Op`) | Key 0 bookmarks: array of `[text name, [bytes(32) heads]]` sorted by name; key 1 workspaces: array of `[bytes(16) id, bytes(32) change]` sorted by id. Remote and tag namespaces are added in later drafts. | |
|
188 |
+ |
| `Signature` | Map: 0 key id, 1 alg (1 = Ed25519 + ML-DSA-65), 2 Ed25519 bytes(64), 3 ML-DSA-65 bytes(3309). A signature list is a CBOR array of these. | |
|
189 |
+ |
| Secret key file | Map: 0 version, 1 key id, 2 Ed25519 seed bytes(32), 3 ML-DSA-65 seed bytes(32). Kept only in the user's key directory. | |
|
190 |
+ |
|
|
191 |
+ |
Atom indices count the atoms one change introduces for one node, in edit order, across all of that change's `Insert` edits on the node. |
|
192 |
+ |
|
| 174 |
193 |
|
## 6. The change graph |
| 175 |
194 |
|
|
| 176 |
195 |
|
### 6.1 Change object |
|
|
… |
270 unchanged lines |
| 447 |
466 |
|
objects/ |
| 448 |
467 |
|
pack-<id>.pack append-only pack file |
| 449 |
468 |
|
pack-<id>.idx sorted (ObjectRef → offset, length, type) index |
| 450 |
|
- |
loose/ objects written since the last pack |
|
469 |
+ |
loose/ objects written since the last pack, as header || body |
|
470 |
+ |
sigs/ signature lists keyed by the ObjectRef they cover (§5.4) |
| 451 |
471 |
|
ops/ operation objects and op heads |
| 452 |
472 |
|
refs/ current view cache (derived from ops; rebuildable) |
| 453 |
473 |
|
workspaces/<id>/ snapshot cache, fsmonitor cookie |
|
|
… |
321 unchanged lines |
| 775 |
795 |
|
|
| 776 |
796 |
|
--- |
| 777 |
797 |
|
|
| 778 |
|
- |
*Changelog.* Draft 0.4a (2026-09-26): §13.2 pins the FastCDC gear table, rolling hash, and masks so boundaries are identical across implementations. |
|
798 |
+ |
*Changelog.* Draft 0.4b (2026-09-26): §5.5 records the encoding conventions for variants, references, views, signatures, and secret key files; §13.1 adds the signature directory. |
|
799 |
+ |
|
|
800 |
+ |
Draft 0.4a (2026-09-26): §13.2 pins the FastCDC gear table, rolling hash, and masks so boundaries are identical across implementations. |
| 779 |
801 |
|
|
| 780 |
802 |
|
Draft 0.4 (2026-09-26): overview no longer describes the constrained profile by word size; HLC drift bound replaces timestamp-based rejection; node kinds reduced to file, dir, symlink with a separate content mode and defined mode switching; symlinks always opaque; checkout safety rules (§7.7); workspace conflicts (§9.7) replace the case-folding tree conflict and cover normalization, reserved names, and path length; operation log entries suppressed for empty snapshots. |
| 781 |
803 |
|
|
|
|
… |
3 unchanged lines |