하나의 실패 시그니처와 두 개의 러너: 플레이크 프리즈 인용 규칙
요약
본 문서는 '플레이크 프리즈'라는 개념을 설명하며, 이는 로컬 게이트가 여러 증인과 속성 다이제스트를 공유하고 상반된 판결을 내리며 안정적인 실패 시그니처를 보일 때만 인용될 수 있습니다. 원격 재실행은 가능하지만, 프리즈 자체 발행은 불가능합니다. 또한, 이 시스템은 부울 작업 상태나 비트 변경에 대한 처리 규칙과 게이트가 읽는 필드들에 대한 상세한 지침을 제공합니다.
핵심 포인트
- 플레이크 프리즈는 안정적인 실패 시그니처와 두 명의 증인을 요구함.
- 원격 재실행은 허용되지만, 프리즈 자체 발행은 금지됨.
- 게이트는 산문 설명 대신 JSON 객체 형태의 필드를 읽어야 함.
- 핀 불일치는 파이프라인 중단 사유이며, 이는 플레이크의 증거가 아님.
- 초안 다이제스트는 명세 다이제스트와 비교하여 격리(quarantine)되어야 함.
플레이크 프리즈(flake freeze)는 로컬 게이트가 피처 핀(fixture pin), 속성 다이제스트(property digest), 바운드(bound)를 공유하고, 상반된 판결을 가지며, 하나의 안정적인 실패 시그니처(stable fail signature)를 보여주는 두 명의 증인(witnesses)을 보유할 때만 인용될 수 있습니다. 원격 재실행(remote replay)은 증인을 추가하는 것은 허용하지만, 프리즈 자체를 발행(mint)하는 것은 허용하지 않습니다.
부울(boolean) 작업 상태는 해당 규칙을 지원할 수 없습니다. 비트(bit)는 핀, 다이제스트, 시그니처, 그리고 러너 역할(runner role)을 모두 삭제합니다.
두 개의 빨간색 빌드(red builds)도 여전히 서로 다른 버그일 수 있습니다. 두 개의 상반된 빌드는 깜빡이는 동일한 버그이거나 패치가 재작성한 피처일 수 있습니다. 레저(ledger)는 이 필드들을 분리하여 유지하며, 결정 함수(decision function)는 그 외의 어떤 것도 인정하지 않습니다.
게이트가 읽는 필드들
증인당 하나의 JSON 객체를 저장합니다. 게이트가 읽는 행에는 산문 설명(prose explanation)을 저장하지 마십시오. 검토자(reviewer)가 산문이 필요하다면, 다이제스트 입력 외부로 유지하십시오.
| 필드 | 결정 사용처 |
|---|---|
| property_id | 동일한 동작을 주장하는 행들을 그룹화함 |
| ... |
인용(citation)은 인정될 때 하나의 실패 ID와 하나의 성공 ID를 명시합니다. CI 작업(CI job)을 명시하지는 않습니다. 만료(Expiry)는 호출자(caller)가 정책으로부터 제공하는 타임스탬프입니다. 이 메모는 기간을 지정하지 않으며, 오래된 인용을 새로 고치지도 않습니다.
프리즈 파일이 작성되기 전의 결과들
위에서 아래로 필터를 읽으십시오. 첫 번째 일치하는 거부(reject)가 승리합니다. 행들을 점수(score)로 평균 내지 마십시오.
| 범위 지정된 입력 | 결과 |
|---|---|
원격 행 중 어느 하나라도 freeze_writer가 true인 경우 | 배치(batch)를 거부함 |
| ... |
'admit' 행은 의도적으로 좁습니다. 다른 모든 행들은 닫힌 패치, 사양 문제(spec problem), 또는 수집기 버그(collector bug)입니다. 이들 중 어느 것도 프리즈는 아닙니다.
1. 발행 기계에서 피처를 핀하기
원격 작업이 시작되기 전에 핀을 계산하십시오. 수집기(collector)는 자신이 발명한 값으로가 아니라 예상되는 값(expected value)으로서 핀을 받아야 합니다.
python - <<'PY'
import hashlib
import pathlib
...
위의 피처 경로는 예시입니다. 속성이 실제로 로드하는 파일을 사용하십시오.
핀 불일치(pin mismatch)는 파이프라인을 중단시킵니다. 이는 플레이크(flake)의 증거가 아닙니다. 만약 에이전트 패치가 피처 파일(fixture bytes)을 수정한다면, 핀이 변경되고 이 게이트는 프리즈(freeze)를 인용하지 않을 것입니다. 해당 패치는 리뷰에서 다루어져야 합니다.
2. 커밋된 속성 파일을 처리하기 (Digest the checked-in property file)
기준이 되는 명세(spec)는 리뷰어가 저장소에서 열어볼 수 있는 파일입니다. 이 바이트들의 해시를 계산하세요. 모델 초안은 누군가 이를 커밋할 때까지 임시 파일에 불과합니다.
python - <<'PY'
import hashlib
import pathlib
...
admit 함수 외부에서 초안의 다이제스트(digest)를 명세 다이제스트와 비교하세요. 만약 다르다면, 해당 초안을 격리(quarantine)시키세요. 초안 해시를 expected_digest로 전달하지 마십시오.
수용(Acceptance)은 명세 파일을 변경하는 커밋입니다. 이는 수집기(collector)의 로그 라인이 아닙니다.
3. 동일한 스키마로 로컬 및 원격 행 추가하기 (Append local and remote rows with the same schema)
두 러너 모두 같은 필드를 작성합니다. 오직 로컬 호출자만이 admit 결과를 권위(authority)로 간주할 수 있습니다.
freeze_writer를 true로 설정하는 원격 행은 다른 모든 필드가 일치하더라도 배치(batch)를 실패하게 만듭니다. 잘못된 행을 삭제하고 계속 진행하지 마십시오. 하나의 권위 위반만으로도 해당 배치를 폐기하기에 충분합니다.
{"witness_id":"w-local-1","property_id":"order_total_nonneg","property_digest":"<spec-sha256>","fixture_pin":"<pin-sha256>","bound":"total>=0","seed":17,"verdict":"fail","signature":"AssertionError","runner":"local","freeze_writer":false}
{"witness_id":"w-remote-9","property_id":"order_total_nonneg","property_digest":"<spec-sha256>","fixture_pin":"<pin-sha256>","bound":"total>=0","seed":17,"verdict":"pass","signature":"ok","runner":"remote","freeze_writer":false}
이 인용 규칙을 테스트하는 동안 시드(seed)를 동일하게 유지하세요. 다른 시드는 다른 조사에 중요할 수 있습니다. 이는 아래 함수에서 입회를 차단하거나 정당화하지 않습니다.
4. 반대되는 판결에 걸쳐 하나의 실패 서명 요구하기 (Require one fail signature across opposite verdicts)
참조 함수(reference function)는 핀 및 다이제스트 검사가 통과된 후에만 호출하세요. 이때 입회(Admission)는 네 가지 술어(predicates)를 요구합니다.
- 원격 증인이 민팅을 시도하지 않았습니다.
- 적어도 하나의 로컬 행과 하나의 원격 행이 속성 id, 다이제스트(digest), pin, 그리고 바운드(bound)를 공유합니다.
- 해당 범위에는 패스(pass)와 실패(fail)가 모두 포함됩니다.
- 범위 내의 모든 실패는 동일한 시그니처를 가지며, 그 시그니처는
ok가 아닙니다.
AssertionError에서 KeyError로 변경된 것은 다른 실패 모드입니다. 이는 플리커(flicker)가 아닙니다. 패치를 닫고 피처(fixture) 또는 스펙을 검사하십시오.
이유 문자열은 CI 로그에 나타나야 합니다. 다음 독자가 어떤 술어(predicate)가 실패했는지 재구성할 필요가 없어야 합니다.
5. 로컬 호출자가 인용(citation)을 작성하게 하라
해당 함수는 식별자들을 반환합니다. 소켓을 열거나, 프리즈 스토어(freeze store)를 쓰거나, 이전의 인용을 확장하지 않습니다.
로컬 작업은 fail_id와 pass_id를 명시하고 정책에서 가져온 만료 시간(expiry)을 포함하는 하나의 인용을 작성할 수 있습니다. 나중에 성공한 실행이 이 함수의 인수는 아닙니다. 리필 입력(refill input)이 없는데, 이는 별도로 검토될 다른 정책일 것이기 때문입니다.
참조 함수
아래 모듈은 자체적으로 완결된 제안입니다. 표준 라이브러리만을 사용합니다. 벤더 클라이언트가 아닙니다.
해당 목록은 이 초안에서 실행되지 않습니다. 뒤따르는 단언(assertions)들은 공유 러너(shared runner)로부터의 측정값이 아니라, 함수가 기대하는 결과값입니다.
from __future__ import annotations
from dataclasses import dataclass
...
이를 witness_gate.py로 저장하십시오. 그런 다음 세 가지 검사를 실행합니다. Python 3.9 이상이면 충분합니다. 타사 패키지는 필요하지 않습니다.
python - <<'PY'
from witness_gate import Witness, decide_freeze
...
만약 단언이 발생하면, 허용 경로(admit path) 또는 두 개의 거부 경로 중 하나가 표류한 것입니다. 작업에 연결하기 전에 함수를 수정하십시오.
각 이유에 따라 행동하는 방법
점수로서가 아니라 다음 단계로 이유 문자열을 사용하십시오.
attempted to mint은 원격 작업 설정이 잘못되었음을 의미합니다. 쓰기 접근 권한을 제거하십시오. 해당 배치에서 프리즈를 인용하지 마십시오.malformed witness는 컬렉터 스키마가 벗어났음을 의미합니다. 작업을 중지하고 라이터를 수정하십시오.need two witnesses는 핀(pin), 다이제스트(digest) 또는 바운드(bound)가 일치하지 않았음을 의미합니다. 두 해시를 로컬에서 재계산하십시오.opposite verdicts required는 일관된 통과(pass) 또는 일관된 실패(fail)가 있음을 의미합니다. 일관된 실패는 동일 키에 대해 통과하는 증인이 나타날 때까지 결함입니다.fail signature is not stable은 적어도 두 가지 실패 모드가 핀을 공유함을 의미합니다. 프리즈 논의를 하기 전에 조사하십시오.need both a local witness and a remote witness는 증거가 단일 출처임을 의미합니다. 누락된 역할을 임의로 만들지 마십시오.stable signature across opposite verdicts만이 인용을 허용하는 유일한 이유이며, 로컬 호출자만 이를 기록할 수 있습니다.
무료 모델과 무료 서버가 적합한 경우
MonkeyCode의 무료 모델 접근은 후보 속성을 초안 작성할 수 있으며, 무료 서버 옵션은 runner=remote 행을 추가하는 원격 리플레이를 실행할 수 있습니다. 공개 고지: 이 문서는 MonkeyCode의 제품 홍보의 일환으로 준비되었습니다. 이 두 가지 옵션은 초안 텍스트와 원격 컬렉션만을 다룹니다.
초안은 스펙 파일이 git에서 변경될 때까지 격리 상태를 유지합니다. 원격 행은 freeze_writer가 false여야 합니다. 어느 쪽 옵션도 admit 술어의 입력값은 아닙니다.
무료 모델이 작동하지 않으면 초안 작성을 건너뛰고 체크인된 스펙을 유지하십시오. 무료 서버가 작동하지 않으면 로컬 러너가 두 역할을 사칭하도록 내버려 두지 마십시오. 누락된 원격 증거는 인용할 수 없음을 의미합니다.
이 기본값은 단일 러너 프리즈보다 더 엄격합니다. 또한 이 게이트가 존재하는 이유이기도 합니다. 할당량(Quotas), 하드웨어, 및 보존 기간(retention)은 본 문서의 범위를 벗어나므로, 기능에 대해 추측을 인코딩하지 마십시오.
핀 스크립트와 스펙 파일이 이미 트리에 있는 경우, 분할은 시험하기에 충분히 작습니다. 즉, 오프라인으로 초안 작성하고, 원격으로 컬렉션하며, 로컬로 인용할 수 있습니다. 나중에 컬렉터를 교체하더라도 결정 함수는 동일하게 유지됩니다.
제한 사항 (Limitations)
시그니처의 동일성 비교는 거칩니다(coarse). 두 개의 AssertionError 행은 서로 다른 메시지를 숨길 수 있습니다. 만약 메시지 식별자가 중요하다면, 호출 전에 정규화된 메시지를 해시하여 signature로 사용하십시오. 이 설명은 해당 정규화기(normalizer)를 정의하지 않습니다.
쌍 규칙(pair rule)은 동일한 시드(seed)를 요구하지 않습니다. 다른 키들이 일치하는 경우, 서로 다른 시드를 사용한 통과(pass)와 실패(fail)를 인용할 것입니다. 만약 시드가 노이즈 발생원이라면, 별도의 검토에서 해당 술어(predicate)를 추가하십시오. 새로운 테이블 없이는 이를 이 함수에 통합하지 마십시오.
유효한 인용은 안전성 증명(safety proof)이 아닙니다. 피처(fixture)가 너무 좁을 수 있습니다. 핀(pin) 외부의 입력값도 여전히 속성을 실패하게 만들 수 있습니다. 더 넓은 생성기(generators)와 입력 축소(input shrinking)는 별개의 작업으로 유지되어야 합니다. 이 게이트는 단지 프리즈 인용이 허용되는지 여부만을 결정합니다.
만료일(Expiry)은 정책 입력값으로 남아있습니다. 만료 필드가 없는 인용은 decide_freeze가 '허용(admit)'을 반환했더라도 작성자(writer)에 의해 거부되어야 합니다. 여기에 표시된 함수는 시계(clock)를 확인하지 않습니다.
누가 사용해서는 안 되는 경우 (Who should not use this)
실패가 안정적인 시그니처를 가지지 못하는 경우, 타임아웃을 포함하여 빈 에러 문자열을 기록하는 경우에는 이 게이트를 건너뛰십시오. 속성 텍스트가 프롬프트에만 존재하는 경우에도 건너뜁니다. 로컬 및 원격 작업이 쓰기 가능한 프리즈 저장소(writable freeze store)를 공유하고, 원격 경로에서 freeze_writer를 강제 'false'로 설정할 수 없는 경우에도 건너뛰십시오.
마지막 레이아웃에서는 원장(ledger)이 권한을 제약하지 않습니다. 행들을 수집하는 것은 노이즈만 추가할 것입니다.
또한, 동일한 핀에서, 동일한 시그니처로, 그리고 통과를 입증하는 증인(passing witness) 없이 두 번 재현된 실패의 경우에도 건너뛰십시오. 이 경우는 코드 또는 사양 변경이 필요합니다. 이미 함수가 이를 거부하고 있으므로, 그 거부 상태는 유지하십시오.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기