merge(478): WebSocket CRDT sync layer (manual squash from feature/story-478)
Manual squash-merge of feature/story-478_… into master after the in-pipeline mergemaster runs failed silently. The 478 agent did substantial real work across multiple respawn cycles before being interrupted; commits on the feature branch were intact and verified high-quality but never merged via the normal pipeline path due to compounding bugs: - The first mergemaster attempt ran ($0.82 in tokens) and exited "Done" cleanly but didn't push anything to master — likely the worktree was briefly on master rather than the feature branch when the merge_agent_work MCP tool ran, so it found nothing to merge. - Subsequent timer fires defaulted to spawning coders instead of resuming mergemaster, burning more tokens for no progress. - Bug 510 (split-brain shadows yanking done stories back to current) and bug 501 (timers don't cancel on stop/completion) compounded the cost. What this commit lands: - server/src/crdt_sync.rs (new, ~518 lines): GET /crdt-sync WebSocket handler that subscribes to locally-applied SignedOps and streams them as binary frames. Per-peer bounded queue (256 ops) drops slow peers. - server/src/crdt_state.rs: new public functions subscribe_ops(), all_ops_json(), apply_remote_op() backing the sync handler. Adds the CRDT_OP_TX broadcast channel (capacity 1024). - server/src/main.rs: wires up the sync subsystem at startup. - server/src/http/mod.rs: registers the new endpoint. - server/src/config.rs: adds optional rendezvous field for outbound peers. - server/src/worktree.rs: minor changes from the original branch. - server/Cargo.toml: cfg lint suppression for CrdtNode derive. - crates/bft-json-crdt/src/debug.rs: fix unused-variable warnings. Resolved a trivial test-mod merge conflict in crdt_state.rs (both 478 and 503 added new tests at the end of the test module — kept both sets). Note: this is the squash of the original 478 work that the user explicitly authorized landing. The earlier rogue commit ac9f3ecf — which added a DIFFERENT, broken implementation of the same feature directly to master under the user's identity without consent — was reverted earlier in this session. The forensic tags rogue-commit-2026-04-09-ac9f3ecf and pre-502-reset-2026-04-09 still exist for incident audit. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -191,7 +191,7 @@ impl<T> ListCrdt<T>
|
||||
where
|
||||
T: CrdtNode,
|
||||
{
|
||||
pub fn log_ops(&self, highlight: Option<OpId>) {
|
||||
pub fn log_ops(&self, _highlight: Option<OpId>) {
|
||||
#[cfg(feature = "logging-list")]
|
||||
{
|
||||
let mut lines = Vec::<String>::new();
|
||||
@@ -242,7 +242,7 @@ where
|
||||
|
||||
let cur_char = if is_last(op) { "╰─" } else { "├─" };
|
||||
let prefixes = stack.iter().map(|s| s.1).collect::<Vec<_>>().join("");
|
||||
let highlight_text = if highlight.is_some() && highlight.unwrap() == op.id {
|
||||
let highlight_text = if _highlight.is_some() && _highlight.unwrap() == op.id {
|
||||
if op.is_deleted {
|
||||
"<- deleted".bold().red()
|
||||
} else {
|
||||
@@ -289,27 +289,27 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub fn log_apply(&self, op: &Op<T>) {
|
||||
pub fn log_apply(&self, _op: &Op<T>) {
|
||||
#[cfg(feature = "logging-list")]
|
||||
{
|
||||
if op.is_deleted {
|
||||
if _op.is_deleted {
|
||||
println!(
|
||||
"{} Performing a delete of {}@{}",
|
||||
display_author(self.our_id),
|
||||
display_op_id(op),
|
||||
op.sequence_num(),
|
||||
display_op_id(_op),
|
||||
_op.sequence_num(),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(content) = op.content.as_ref() {
|
||||
if let Some(content) = _op.content.as_ref() {
|
||||
println!(
|
||||
"{} Performing an insert of {}@{}: '{}' after {}",
|
||||
display_author(self.our_id),
|
||||
display_op_id(op),
|
||||
op.sequence_num(),
|
||||
display_op_id(_op),
|
||||
_op.sequence_num(),
|
||||
content.hash(),
|
||||
display_op_id(op)
|
||||
display_op_id(_op)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user