본문 바로가기
C.W.K.
Stream
Lesson 01 of 05 · published

기억을 바꾸는 문은 하나

~12 min · write-path, atomicity, permissions, provenance

Level 0흔적
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete

버튼마다 writer를 만들지 마

inline editor는 save endpoint, restore는 history endpoint, delegation은 apply endpoint를 따로 만들기 쉬워. 처음엔 각 기능이 독립적이라 깔끔해 보이지만 시간이 지나면 한 경로만 permission check가 오래되고 다른 경로는 ledger trailer를 빼먹어.

memory source에 닿는 마지막 함수는 하나여야 해. caller는 intent와 actor와 expected hash와 proposed bytes를 넘기고, canonical writer가 scope, permission, stale state, atomic replacement, ledger, reindex를 순서대로 수행해.

검사 순서도 계약이야

permission을 write 뒤에 검사하거나 ledger commit이 실패한 뒤 source만 남으면 invariant가 깨져. validate target, authorize actor, compare base, prepare temp, atomic replace, semantic commit, reindex trigger라는 ordering이 필요해.

모든 단계를 하나의 database transaction에 넣을 수는 없어. filesystem과 Git과 index는 서로 다른 시스템이야. 그래서 failure state와 repair strategy가 중요하다. source write가 성공하고 ledger가 실패하면 write를 숨기지 말고 uncompensated state로 기록해 다음 sweep가 plant commit을 만들게 해.

atomic replace는 중간 bytes를 숨겨

파일을 in-place로 길게 쓰면 watcher와 editor가 절반짜리 내용을 읽을 수 있어. 같은 filesystem에 temp를 만들고 fsync한 뒤 replace하면 reader는 old 또는 new 전체만 본다.

frontmatter와 body를 따로 write하지도 마. memory fragment가 논리적으로 한 문서라면 validation된 전체 bytes를 한 번에 바꿔야 해. partial field update API도 마지막엔 완전한 document를 조립해 replace한다.

idempotency key가 재시도를 지켜

client timeout 뒤 같은 request를 재전송할 수 있어. operation id와 proposed hash를 기록하면 이미 성공한 mutation을 다시 commit하지 않고 기존 result를 돌려줄 수 있어.

단 actor와 target이 다른 request가 같은 content hash를 가졌다고 합치면 안 돼. idempotency identity는 intent boundary를 포함해야 하고, expiry 뒤 재사용도 거부해야 audit가 정확해.

여러 기능이 같은 source를 바꾸면 마지막 문 하나가 invariant를 소유해야 해. entry point마다 safety를 복사하지 말고 intent만 다르게 넘겨.

Code

canonical writer의 ordering 뼈대·python
def mediated_write(target, proposed, actor, expected_hash):
    assert target.endswith(".md")
    assert actor in {"dad", "pippa"}
    current_hash = "base123"
    if current_hash != expected_hash:
        raise RuntimeError("stale source")
    # atomic_replace(target, proposed)
    # append_semantic_ledger(actor, target, proposed)
    # enqueue_reindex(target)
    return {"status": "written", "actor": actor}

assert mediated_write("memory/a.md", "new", "dad", "base123")["status"] == "written"

External links

Exercise

source mutation endpoint를 전부 찾아 마지막 filesystem write 함수까지 call graph를 그려. canonical path를 우회하는 writer를 제거하고 intent parameter로 합쳐.
Hint
restore, import, migration, admin repair가 흔한 비밀 writer야.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.