C.W.K.
Stream
Lesson 05 of 05 · published

불변 플랜

~11 min · immutable-plan, plan-hash, determinism

Level 0Finder 에서 길 잃음
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"돌아가는 동안 편집할 수 있는 플랜은 플랜이 아냐. 소문이야."

플랜이 얼리는 것

OperationPlan 은 의도의 얼린 스냅샷이야. 소스랑 목적지 참조, 기대 리소스 정체성이랑 메타데이터, 충돌 결정, 패키지-그리고-심링크 정책, 그리고 그 전부에 대해 계산된 결정론적 해시를 담아. 한번 생기면 절대 안 바뀌어. 엔진이 그걸 읽고, 저널하고, 실행해 — 근데 엔진 포함 아무것도 돌아가는 동안 제자리에서 편집 안 해.

변경은 새 플랜을 의미해

그럼 현실이 옮겨가면 — 플랜이 예상 못 한 충돌이 나타나거나, 사용자가 결정을 수정하면 — 어떻게 돼? 돌아가는 플랜을 변형 안 해; 그러면 해시가 거짓말이 되고 저널 기록이 무의미해져. 플랜(또는 리비전)을 만들어, 자기 해시랑 자기 저널 정체성을 가진. 옛 플랜은 대체되지, 몰래 다시 쓰이지 않아. 불변성이 '앱이 정확히 뭘 의도했어?' 를 영구적이고 확인 가능한 답을 가진 질문으로 만들어.

해시가 왜 중요해

결정론적 해시가 플랜을 검증 가능한 걸로 바꿔. 저널이 해시를 기록하고; 복구가 재개하는 플랜이 커밋된 플랜과 바이트 단위로 같은지 확인할 수 있어. 같은 의도의 두 실행이 같은 해시를 내니까, 시스템이 짐작 없이 정체성을 알아봐. 얼린 의도 더하기 해시가 복구랑 감사를 최선노력이 아니라 결정론적으로 만드는 거야.

플랜은 불변이고 해시됐어; 바뀌는 조건은 편집이 아니라 새 플랜을 낳아. 얼린 의도 — 소스·목적지·기대 정체성·충돌 결정·정책 — 는 엔진이 실행하고 저널이 기록하는 계약이야. 돌아가는 플랜은 절대 다시 안 쓰여; 리비전은 새 정체성을 가진 새 플랜이야.
트랙 클리어 — 엔진이 지어졌어. 경계 하나, 저널 먼저, 상태 기계, UI 는 변형 못 함, 그리고 불변 해시 플랜. 함께 Track 1 의 논지에 대한 답이야: 이게 '믿을 수 있는 변형' 을 소망 이상으로 만드는 기계 장치야. 앞의 전부 — 복사/검증/삭제, 충돌, 코디네이션, 복구 — 는 이 엔진 위에서 돌아.

Code

불변이고 해시된 플랜·swift
struct OperationPlan: Hashable {
    let id: OperationID
    let kind: OperationKind                 // copy, move, rename, trash, tag...
    let sources: [LocationReference]
    let destination: LocationReference?
    let expectedIdentities: [ResourceID]    // what we revalidate against
    let expectedMetadata: [MetadataSnapshot]
    let collision: CollisionDecision        // frozen, not inferred at runtime
    let traversalPolicy: TraversalPolicy    // packages atomic, symlinks as links
    let planHash: String                    // deterministic over all the above
    // NOTE: every field is `let`. There is no mutating method. On purpose.
}

// Reality changed? Don't edit -- supersede with a NEW plan:
func revise(_ old: OperationPlan, newCollision: CollisionDecision) -> OperationPlan {
    OperationPlan(from: old, collision: newCollision)   // fresh id, fresh hash
}

External links

Exercise

네가 쓴 코드에서 가변 'request' 나 'job' 객체를 골라 — 생애 동안 필드가 설정되는 거. 코드 두 부분이 다른 시점에 편집해서 일관 안 된 상태가 될 수 있는 방법들을 나열해봐. 그다음 어떤 변경이든 새 버전을 낳는 불변 값으로 다시 설계해봐. 방금 어떤 버그 부류를 지웠어?
Hint
가변 request 객체는 '부분 설정됨' 이랑 '시작 뒤 편집됨' 버그를 불러 — 고전은 검증이랑 사용 사이에 바뀌는 필드야. 불변으로 만들면 변경이 자기 정체성을 가진 새 객체라서, '내가 검증한 게 돌아간 그거' 가 구성상 참이 돼. 그게 플랜 해시가 Waygate 한테 주는 딱 그 보장이야.

Progress

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

댓글 0

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

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