Skip to content

Writing a Repair Program

kimjooyoon edited this page Oct 2, 2026 · 2 revisions

Gooo 수정 프로그램 작성하기

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

Gooo 수정 프로그램은 어느 입력에 어떤 변경을 제안할지를 선언합니다. 컴파일러는 선언에 연결된 코드를 만들지만, 그 코드의 채택까지 스스로 승인하지는 않습니다.

이 가이드에서는 정책 생성 프로필의 사람용 출력이 실패했는데도 성공으로 끝나던 동작을 다룹니다. 같은 함수에 이미 있는 출력 오류 처리 블록을 선택해 수정 후보를 만듭니다. 임의의 Go 코드를 알아서 고치는 범용 도구를 설명하는 문서는 아닙니다.

이 실습의 기준은 개발 브랜치에 병합된 #854의 버전 1c0d251과 Go 1.27.0입니다. 공개 릴리스 전체의 지원 약속과는 구분합니다.

먼저 알아둘 세 가지

질문 이 실습의 답
무엇을 입력하나요? Gooo 수정 선언과 고정된 원본 Go 파일
무엇을 얻나요? 생성된 Go 코드와 그 출처를 담은 JSON
원본이 자동으로 바뀌나요? 아닙니다. 적용·실행·채택은 별도 작업입니다.

처음부터 끝까지 한 흐름을 읽고 싶다면 오류 처리 코드 생성 실습을 먼저 볼 수 있습니다. 여기서는 선언을 어떻게 선택하고 해석하는가에 집중합니다.

1. 지원 버전과 실습 입력을 선택합니다

다른 작업과 분리된 체크아웃에서 다음 버전을 사용할 수 있습니다.

git clone https://github.com/kimjooyoon/meta-ontology-go.git gooo-repair-lab
cd gooo-repair-lab
git checkout 1c0d2519c6c80da127b57b932e1b280ef4676c77

입력은 internal/meta/policycompilation/testdata/go-error-guard/profile-original.go.golden입니다. 실제 과거 공개 CLI 구현을 보존한 원본이며, 현재 코드를 일부러 망가뜨려 만든 입력이 아닙니다.

이 파일에 연결된 원본 식별값은 sha256:7ee9cec15457d359c3df81d5ea54131c72a5eb909496500bbfdb91ac1bdfbc7a입니다. 다른 파일을 넣고 이 식별값을 그대로 사용하는 경우에는 원본 불일치로 거절되어야 합니다.

2. 수정 선택을 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:v2;function=runMetaPolicyGenerationProfile;writer=stdout;writer-type=interfaceWriter;source=sha256:7ee9cec15457d359c3df81d5ea54131c72a5eb909496500bbfdb91ac1bdfbc7a;handler=sha256:bc804b799d7c744cba976e1c83f66751fc4485ccc2840129d6fe35782e8affdb"
GOOO

문자열이 길지만, 선언하는 선택은 다섯 가지입니다.

선택 이 프로그램의 값 왜 필요한가요?
함수 runMetaPolicyGenerationProfile 다른 함수까지 고치지 않도록 대상을 한정합니다.
출력 매개변수 stdout 어떤 출력의 버려진 오류를 다룰지 정합니다.
로컬 writer 타입 interfaceWriter 이름만 비슷한 임의 타입을 출력 대상으로 추측하지 않습니다.
원본 식별값 source 어떤 원본 바이트를 전제로 한 요청인지 고정합니다.
기존 처리 블록 식별값 handler 가져올 오류 처리 블록을 고정합니다.

Source와 Candidate는 입력과 생성물을 나타내고, GuardWrite 활동이 둘을 연결합니다. 기존 Gooo 프런트엔드는 이를 의미 모델인 IR로 내립니다. 컴파일러는 그 모델의 입력 사용·결과 생성 관계와 실제 수정 활동이 맞는지 확인합니다.

go-error-guard:v2는 아무 버전 번호나 붙이는 표지가 아닙니다. 선택한 규칙의 의미와 지원 범위입니다. 다른 형태의 코드를 통과시키려고 v1의 의미를 암묵적으로 바꾸는 대신, 별도 프로필을 선택합니다.

3. 후보를 생성합니다

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

이 어댑터는 입력을 읽고 JSON을 표준 출력으로 내보냅니다. 위 예에서는 호출자가 지정한 리다이렉션이 임시 결과 파일을 만듭니다. 원본 프로젝트를 수정하거나 생성된 코드를 실행하지 않습니다.

jq가 있다면 큰 Go 코드 문자열을 펼치기 전에 다음 필드만 읽을 수 있습니다.

jq '{state, reason, activity_id, program_digest, semantic_digest,
     source_digest, candidate_digest, edit_start, edit_end,
     admission, mutation_authority, promotion_authority}' "$work/proposal.json"
결과 읽는 방법
state: PROPOSED 선택한 규칙으로 후보가 생성됐습니다.
candidate_source 실제 생성된 Go 코드입니다.
edit_start, edit_end 원본의 선택 구간입니다. 0부터 시작하는 바이트 좌표이며 끝은 제외합니다.
admission.state: UNKNOWN 이 생성 결과 자체에는 독립된 채택 판정이 없습니다.
수정·승격 권한 0 후보가 프로젝트를 고치거나 승격할 권한을 얻은 것은 아닙니다.

이 버전은 원시 후보를 만듭니다. 사람이 보기 좋은 형식 정리가 필요할 수 있습니다. 뒤에서 소개하는 두 활동 파이프라인의 형식 정리 기능까지 이 병합 버전에 들어 있다고 가정하지 마세요.

이 문서의 호출 형식은 병합된 어댑터와 CI의 실제 생성 입력에 근거합니다. 문서의 셸 절차 전체를 별도 사용자 세션에서 실행했다는 뜻은 아닙니다.

4. 코드에서는 무엇이 바뀌나요?

기존 사람용 출력은 쓰기 호출을 한 뒤 그 오류를 버리고 성공을 반환했습니다. 생성된 후보는 같은 호출에 기존 실패 반환을 연결합니다.

아래는 읽기 쉽게 줄바꿈한 설명용 Go 조각입니다. 정확한 생성 바이트는 candidate_source와 그 식별값으로 추적합니다.

if _, err := fmt.Fprintf(
    stdout,
    "generated profile: %s\npolicy: %s\nartifact: %s\njudge: %s\nmanifest: %s\n",
    policycompilation.PublicProfileID,
    artifacts.paths[0], artifacts.paths[1], artifacts.paths[2], artifacts.paths[3],
); err != nil {
    return exitFailure
}
return exitOK

목표는 모든 경우를 성공으로 만드는 것이 아닙니다. 출력 실패를 정확하게 실패로 보고하면서, 이미 생성한 외부 파일과 정상 출력은 유지하는 것입니다.

따라서 이 변경은 모든 입력에서 원본과 동작이 같아야 하는 리팩터링이 아닙니다. 특정 실패 상황의 동작을 바꾸는 버그 수정 후보입니다. 코드 변환과 효과에서 두 종류의 검증 기준을 구분합니다.

5. 지원하지 않는 입력은 어떻게 읽나요?

상태 예 다음 판단
UNKNOWN / DIRECT_MISSING 선택한 함수가 없음 어떤 입력이나 대상 선언이 빠졌는지 확인합니다.
UNKNOWN / AMBIGUOUS 대상이 하나로 정해지지 않음 후보가 무엇을 선택해야 하는지 명확히 합니다.
UNKNOWN / UNBOUNDED 규칙이 지원하지 않는 타입·제어 흐름 지원 범위를 확인하고 다른 시도를 별도로 준비합니다.
REFUTED 원본 또는 처리 블록의 pin이 실제 입력과 다름 모순된 연결을 조사합니다. 증거 부족과 섞지 않습니다.

stage, step, reason, unknown_class, next_operation, blocked_by를 함께 읽습니다. UNKNOWN은 원본 프로그램의 의미가 틀렸다는 선언도, 모든 다른 작업을 중단하라는 뜻도 아닙니다.

다른 시도를 위해 선택을 바꿀 수는 있습니다. 다만 원본·선택·평가 기준이 바뀌었다면 새로운 시도로 구분해야 합니다. 예전 실패를 지우거나 기대값을 낮춰 같은 개선이 성공했다고 기록하지 않습니다.

6. 어떤 증거가 실제로 있나요?

같은 고정 기대값으로 원본과 생성 후보를 실행한 #854의 CI에서 다음이 관측됐습니다.

공개 정책 생성 프로필의 고정 사례 원본 생성 후보
사람용 출력 거절 FAIL PASS
JSON 출력 거절 PASS PASS
사람용 정상 출력 PASS PASS
JSON 정상 출력 PASS PASS
정확한 외부 생성 파일 4개 유지 PASS PASS
합계 4 PASS / 1 FAIL 5 PASS / 0 FAIL

첫 행의 PASS는 출력이 전달됐다는 뜻이 아닙니다. 출력 거절을 주입했을 때 CLI가 실패를 올바르게 보고했다는 뜻입니다. 이 다섯 사례는 정책 생성 프로필의 범위이며, 일반 생성 명령이나 정책 수정 프로필의 모든 동작까지 대신 증명하지 않습니다.

입력·IR·생성 코드와 수용 근거 추적하기
  • native producer head: 4eac9bdcb0cd1796e8c2a1bb74e3acd659411fab.
  • Gooo 프로그램: sha256:7c64ecf45b10ff7e49546615efaaf9c2b7ad1d7de993f5cf203645651e27d698.
  • 의미 IR: sha256:dee485c90b963efae03326845871a097e126de99771679341d99b60991c8333f.
  • 원시 생성 후보: sha256:61b0b3e5cac9ab4721831a28fee959a509bc859ce250d3a2414c2f4c7a44806e.
  • 생성·실행 artifact 10338929847의 test.json에서 gooo return guard witness와 TestGoReturnGuardActualPublicProfileUsesFrozenNativeOracle를 찾습니다.
  • 컴파일러의 최종 수용 기록은 전체 CI 수용과 위의 한정된 기능 사례를 구분합니다.
  • 공개 구현에 생성 코드를 적용하는 경로는 컴파일러 제안과 별도로 추적합니다.

이 해시들은 입력과 산출물의 동일성을 연결합니다. 작성자 신뢰, 모든 의존성의 무결성, 의미적 올바름 또는 사용자 효용까지 대신하지 않습니다. CI artifact는 보존 기간이 있으므로 영구 릴리스 파일로 취급하지 않습니다.

7. 생성·검증·채택을 왜 분리하나요?

후보를 만든 주체가 자기 평가 기준도 바꿔 성공을 선언하면, 무엇이 실제로 좋아졌는지 구분할 수 없습니다.

Gooo 선언은 선택을 명시하고, 생성 결과는 그 선택과 바이트를 연결합니다. 고정된 검사는 실제 동작을 비교하고, 채택은 정해진 권한 안에서 따로 결정합니다. 마지막으로 다음 실행이 채택된 결과를 사용해야 일회성 후보 생성 이상의 경로가 됩니다.

이 어댑터는 외부 CI 결과를 원래 후보 JSON에 덮어쓰지 않습니다. 따라서 과거 후보의 채택 상태 UNKNOWN과 그 뒤의 실행 근거가 함께 남을 수 있습니다. 개발 과정에서도 후보 커밋, 테스트 입력, CI 실행, 병합, 후속 실행을 서로 다른 사건으로 연결합니다.

거절도 정상적인 종료지만 개선 성공으로 세지는 않습니다. 결정적 재실행은 같은 결과를 얻었다는 근거이지, 유용해졌다는 근거가 아닙니다. 속도·메모리 개선 역시 비교 가능한 실제 전후 관측이 필요합니다.

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

지원 범위와 후속 실험

범위 선택과 경계
이 실습 버전의 v1 서로 다른 io.Writer, 인접한 분기, 진단 출력과 반환이 있는 처리기
이 실습 버전의 v2 명시한 로컬 writer 인터페이스, 먼저 반환하는 분기, 반환만 하는 처리기
별도 파이프라인 실험 Source -> RawCandidate -> Candidate로 생성과 형식 정리 연결
일반 생성 명령용 v3 준비 중첩된 사람용 출력 지점과 첫 실패에서 중단하는 동작을 명시

아래 두 항목은 위에서 고정한 병합 버전의 실습에 포함되지 않습니다. 파이프라인은 #855와 #856, 일반 생성 명령의 후속 사례는 #857에서 수용 여부와 실제 증거를 확인합니다. 준비된 v3의 여덟 사례를 이미 통과한 사례로 세지 않습니다.

Clone this wiki locally