//! Stable terminal outcomes for automated Git import callers.
//! Diagnostics remain on stderr. Unknown publication state is explicit; a
//! nonzero exit alone never authorizes rollback or another history fetch.
const std = @import("std");
pub const Outcome = enum {
changed,
unchanged,
refused,
insufficient_history,
busy,
recovery_required,
committed_uncertain,
recovered_changed,
recovered_unchanged,
};
pub const Retry = enum { none, deepen, later, recover };
pub const Durability = enum { not_committed, durable, uncertain };
pub const Result = struct {
schema_version: u8 = 1,
outcome: Outcome = .refused,
reason: []const u8 = "preflight_failed",
changed: ?bool = false,
committed: ?bool = false,
durability: Durability = .not_committed,
retry: Retry = .none,
added_checkins: ?usize = null,
pub fn refuse(self: *Result, reason: []const u8) void {
self.* = .{ .reason = reason };
}
pub fn success(self: *Result, changed: bool, count: ?usize) void {
self.* = .{
.outcome = if (changed) .changed else .unchanged,
.reason = "ok",
.changed = changed,
.committed = true,
.durability = .durable,
.added_checkins = count,
};
}
pub fn pending(self: *Result, reason: []const u8) void {
self.* = .{
.outcome = .recovery_required,
.reason = reason,
.changed = null,
.committed = null,
.durability = .uncertain,
.retry = .recover,
};
}
pub fn write(self: Result, out: *std.Io.Writer) !void {
try std.json.Stringify.value(self, .{}, out);
try out.writeByte('\n');
}
};
test "import result keeps uncertainty distinct from unchanged refusal" {
var result: Result = .{};
result.pending("publication_interrupted");
try std.testing.expect(result.changed == null);
try std.testing.expect(result.committed == null);
try std.testing.expectEqual(Retry.recover, result.retry);
result.refuse("map_stale");
try std.testing.expectEqual(false, result.changed.?);
try std.testing.expectEqual(Retry.none, result.retry);
result.success(true, 0);
try std.testing.expect(result.changed.?);
try std.testing.expectEqual(@as(usize, 0), result.added_checkins.?);
}