Writer 하나, View 둘
engine 하나가 lifecycle mutation 전부를 소유하면 concurrency 를 다룰 만해져. CLI 와 UI 는 intention 을 제출하지 event file 을 append 하거나 database row 를 직접 고치지 않아. writer 가 current state 하나에 맞서 claim, stage, review, pipeline, landing transition 을 serialize 해.
append-only record 와 SQLite 는 다른 일을 해. event stream 은 무슨 일이 어떤 순서로 있었는지 ground truth 야. SQLite 는 빠른 query 용으로 current row 와 relationship 을 project 하고. 둘을 independent writer 로 취급하면 workshop 안에서 audit 할 수 없는 reconciliation 문제가 생겨.
mirror 는 rebuild 가능해야 해. 빈 database 에서 시작해 canonical event 와 durable declaration 을 replay 하고 같은 current state 를 복구해. 이 시험이 event 나 canonical source 없이 ad hoc SQL update 로 들어온 hidden state 를 드러내.
운영 중 mirror 가 lag 하거나 repair 가 필요할 수 있어. health 는 그 상태를 명시적으로 보고해야 해. 안전한 반응은 truth 에서 rebuild 또는 reconcile 하는 거지, 원래 history 가 달랐던 척하는 compensating event 를 쓰는 게 아니야.
빠르게 query 하고 영원히 설명해
queue screen, count, join 에는 SQLite 를 쓰고 왜 state 가 생겼는지 답할 때 event stream 을 써. projection 은 read 를 최적화하면서 두 번째 authority 가 되지 않아.
periodic rebuild test 는 disaster recovery 이상이야. 의미 있는 mutation 마다 canonical representation 하나가 있다는 architecture test 야.