심볼 변경 시 속성 크레딧 획득 또는 에이전트 패치 폐쇄 유지
요약
본 문서는 소프트웨어 패치 병합 시의 엄격한 검증 원칙과 새로운 '속성 크레딧' 획득 규칙을 제안합니다. 성공적인 병합은 모든 변경된 심볼이 속성 크레딧을 가지고, 피처 해시가 잠금 상태와 일치하며, 플레이크 동결 기여도가 0일 때만 가능합니다. 특히, '속성 크레딧'은 술어의 불변성을 명시하고 소스 해시를 저장하는 등 구체적인 조건을 충족할 때만 부여되는 유일한 긍정적 단위입니다.
핵심 포인트
- 병합 조건: 속성 크레딧 확보, 피처 잠금 일치, 플레이크 동결 기여도 0이 필수.
- 속성 크레딧은 술어의 불변성을 명시하고 소스 해시를 저장할 때만 얻을 수 있는 핵심 단위임.
- 커버리지는 정확히 1.0이어야 하며, 근사치는 거부 사유가 됩니다.
- 패치에 포함된 테스트는 단지 '보이는' 것일 뿐, 진정한 불변성 검증이 아닐 수 있습니다.
에이전트 패치는 작업(job)이 성공적일 경우 병합되지 않습니다. 모든 변경된 심볼이 속성 크레딧을 가지고, 모든 피처(fixture) 해시가 잠금(lock)과 일치하며, 모든 플레이크(flake) 동결(freeze) 기여도가 0일 때만 병합됩니다.
CI는 세 가지 다른 신호를 하나의 비트로 축소합니다. 속성은 통과할 수 있고, 피처는 재실행될 수 있으며, 알려진 플레이크는 무음 처리될 수 있습니다. 이 결과들은 서로 대체할 수 없습니다. 이 원장(ledger)이 목표로 하는 누락은 구체적입니다: 프로덕션 동작이 변경되었고, 편집된 심볼을 커버하는 불변성(invariant)이 없으며, 동결(freeze)이 검사를 조용하게 유지한 경우입니다.
아래의 점수 규칙들은 제안입니다. 분류기(classifier)는 실행되지 않은 예시이며, 프로덕션 리포지토리에서 측정된 게이트가 아닙니다.
크레딧을 받는 항목
속성 크레딧은 유일한 긍정적 단위입니다. 변경된 심볼이 술어(predicate)가 불변성을 명시하고, 해당 술어의 소스 해시가 영수증에 저장되며, 해당 술어가 결과를 동결된 문서와 비교하지 않을 때 한 점을 얻습니다.
피처 잠금은 필수적이며 가치가 없습니다. 일치하는 해시는 입력 바이트가 검토한 바이트임을 보여줄 뿐입니다. 동작이 허용 가능하다는 것을 보여주지 않습니다.
플레이크 동결은 격리 인용(quarantine citation)이며 역시 가치가 없습니다. 이는 관련 없는 실패가 검토를 막지 않도록 기준선 플레이크를 지적할 수 있습니다. 이 패치가 편집한 심볼에 누락된 술어의 대용이 될 수는 없습니다.
커버리지(Coverage)는 크레딧을 받은 심볼을 변경된 심볼로 나눈 값입니다. 승인(Admission)은 근사치가 아닌 정확해야 합니다.
admit if coverage == 1.0
and fixture_status == "match"
and rejection_codes == []
...
커버리지 0.5는 부드러운 경고가 아닙니다. 영수증이 거부하고, 누락된 심볼은 작성자에게 되돌아갑니다.
불리언 게이트가 침묵을 지키는 경우
에이전트 디프(Agent diffs)에는 종종 수정 사항 옆에 새로운 테스트가 포함됩니다. 그 패턴은 신중해 보입니다. 이는 단언(assertion)이 동일한 디프가 재작성한 피처와 같거나, 스킵(skip)이 패치 자체가 생성한 동결 ID를 인용할 때 원장(ledger)을 실패하게 만듭니다.
작업은 여전히 통과합니다. 영수증은 그렇지 않습니다. R5는 검사처럼 꾸며진 고정 장치(fixture) 동등성을 표시합니다. R4는 기준선 원장(baseline ledger)에 없는 동결 ID를 표시합니다. R3은 변경된 심볼에 대한 유일한 신호로 사용되는 기준선 동결을 표시합니다.
더 조용한 실패는 고정 장치 상태를 읽은 후 true를 반환하는 헬퍼입니다. 테스트 이름에 'property'라는 단어가 포함되어 있습니다. 피리케이티브 해시(predicate hash)는 고정 장치가 이동할 때마다 움직이므로, 분류기(classifier)가 크레딧을 보류합니다. 테스트 이름의 레이블은 불변량(invariant)이 아닙니다.
결정 테이블 (Decision table)
| 레인 | 크레딧 | 허용 규칙 | 증거로 원격 실행 가능? | 거부 사유 |
|---|---|---|---|---|
| 변경된 심볼의 속성 | 심볼당 1 | 커버리지는 1.0이어야 함 | 로컬 통과 후 확인용으로만 | R1 누락 속성, R5 고정 장치 동등성 |
| ... | ||||
| 읽는 것은 정책입니다. 아래 단계들은 그것을 계산할 뿐입니다. |
1단계: diff에서 변경된 심볼 목록화
에이전트가 우연히 건드린 테스트가 아니라 패치(patch)부터 시작합니다. 정의가 변경되거나 호출 사이트 변경으로 관찰 가능한 결과가 바뀌는 경우 심볼을 계산합니다.
git diff --unified=0 origin/main...HEAD -- '*.py' \
| awk '/^diff --git/{f=$0} /^@@/{print f, $0}'
changed_symbols.txt에 한 줄마다 정규화된 이름(qualified name)을 작성합니다. 빈 목록은 검토를 조기에 종료시킵니다. 테스트 전용 편집이라도 동작 잠금(lock behavior)을 주장하면 속성을 가질 수 있지만, diff가 건드리지 않은 프로덕션 파일의 고정 장치 크레딧은 얻지 못합니다.
검토하기에 충분히 짧게 목록을 유지하세요. 생성된 파일이 심볼 개수를 폭발적으로 늘린다면, 해당 경로를 명령어에서 제외하고 영수증에 명시하십시오. 숨겨진 제외는 또 다른 부울 값일 뿐입니다.
2단계: 접촉된 각 어설션 분류하기
접촉된 테스트의 모든 어설션(assertion)에 하나의 클래스를 레이블링합니다.
property— 입력과 출력에 대한 술어(predicate)이며, 전체 예상 문서를 포함하지 않습니다.fixture_eq— 커밋된 블롭(blob)과의 동등성 또는 스냅샷 비교입니다.freeze_ref— 건너뛰기(skip), 실패 처리(xfail), 또는 flake id를 인용하는 주석입니다.opaque— 의미가 diff에서 보이지 않는 헬퍼, 목(mock), 또는 단언문(assertion)입니다.
클래스 1만 크레딧을 추가할 수 있습니다. 클래스 2는 블롭 해시가 일치하는 경우 fixture 게이트를 만족할 수 있습니다. 클래스 3은 절대 크레딧을 추가하지 않습니다. 클래스 4는 아무것도 추가하지 않으며, 클래스 4의 증거만 있는 변경된 심볼은 여전히 커버되지 않은 상태로 남습니다.
샘플 분류기(sample classifier)에 사용된 어휘 holds, implies, 및 invariant는 언어 기능이 아닌 로컬 관례입니다. 만약 귀하의 스위트가 다른 술어 이름을 사용한다면, 클리어런스(clearance)를 신뢰하기 전에 힌트를 변경하십시오.
단계 3: 경로가 아닌 fixture 바이트 해시
경로 문자열은 파일을 대체하는 편집에서도 살아남습니다. 에이전트는 tests/fixtures/invoice.json을 다시 작성하고 테스트의 경로는 변경하지 않을 수 있습니다.
python - << 'PY'
import hashlib, pathlib
root = pathlib.Path("tests/fixtures")
...
대상 브랜치에서 fixture.lock에 대해 나열된 diff입니다. 불일치가 있으면 R2입니다. 패치 내부에 락(lock)을 업데이트하는 것은, 속성이 새 블롭을 예상 값으로 사용하지 않고도 모든 변경된 심볼을 여전히 커버할 때만 허용됩니다.
fixture 디렉토리가 없으면, 게이트를 만족시키기 위해 해시를 지어내지 말고 fixture_status를 not_applicable로 기록하십시오.
단계 4: 기준선 원장(baseline ledger)에서만 freeze 인용
격리 파일은 대상 브랜치에 이미 존재해야 합니다. 패치 로컬의 freeze 파일은 유효한 id의 출처가 아닙니다.
flakes:
- id: FLK-1044
signature: "TimeoutError: checkout_worker"
...
해당 날짜들은 규칙에 대한 예시 필드일 뿐, 실제 발생한 사고 보고서가 아닙니다. 인용(citation)은 id가 해당 기준선 파일(baseline file)에 있고, 서명(signature)이 여전히 일치하며, expires_on이 검토 시점(review clock)보다 나중일 때만 유효합니다. 2026-10-11의 검토 시점에서 보면 위 예시 id는 여전히 인용 가능합니다. 하지만 2026-10-01에 만료된 id는 그렇지 않습니다.
행동 패치(behavior patch)에서 만료 기한을 연장하지 마십시오. 만료 기한은 정책 편집이며 별도의 검토를 거쳐야 합니다. 단순히 변경된 심볼을 조용히 유지하는 동결(freeze)은 id가 오래되었고 만료되지 않았더라도 R3입니다.
5단계: 작업 영수증 (Worked receipt)
두 개의 변경된 심볼, 즉 billing.prorate와 billing.invoice_total을 가져옵니다. 첫 번째 테스트는 assert holds(prorate(10, 0.5) >= 0)입니다. 이것이 한 크레딧입니다. 두 번째 테스트는 assert invoice_total(order) == load_fixture("invoice.json")입니다. 이것은 R5이며 크레딧은 없습니다. 기준선 FLK-1044에 대한 관련 없는 인용 역시 크레딧을 추가하지 않습니다.
{
"changed_symbols": ["billing.prorate", "billing.invoice_total"],
"credits": {"billing.prorate": 1, "billing.invoice_total": 0},
...
}
수리(repair)는 피처 파일(fixture)을 오라클로 읽지 않는 술어(predicate)입니다. 예를 들어 assert holds(invoice_total(order) == sum(line.net for line in order.lines))와 같습니다. 이 술어가 로컬-그린(local-green) 상태가 되면 커버리지(coverage)는 1.0에 도달할 수 있고 R1이 해제됩니다. 만약 피처 파일의 동등성 비교가 파일 내에 남아 있다면 R5는 유지됩니다. 이를 삭제하거나, 크레딧 열 밖에 비-오라클 잠금(non-oracle lock)으로만 남겨야 합니다.
새로운 술어 없이 다시 실행해도 이 영수증은 변하지 않습니다. 그린 상태가 커버리지를 의미하는 것은 아닙니다.
6단계: 적응할 수 있는 분류기 (Classifier you can adapt)
이 모듈은 미실행 제안 코드(unexecuted proposal code)입니다. 힌트 어휘(hint vocabulary)를 사용하지 않는 스위트에서는 오작동할 것입니다. 병합하기 전에 스크래치 브랜치에서 실행하고 수동으로 읽어본 코드와 비교하십시오.
#!/usr/bin/env python3
"""미실행 제안: 에이전트 패치 영수증에 대한 심볼 크레딧."""
...
샘플 입력은 5단계의 작업 사례를 문자열로 인코딩한 것이므로, 저장소 없이 파일이 실행됩니다. 이 결과를 검토 아티팩트로 취급하기 전에 해당 문자열들을 실제 테스트 본문으로 교체하십시오.
python tools/merge_ledger.py > receipt.json
python -c 'import json,sys; r=json.load(open("receipt.json")); sys.exit(0 if r["admit"] else 1)'
프로세스 종료 상태가 기계적인 게이트 역할을 합니다. 검토자는 어떤 재정의(override)보다 먼저 rejection_codes를 읽습니다. 재정의는 영수증에 명시적인 필드로 포함되어야 하며, 동결 인용을 크레딧으로 변환할 수 없습니다.
위의 스코어러는 fixture_status를 계산하지 않으며 만료(expiry)도 파싱하지 않습니다. 이 스코어러의 admit 플래그를 3단계 잠금 비교와 교차하고, 4단계에서 이미 승인된 flake id만 공급해야 합니다. 해시 불일치로 인해 참(true) 플래그가 된 경우에도 여전히 R2입니다.
7단계: 누락된 술어 초안을 작성한 후 로컬에서 증명하기
공개 정보: 이 문서는 MonkeyCode의 제품 홍보의 일환으로 준비되었습니다. MonkeyCode의 무료 모델 액세스는 여기서 하나의 역할만 합니다. R1 영수증이 발견되지 않은 심볼 목록을 제공하면, 무료 모델에게 diff로부터 후보 assert holds(...) 라인을 작성하도록 요청할 수 있습니다. 이 라인들은 신뢰할 수 없는 텍스트입니다.
초안은 오직 다음 두 가지 조건을 충족할 때만 유지해야 합니다. 첫째, 초안 없이 불변성(invariant)을 다시 진술할 수 있어야 하며, 둘째, 로컬 실행이 패치된 코드에 대해 이를 실행한 후에만 가능합니다. 단순히 피처 파일 내용을 다시 진술하는 초안은 크레딧이 아닌 fixture_eq 클래스입니다.
무료 서버 옵션에는 두 번째의 별도 역할이 있습니다. 로컬 속성 라인이 녹색(green) 상태가 되면, 해당 순수 라인을 원격으로 재실행하고 로그를 확인 자료로 첨부합니다. 확인 자료는 크레딧이 아닙니다. 이는 R2, R3, R4, 또는 R6을 해제하지 못합니다.
원격 로그만 포함된 영수증은 거부됩니다. 두 옵션 모두 이 워크플로우를 위한 운영자 공급 가용성 주장입니다. 본 문서는 모델 이름, 할당량(quota), 하드웨어 프로필, 지속 시간 또는 영구성(permanence)을 명시하지 않습니다. 만약 두 옵션 중 어느 것이든 사용 불가능하다면, 로컬에서 영수증을 계산해야 합니다. 원격 라인이 누락되었기 때문에 admit이 바뀌어서는 안 됩니다.
단계 8: 네 가지 필드를 순서대로 읽기
coverage가 1.0과 같아야 합니다. 그보다 낮은 값은 미커버된 이름이 있는 작성자에게 반환됩니다.rejection_codes는 비어 있어야 합니다. 남아있는R5는 다른 예측자(predicate)가 점수를 얻었더라도 여전히 피처 동등성(fixture equality)에 문제가 있음을 의미합니다.freeze_citations의 각 id는 기준선(baseline)이며, 서명 일치(signature-matched) 상태여야 하고, 영수증에 인쇄된 CI 시계 대비 만료되지 않았어야 합니다.predicate_hashes는 diff 내의 테스트 본문과 일치해야 합니다. 검토된 수정 없이 이동한 해시 값은 오래된 영수증(stale receipt)이며, 오래된 영수증은 통과할 수 없습니다.
이 네 가지 확인 절차를 거친 후에만 병합(Merge)하십시오. 대기열을 비우기 위해 커버리지 막대를 "가장 많은 심볼(most symbols)"로 낮추지 마십시오.
제한 사항 (Limitations)
클래시파이어는 어휘적(lexical)입니다. 헬퍼 형태의 속성(Helper-shaped properties)은 opaque하게 되어 거짓 R1 결과를 생성합니다. assert holds(True)와 같은 공허한 형식(vacuous forms)은 상수 검사(constant check)를 추가하지 않으면 크레딧처럼 보일 수 있습니다. 이 검사를 추가하는 것이 의미가 있으려면, 명확히 해야 합니다.
스냅샷 중심의 스위트(Snapshot-heavy suites)는 거의 모든 에이전트 패치에서 R5를 수집할 것입니다. 이는 코드를 비활성화하라는 요청이 아니라, 변경 사항당 하나의 불변성(invariant)을 추출하라는 신호입니다. 만약 불변성을 명명할 수 없다면, 이 원장(ledger)은 해당 변경 사항에 적합하지 않습니다.
만료는 전달하는 시계를 사용합니다. 시간이 흐른 시계는 죽은 동결(dead freezes)을 허용합니다. 시계를 CI 타임스탬프에 고정하고 freeze_citations 옆에 인쇄하십시오.
여기 있는 어떤 것도 공식적인 증명은 아닙니다. 유창한 예측자(fluent predicate)도 여전히 잘못된 비즈니스 규칙을 인코딩할 수 있습니다. 로드, 마이그레이션 및 보안 검토는 영수증 범위 밖에 남아 있습니다.
건너뛰어야 할 경우 (Who should skip it)
정책상 이미 행동적이지 않은 것으로 취급하는 기계적인 이름 변경(mechanical rename)의 경우에는 이 원장 절차를 건너뛰십시오. 또한, 수정된 코드가 실시간 제3자 상태(live third-party state) 없이 결정론적 예측자를 가지지 않는 경우에도 건너뜁니다. 이러한 설정에서는 전략이 R1 노이즈를 만들어내며, 기록된 상호작용 계약(recorded interaction contract) 자체가 정직한 아티팩트입니다.
병합 크레딧을 부여하기 위해 freeze 파일을 필요로 한다면 ledger를 채택하지 마십시오. 그 필요는 규칙에 모순됩니다. free-model 초안을 기록의 출처로 사용하지 말고, free-server 로그를 유일한 pull-request 증거로 제출하지 마십시오.
규제 대상 팀은 아카이브 내 로컬 영수증(local receipt), lock 파일, 그리고 CI 타임스탬프를 해당 정책이 이미 명시하는 대로 보관해야 합니다. 다음 agent 패치에서는 runner 브랜드가 아닌 거부 코드(rejection codes)부터 시작하십시오. 코드가 전략입니다. 원격 확인은 선택 사항으로 유지됩니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기