Skip to content
zit Artifact [fde673e532]
Login

Artifact [fde673e532]

Artifact fde673e532f00b2eaf3215072602cf2f9413ba89d54704a71a229a76d0bf12f2:


//! Sync Protocol — draft-fossil-sync-protocol-00.
//!
//! Two repositories reconcile a content-addressed artifact set over HTTP. The
//! protocol is client-driven; the server is stateless across rounds, so only
//! the client runs a state machine (Section 3.8).

const std = @import("std");

/// The client's protocol state (Section 3.8). The server reacts to each
/// request independently and has no state machine.
pub const ClientState = enum {
    /// Operation selected; no round sent yet.
    init,
    /// First round of a modern clone: login suppressed, config/uv-hash
    /// deferred, an `error` reply ignored (Sections 8.3, 8.4, 11.1).
    clone_round0,
    /// Steady round loop: authenticated request, reply dispatched, phantom /
    /// send-queue / config / private work advances (Section 3.2).
    exchange,
    /// Clean stop: no continuation condition of Section 3.7 held.
    terminated,
    /// A fatal protocol error ended the sync without convergence.
    aborted,
};

/// The operation a sync round is performing.
pub const Operation = enum { pull, push, sync, clone };

pub const Error = error{ FatalProtocolError, NotAuthorized, NotImplemented };

/// Robustness posture (Section 3.9): conservative in what it sends, strict in
/// what it accepts. An unknown non-`pragma` operator and a malformed content
/// card are fatal; liberality is confined to the four enumerated points.
pub const Client = struct {
    state: ClientState = .init,
    operation: Operation = .sync,

    /// Drive one request/reply round, returning the next state. Not yet
    /// implemented — see Section 3.2 (dispatch) and Section 3.7 (termination).
    pub fn step(self: *Client) Error!ClientState {
        _ = self;
        return Error.NotImplemented;
    }
};

test "client starts in init" {
    const c: Client = .{};
    try std.testing.expectEqual(ClientState.init, c.state);
}