feat(role-sync): mirror-mode conflict detection + NATS events (010 PR-4) - #78
Merged
Merged
Conversation
Fourth PR of proposal 010 — the convergence story. In mirror mode
both PR-2 (file → CRD) and PR-3 (CRD → file) run simultaneously, and
this PR adds the small piece that prevents echo loops and surfaces
genuine concurrent-write conflicts.
New module acc/role_sync_conflict.py with ConflictDetector class:
* classify_file_change(role_id, body) returns one of:
- "echo" — matches our last CRD-driven write within the window
- "applied" — genuine operator edit (outside window or no prior
write recorded)
- "conflict" — concurrent edit detected; LWW resolution applied
* record_our_write(role_id, body) is called by the CRD projector
after every file write so the detector can correlate.
* publish_applied / publish_conflict emit NATS events on
<events_subject>.applied / .conflict. Payload is JSON with
role_id, source identifiers, and (for conflicts) the loser snippet
+ RFC3339 timestamp.
* Time source + publisher are both dependency-injected so unit tests
drive scenarios deterministically (no time.sleep, no live NATS).
* Counters (applied/echo/conflict) accumulate for future /metrics
integration.
Test coverage: 12 unit tests covering all three classification
outcomes, per-role isolation, record-replacement semantics, the
applied/conflict event surface (including subject normalisation,
publisher absence, publisher exceptions), and counter increments.
Wiring into RoleCRDProjector deliberately deferred to a tiny
follow-up PR so the classifier is reviewed standalone. The detector
is inert in production builds today.
Total: +458 LOC across 3 files (production ~240 + tests ~190 + docs).
Well under PR-4's 500-LOC budget.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fourth PR of proposal 010 — the convergence story. In
mirrormode both PR-2 (Go-side file → CRD) and PR-3 (Python-side CRD → file) run simultaneously; this PR adds the small piece that prevents echo loops and surfaces genuine concurrent-write conflicts on NATS.New module
acc/role_sync_conflict.pywithConflictDetector:classify_file_change(role_id, body)returns one of:echoconflict_window_s→ ignoreappliedconflictrecord_our_write(role_id, body)called by the projector after every CRD-driven file write.publish_applied/publish_conflictemit on<events_subject>.{applied,conflict}with payload sufficient for an audit log + PR-5's TUI badge.Time source + NATS publisher both dependency-injected, so 12 unit tests drive scenarios deterministically with zero
time.sleepand zero live NATS.Status
Detector is inert in production today. Wiring into
RoleCRDProjectoris deliberately deferred to a tiny follow-up PR so the classifier can be reviewed in isolation. This PR is purely the building block + tests.Test plan
echo/applied/conflict)recordfor alpha doesn't affect beta)acc.role.sync.andacc.role.syncboth work)Diff size
Under PR-4's 500-LOC proposal estimate.
Proposal 010 reference
010 - Bi-directional file-CRD sync for role definitions.md. Status: Signed off 2026-05-14. PR-1 #75 + PR-2 #76 + PR-3 #77 merged.🤖 Generated with Claude Code