Skip to content

Latest commit

 

History

History
84 lines (52 loc) · 7.71 KB

data-model.md

File metadata and controls

84 lines (52 loc) · 7.71 KB

CodeFolderSync V3 data model

The executable contracts are codefoldersync/src/v3/types.ts, the SQLite initialization in state.ts and hub.ts, and the manifest validation in objects.ts and catalog.ts.

Versions

Both schemaVersion and protocolVersion are 3. V1 and V2 configuration, hubs, manifests, and RPC are rejected. V3 uses fresh folder, state, hub, event, and key identities.

Configuration

ProductConfig contains revision, folder identity, local root/state projection, local peer identity, hub, authority public key, enrolled peers and roots, ignore digest, signed synchronization policy, lifecycle, backup witness, service timing, and authority signature. The policy selects default-branch gating or an explicit file allowlist and records plaintext ENV consent.

The authority signature covers portable desired state. The local root must equal the root in that peer's signed record. Targets are saved mode read-only; a changed signed field fails verification and cannot publish.

Namespace manifest

NamespaceManifest contains:

  • folder and ignore identity;
  • sorted recursive catalog entries;
  • sorted repository identity, branch, and HEAD contexts for default-branch scope;
  • a diagnostic creation time;
  • an independently recomputed semantic digest.

A catalog entry contains path, parent path, parent node ID, display and portable name, stable node ID, kind, manifest ID, executable meaning, and local filesystem observations. The synthetic root identity is $root. Manifest validation requires every non-root entry to name an existing directory parent. Device, inode, timestamps, and size are rename/capture hints and are excluded from cross-peer semantic equality.

The semantic digest covers accepted paths, parent identities, stable node IDs, kinds, content manifests, executable meaning, and repository contexts. Selected-file snapshots use an empty repository-context list. Target verification rescans with source node IDs as its accepted identity baseline.

Mutation events

Each signed snapshot carries a monotonically increasing peer sequence and a deterministic ordered mutation list derived from the accepted base and proposed namespace. Mutation kinds are put-node, move-entry, delete-entry, restore-entry, and repository-context. Context mutations bind the repository path, identity, branch, and HEAD versions without transferring Git metadata.

Every mutation records folder, peer, event and node identity; peer sequence; base configuration revision; base and resulting entry/publisher versions; affected paths; and the complete immutable object closure needed for the resulting node. Event history therefore preserves both whole-checkpoint evidence and explicit causal node operations. A restore may reuse a retained tombstoned node ID only when the same path and content version reappear.

Publisher manifests

Every object ID is SHA-256 of exact bytes.

  • A regular manifest records executable meaning, byte length, whole-file digest, and ordered immutable chunks.
  • A symlink manifest records exact target text and its digest.
  • A tree manifest records sorted child name, kind, and manifest. It represents immutable included directory-conflict evidence, never local-only siblings.

Objects are stored in SQLite WITHOUT ROWID tables with WAL and full synchronous commits. Reads always verify their digest.

Local Git context

Git metadata stays local. Snapshots have no Git-boundary list or Git-state mutation, and old Git-boundary snapshots are rejected. Default-branch snapshots record each repository's path, root-commit identity hash, branch, and exact HEAD. Selected-file discovery needs only contained metadata exclusions and does not require a committed or idle checkout. External Git targets remain unsupported. See synchronization policies.

Local SQLite state

Table Purpose
meta Accepted sequence and baseline digest
catalog Rebuildable current stable-node observations
catalog_history Accepted placement/publisher version hashes and tombstones
outbox Exact signed event and object closure pending acknowledgement
held_outbox Previous-context signed events and objects retained without replay
journals Rename, snapshot-apply, adoption, and cutover intent
conflicts Local recovery and visible conflict records

The complete accepted baseline snapshot also lives as owner-only baseline.json so three-way merge can distinguish local, remote, and concurrent change.

With independently suspended repositories, this file retains their previous accepted local entries and contexts while eligible entries advance. The global cursor still names the latest accepted hub event; it does not imply that every suspended scope accepted that event. The derived catalog likewise retains suspended observations.

After a verified Git-context advance, a temporary committed-tree baseline supplies stable node IDs while the actual checkout is captured again. The accepted baseline advances only through normal acceptance. Old-context queued events remain in held_outbox; their objects are not garbage-collected or inserted into the new checkout.

A normal apply journal stores current/desired eligible manifests, the complete hub event's accepted digest and sequence, the recovery and move-staging roots, and its repository scope. Scope names all discovered/enrolled roots, eligible contexts, suspended reasons, and enclosing checkout guards. Child move journals name their apply ID and affected namespace paths. Recovery validates that journal scope and proves the complete accepted digest against hub history before applying its eligible projection.

Changed contexts retain the original transaction as held-snapshot-apply and their move intents as held-move. One SQLite transaction writes retained records and narrows or removes the replayable parent. Status reports heldApplyEntries. Unknown contexts keep their replayable projection pending; completed siblings leave its baselines intact. Retained records and their immutable objects are not automatically removed.

Hub SQLite state

Table Purpose
folders Accepted config revision, sequence, and current snapshot
events Immutable event/barrier identity, payload hash, peer sequence, mutation list, digest and global order
conflicts Fleet-visible retained conflict records
adoption_targets Peer, source generation/digest, and verification time

An event ID retry returns its stored sequence only when the payload hash matches. Changed payload reuse is rejected. A signed normal snapshot includes its explicit mutations and conflict records; the hub inserts its event, current checkpoint, mutation history, and conflicts in one transaction.

Adoption plan

The target-local plan records adoption ID, source sequence/digest, target peer/digest, creation time, sanitized summary, and path classifications inside an AES-256-GCM envelope. Its independent mode-0600 key stays in the target's machine-local key directory. Apply accepts only the exact target and source generations named by that authenticated plan.