--- id: wiki-2026-0508-reconciliation title: Reconciliation category: 10_Wiki/Topics status: verified canonical_id: self aliases: [Data Reconciliation, Conflict Resolution, CRDT] duplicate_of: none source_trust_level: A confidence_score: 0.9 verification_status: applied tags: [reconciliation, crdt, distributed, finance, sync] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: typescript framework: yjs --- # Reconciliation ## 매 한 줄 > **"매 두 source 의 truth 의 align"**. Reconciliation 의 financial (ledger ↔ bank statement match), data (master ↔ replica), distributed (CRDT conflict-free merge), AI (multi-agent state sync) 의 cross-domain pattern. 2026 의 local-first software 의 CRDT renaissance. ## 매 핵심 ### 매 Financial reconciliation - **3-way match**: PO ↔ receipt ↔ invoice. - **Bank rec**: GL ↔ bank statement 의 daily. - **Sub-ledger to GL**: AR/AP detail 의 control account match. - **2026 tools**: BlackLine, FloQast, AI-driven (Trullion). ### 매 Data reconciliation - **CDC (Change Data Capture)**: Debezium, source-of-truth log. - **Lambda architecture**: batch + stream — 매 reconcile 의 daily. - **Idempotency**: 매 retry 의 safe — UUID dedup. - **Checksum**: row-count + hash 의 source vs target. ### 매 CRDT (Conflict-free Replicated Data Type) - **G-Counter**: grow-only counter (sum across replicas). - **PN-Counter**: increment + decrement. - **OR-Set**: observed-remove set — add wins. - **LWW-Register**: last-write-wins by timestamp. - **RGA / Yjs Y.Text**: collaborative text. - **Automerge**: JSON CRDT, local-first. ### 매 Modern distributed - **Operational Transform (OT)**: Google Docs 의 legacy. Server-coord. - **CRDT**: Notion, Linear, Figma (mixed). P2P-friendly. - **Vector clocks**: causal ordering. - **Hybrid Logical Clock (HLC)**: physical + logical — CockroachDB. ### 매 응용 1. Collaborative editing (Yjs, Automerge). 2. Offline-first mobile app sync. 3. Multi-region database (DynamoDB Global, Cosmos DB). 4. Bank ledger reconciliation. 5. Multi-agent LLM shared scratchpad. ## 💻 패턴 ### Yjs collaborative text (TypeScript) ```typescript import * as Y from "yjs"; import { WebsocketProvider } from "y-websocket"; const doc = new Y.Doc(); const provider = new WebsocketProvider("wss://sync.example.com", "room-1", doc); const text = doc.getText("content"); text.observe(event => console.log("delta:", event.delta)); text.insert(0, "Hello "); // 매 다른 client 의 concurrent insert 의 auto-merge ``` ### Automerge JSON CRDT ```typescript import * as Automerge from "@automerge/automerge"; let doc1 = Automerge.from({ tasks: [] as string[] }); let doc2 = Automerge.clone(doc1); doc1 = Automerge.change(doc1, d => d.tasks.push("write spec")); doc2 = Automerge.change(doc2, d => d.tasks.push("review code")); const merged = Automerge.merge(doc1, doc2); // merged.tasks == ["write spec", "review code"] — 매 conflict X ``` ### G-Counter (CRDT) ```python class GCounter: def __init__(self, node_id: str): self.node = node_id self.counts: dict[str, int] = {} def inc(self, n: int = 1): self.counts[self.node] = self.counts.get(self.node, 0) + n def value(self) -> int: return sum(self.counts.values()) def merge(self, other: "GCounter"): for k, v in other.counts.items(): self.counts[k] = max(self.counts.get(k, 0), v) ``` ### Bank reconciliation pseudo ```python def reconcile(gl: list[Txn], bank: list[Txn]) -> dict: matched, gl_only, bank_only = [], [], [] bank_idx = {(t.amount, t.date): t for t in bank} for g in gl: key = (g.amount, g.date) if key in bank_idx: matched.append((g, bank_idx.pop(key))) else: gl_only.append(g) bank_only = list(bank_idx.values()) return {"matched": matched, "gl_only": gl_only, "bank_only": bank_only} ``` ### Idempotent upsert (Postgres) ```sql INSERT INTO orders (id, amount, status) VALUES ($1, $2, $3) ON CONFLICT (id) DO UPDATE SET amount = EXCLUDED.amount, status = EXCLUDED.status, updated_at = NOW(); ``` ### CDC with Debezium (Kafka Connect) ```json { "name": "pg-source", "config": { "connector.class": "io.debezium.connector.postgresql.PostgresConnector", "database.hostname": "db", "database.dbname": "app", "plugin.name": "pgoutput", "topic.prefix": "app", "table.include.list": "public.orders,public.payments" } } ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | Real-time collab text | Yjs (mature, fast) | | Offline-first app | Automerge (rich JSON) | | Counter across regions | PN-Counter / G-Counter | | Centralized server OK | OT (simpler) or CRDT | | Bank/finance | Manual + AI-assist (BlackLine) | | DB replica sync | CDC (Debezium) + idempotency | **기본값**: Yjs 의 collab text, Automerge 의 structured offline-first, CDC 의 enterprise data sync. ## 🔗 Graph - 부모: [[Distributed-Systems]] · [[Data-Engineering]] - 변형: [[CRDT]] - 응용: [[Local-First]] - Adjacent: [[Eventual Consistency]] · [[CDC]] · [[Idempotency]] ## 🤖 LLM 활용 **언제**: 매 reconciliation rule 의 fuzzy match (description, amount tolerance), exception explanation, audit trail summary. **언제 X**: deterministic match (use SQL JOIN), regulated final attestation (human sign-off). ## ❌ 안티패턴 - **OT 의 P2P 의 force**: 매 OT 의 server 의 require — P2P 의 CRDT 의 use. - **LWW 의 collab text**: 매 char-level loss — RGA / Yjs 의 use. - **No vector clock 의 causal**: 매 wall-clock skew → wrong order. - **No idempotency key**: retry 의 duplicate → double charge. - **Reconcile manually 매 day**: automate w/ exception queue. ## 🧪 검증 / 중복 - Verified (Yjs docs, Automerge paper, Shapiro CRDT survey 2011, Debezium docs). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — finance + CRDT + data sync unified |