Divergence
With persistence enabled (the default when --dir is set and --appendonly is not disabled), moon advances master_repl_offset on every write even though no replica has ever connected. Redis creates the replication backlog lazily — the offset stays 0 until the first replica attaches — so the two disagree on a byte-compared ROLE.
Reproduce
$ moon --port 6492 --shards 4 --dir /tmp/d --disk-free-min-pct 0
$ redis-cli -p 6492 ROLE # fresh
1) "master"
2) (integer) 0
3) (empty array)
$ for i in $(seq 20); do redis-cli -p 6492 SET k$i v; done
$ redis-cli -p 6492 ROLE
1) "master"
2) (integer) 570 <-- redis reports 0 here
$ redis-cli -p 6492 INFO replication | grep master_repl_offset
master_repl_offset:570
Real redis 8.6.1, same writes: master_repl_offset:0 and ROLE → :0.
Note --appendonly no masks it: the offset stays 0, which is why an isolated probe can read as clean.
Impact
Low but observable. Anything that reads the offset as "has this master made progress / is it a fresh master" sees a nonzero value on a standalone master. Both ROLE and INFO replication expose it.
How it surfaced
scripts/test-consistency.sh's ROLE on a master row (added by #471, which derives ROLE from real server state) has been red since it landed — the suite is not part of PR CI, so nothing caught it. Confirmed unrelated to shard routing: the divergence is a counter, reproduces at --shards 1, and my isolated fresh-server probe is byte-identical to redis.
Fix direction
Either gate offset advancement on a backlog/replica actually existing (matching redis's lazy-backlog semantics), or decide the divergence is intended and relax the parity row to compare the role name + replicas array only — but that decision should be explicit, not left as a permanently red assert.
Divergence
With persistence enabled (the default when
--diris set and--appendonlyis not disabled), moon advancesmaster_repl_offseton every write even though no replica has ever connected. Redis creates the replication backlog lazily — the offset stays0until the first replica attaches — so the two disagree on a byte-comparedROLE.Reproduce
Real redis 8.6.1, same writes:
master_repl_offset:0andROLE→:0.Note
--appendonly nomasks it: the offset stays0, which is why an isolated probe can read as clean.Impact
Low but observable. Anything that reads the offset as "has this master made progress / is it a fresh master" sees a nonzero value on a standalone master. Both
ROLEandINFO replicationexpose it.How it surfaced
scripts/test-consistency.sh'sROLE on a masterrow (added by #471, which derives ROLE from real server state) has been red since it landed — the suite is not part of PR CI, so nothing caught it. Confirmed unrelated to shard routing: the divergence is a counter, reproduces at--shards 1, and my isolated fresh-server probe is byte-identical to redis.Fix direction
Either gate offset advancement on a backlog/replica actually existing (matching redis's lazy-backlog semantics), or decide the divergence is intended and relax the parity row to compare the role name + replicas array only — but that decision should be explicit, not left as a permanently red assert.