Skip to content

Compiler Generated Repairs

kimjooyoon edited this page Oct 2, 2026 · 3 revisions

Gooo로 오류 처리 코드를 생성하기

2026-10-03 안내: 아래 예제와 관측은 각 절에 고정된 소스·도구체인을 기준으로 읽습니다. 최신 바디 생성과 자체 소형 모델의 흐름은 모델과 메타프로그래밍, 지금 사용할 버전은 현재 상태와 시작하기에 정리했습니다.

Gooo의 메타프로그래밍은 코드에 이름표를 붙이는 데서 끝나지 않습니다. 어떤 원본의 어떤 동작을 바꿀지 선언하고, 그 선언에 연결된 수정 코드를 생성할 수 있습니다.

이 실습에서는 결과를 출력하지 못했는데도 성공으로 보고하던 CLI 동작을 다룹니다. Gooo는 이미 존재하는 JSON 출력의 오류 처리 코드를 선택해, 사람이 읽는 출력 경로의 수정 후보를 만듭니다. 후보를 생성하는 일과 그 후보를 받아들이는 일은 분리됩니다.

지원 기준: 개발 브랜치의 #851 병합본, go-error-guard:v1. 실험적 컴파일러 프로필과 예제 어댑터이며, 공개 릴리스 전체의 지원 약속이나 새로운 범용 리팩터링 명령은 아닙니다.

1. 무엇을 해결하나요?

계산을 끝내는 것과 결과를 전달하는 것은 다릅니다.

출력 대상이 닫혔는데 CLI가 종료 코드 0을 반환하면, 호출자는 결과를 정상적으로 받았다고 오해할 수 있습니다. 이 사례의 목표는 모든 실행을 성공으로 만드는 것이 아닙니다. 전달에 실패했을 때 실패를 정확하게 보고하는 것입니다.

그대로 지켜야 하는 것 바뀌어야 하는 것
정상 출력의 내용과 기존 JSON 오류 처리 사람용 출력에서 버려지던 쓰기 오류
선택하지 않은 원본 구간 그 쓰기 호출에 오류 처리를 연결하는 구간
기존 검사의 기대값 오류를 무시하던 실제 동작

구조만 바꾸는 리팩터링과 버그 수정은 목표가 다릅니다. 이 수정은 특정 실패 상황의 동작을 의도적으로 바꾸므로, 원본과 모든 상황에서 같은 동작을 한다고 주장하지 않습니다. 코드 변환과 효과에서 이 차이를 더 읽을 수 있습니다.

2. 실행할 환경과 입력

Go 1.27.0을 사용한 저장소의 CI 결과를 기준으로 설명합니다. 다른 작업과 분리된 체크아웃에서 병합된 버전을 선택할 수 있습니다.

git clone https://github.com/kimjooyoon/meta-ontology-go.git gooo-guard-lab
cd gooo-guard-lab
git checkout ba8a8d5250e1b2ccdf87a495eb7930a7ef082614

실습 입력은 internal/meta/policycompilation/testdata/go-error-guard/original.go.golden입니다. 과거 a97a102... 버전의 실제 Go 파일을 보존한 fixture입니다. 현재 CLI를 일부러 고치거나 망가뜨리는 실습이 아닙니다. 아래의 고정된 식별값은 이 입력에만 대응합니다.

결함이 이미 수정된 현재 구현을 같은 식별값으로 넣으면 원본 불일치로 거절되는 것이 정상입니다. 검사를 통과시키기 위해 식별값을 몰래 바꾸거나, 그 거절을 수정 완료로 읽지 않습니다.

3. 수정할 대상을 Gooo로 선언합니다

출력용 임시 디렉터리와 Gooo 입력을 만듭니다.

work="$(mktemp -d)"
cat > "$work/guard.gooo" <<'GOOO'
package goerrorguard
namespace goerrorguard
entity Source id "gooo://error-guard/source"
entity Candidate id "gooo://error-guard/candidate"
activity GuardWrite(Source) -> Candidate computes "go-error-guard:v1;function=writeSourcePackageResult;writer=stdout;diagnostic=stderr;source=sha256:5bd27e33e18e8c5dc87f25c0cd4004ee370cfa7dc441c85d89bb03fd333a8937;handler=sha256:16406e2ee9ce1a70c1541170c698ca69219afc39dd56aae66c54d7cc64ff2a93"
GOOO

긴 computes 문자열의 각 부분은 다음과 같습니다.

선언 컴파일러에 주는 선택
Source, Candidate 무엇을 사용해 무엇을 생성하는가
GuardWrite 그 둘을 연결하는 작업
go-error-guard:v1 적용할, 범위가 제한된 변환 규칙
function 수정 대상 함수
writer, diagnostic 결과와 진단 메시지를 쓰는 매개변수
source 입력 Go 파일 전체 바이트의 식별값
handler 복사할 기존 오류 처리 블록의 식별값

이 선택은 자연어에서 추측해 채우지 않습니다. 기존 Gooo 프런트엔드는 선언을 의미 모델인 IR로 내리고, 컴파일러는 입력 사용과 결과 생성 관계가 그 모델에 맞는지 확인합니다.

해시는 이 입력이 어느 입력인지 구분합니다. 서명, 작성자 신뢰, 올바른 동작의 증명까지 대신하지는 않습니다.

4. 수정 후보를 생성하고 읽습니다

저장소 루트에서 예제 어댑터를 호출합니다.

go run ./examples/meta-policy-compilation/go-error-guard \
  -program "$work/guard.gooo" \
  -source ./internal/meta/policycompilation/testdata/go-error-guard/original.go.golden \
  > "$work/proposal.json"

이 어댑터는 두 입력을 읽고 JSON을 표준 출력으로 내보냅니다. 원본 프로젝트를 수정하거나 후보를 실행하지 않습니다. 위 호출에서 새 파일을 만드는 주체는 호출자가 지정한 출력 리다이렉션입니다.

결과에서 다음을 읽습니다.

필드 읽는 방법
state PROPOSED이면 후보가 생성됐다는 뜻
candidate_source 실제 생성된 Go 코드
edit_start, edit_end 원본의 0부터 시작하는 바이트 구간, 끝 위치는 제외
program_digest, semantic_digest Gooo 입력과 의미 모델의 식별값
source_digest, candidate_digest 원본과 생성 코드의 식별값
admission.state 독립된 검증·채택 근거가 없다면 UNKNOWN
mutation_authority, promotion_authority 이 후보의 자동 수정·승격 권한은 각각 0

후보 생성 성공과 채택 여부 UNKNOWN은 모순이 아닙니다. 파일을 만들어 낸 사실과 그 파일을 사용해도 된다는 판단은 서로 다른 질문입니다.

원본의 선택된 호출 구간만 교체하며, 선택한 기존 오류 처리 블록은 바이트 그대로 복사합니다. 원래 쓰기 호출은 한 번 평가됩니다. 구문·바인딩 검사만으로 전체 프로그램의 타입, 실행 효과, 의미적 동등성이 증명되지는 않습니다.

호출 형식은 병합된 어댑터 구현에 근거합니다. 아래 실행 증거는 CI의 컴파일러 API와 실제 CLI 패키지 검증에 대한 것입니다. 이 문서의 셸 실습 전체를 별도 사용자 세션에서 실행했다는 증거로 바꾸어 말하지 않습니다.

5. 실제로 무엇이 달라졌나요?

#851의 native CI는 같은 활성 CLI 테스트 원본을 고정한 뒤, 원래 구현과 생성된 후보를 각각 Go 빌드 overlay로 실행했습니다. 기존 프로젝트 파일을 직접 덮어쓴 실험이 아닙니다.

고정된 사용 사례 원본 검사 생성 후보 검사
사람용 결과의 쓰기를 거절하는 출력 대상 FAIL PASS
JSON 결과의 쓰기를 거절하는 출력 대상 PASS PASS
정상적인 사람용 결과 출력 PASS PASS
JSON 패키지 결과의 바이트 동일 재실행 PASS PASS
합계 3 PASS / 1 FAIL 4 PASS / 0 FAIL

첫 행의 PASS는 출력이 성공했다는 뜻이 아닙니다. 출력 실패를 요구한 사례에서 CLI가 실패를 올바르게 보고했다는 뜻입니다. 테스트 프로세스의 종료 코드는 원본 1, 생성 후보 0으로 관측됐습니다.

이는 네 사례에서 확인한 오류 처리 변화입니다. 언어 전체 완성률, 임의의 Go 코드에 대한 안전성, 속도 향상이나 메모리 감소를 뜻하지 않습니다. 시간·메모리 개선은 별도의 비교 가능한 관측 쌍이 필요합니다.

정확한 입력과 CI 근거를 더 깊게 추적하기
  • 검사된 PR head: 1147138e038ef56862af488a5a932152cef53620.
  • 생성 프로그램: sha256:f3ac58d6b47a055aa19fddc6ad848134446003b870d3cbfe59036e5217039b1e.
  • 의미 IR: sha256:37f2dd73d819730bca2665d413dc60b595544d561f1f88d50b29007def16e2ee.
  • 원본: sha256:5bd27e33e18e8c5dc87f25c0cd4004ee370cfa7dc441c85d89bb03fd333a8937.
  • 생성 후보: sha256:e65ab82fed6b572ae14098255273fa43df4e34551c5275e44655e60aaa5ddf9d.
  • 활성 테스트 원본 집합: sha256:6f948a474af349fee2a4655b2ee3ad9b1c44854e6bc9bc98513997190ee113ba.
  • 생성·실행 artifact 10336683386의 test.json에서 gooo guard witness와 TestGoErrorGuardGeneratedCandidateUsesFrozenNativeOracle를 찾습니다.
  • 정상 병합과 최종 CI 판정 기록은 기능 사례의 결과와 전체 개발 브랜치 수용을 분리해서 남깁니다.

이 실행은 활성 CLI 테스트 원본 112개와 이름이 지정된 런타임 Gooo 입력 2개를 포함합니다. 그 식별값이 전체 의존성·운영 환경을 모두 포괄한다고 주장하지 않습니다. GitHub artifact의 보존 기간은 유한하므로 링크를 영구적인 배포물로 취급하지 않습니다.

6. UNKNOWN이면 어떻게 진행하나요?

결과 의미 다음에 할 일
PROPOSED + 채택 UNKNOWN 후보는 있으나 별도 검증 근거가 없음 고정한 기대값으로 후보를 검증
UNKNOWN 함수가 없거나, 선택이 모호하거나, 지원하지 않는 형태 기록된 원인과 다음 연산을 읽기
REFUTED 원본·처리 블록의 식별값 등이 선언과 모순됨 잘못 연결된 입력을 조사하고 새 시도를 별도로 기록

UNKNOWN에는 stage, step, reason, unknown_class, next_operation, blocked_by가 있습니다. 이름을 보고 원인을 추측하기보다 어느 단계에서 무엇이 없어 멈췄는지 읽습니다. 이 프로필에서 원본 pin 불일치는 단순한 증거 누락이 아니라 REFUTED입니다.

다른 수정 전략을 시도할 수는 있지만, 성공시키려고 검증 기준을 낮추거나 기존 실패 기록을 지우지는 않습니다. 오류 읽기와 고정된 목표로 선택하기를 함께 참고하세요.

7. 어떤 Go 코드까지 지원하나요?

v1은 자유 함수이며 제네릭이 아니고, 결과가 int 하나인 형태를 다룹니다. 결과·진단 출력은 서로 다른 io.Writer 매개변수여야 합니다. 인접한 분기에서 이미 존재하는 쓰기 오류 검사, 진단 출력, 반환을 찾고, 선택된 형제 분기의 버려진 fmt.Fprintf 결과에 연결합니다.

임의의 인터페이스, closure, 복잡한 제어 흐름을 알아서 해석하는 범용 수정기는 아닙니다. 지원하지 않는 모양은 후보를 억지로 만들어 통과시키지 않습니다.

반환만 하는 오류 처리와 로컬 writer 인터페이스를 다루는 v2는 컴파일러 PR #854의 개발 브랜치 병합본 1c0d251...에 포함됩니다. Gooo 수정 프로그램 작성하기에서 그 병합 버전에 맞는 선언과 입력, 지원 경계, 실제 다섯 사례의 실행 근거를 읽을 수 있습니다. 실제 공개 CLI에 생성 코드를 적용하는 경로는 PR #853에서 별도로 추적합니다. 이 문서의 v1 입력과 v2의 원본·프로그램 식별값은 서로 바꾸어 사용하지 마세요.

8. 이것이 자기개선과 어떻게 연결되나요?

실제 실패 관측
  -> Gooo로 대상과 수정 조건 선언
  -> 원본과 의미 IR에 연결된 코드 후보 생성
  -> 고정된 기대값으로 별도 실행 검증
  -> 정해진 권한 안에서 채택 또는 기각
  -> 다음 실행이 채택된 결과를 실제 사용

초기의 실제 오류 수정 #849는 어시스턴트가 작성한 Go 코드였습니다. 뒤에 추가한 생성 기능으로 그 과거 수정까지 언어가 자율적으로 수행했다고 다시 이름 붙이지 않습니다.

이후에는 생성된 코드가 실제 구현에 들어가고, CI와 다음 실행이 그 결과를 사용하는 경로를 연결합니다. 원시 생성물 뒤에 형식 정리가 필요하다면 원시 후보, formatter 입력·출력, 최종 후보의 식별값을 따로 남깁니다. 예를 들어 #853은 Gooo 생성 구간의 적용과 CI가 제공한 형식 보정을 구분해서 기록합니다.

언어가 후보를 만들었다는 사실은 스스로 병합하거나 평가 기준을 바꿀 권한이 아닙니다. 후보 생성, 실행 증거, 채택, 배포, 다음 사용은 각각 별도의 사건입니다. 개발 과정도 이 provenance의 일부입니다.

테스트·실행 비용·재사용 · Provenance와 결정 · 거버넌스와 기여

Clone this wiki locally