Skip to content

Commit 8e059e2

Browse files
author
jun0
committed
[rustjava-upstream-sync-squash-defeats-convergence] docs: record the squash root cause, correct approach doc §5 premise
Gate3 --squash collapses each sync PR to a single parent, so origin/main never records the upstream cuts as ancestors. Proven by parent counts: 6bfe97c/11ef5010/4bb796de/3a597768 all have 1 parent, while the S4 branch commit 34a4235 has 2 (c80638a + 3296139). approach doc §5's per-round conflict predictions assumed the base advances. It did not, so S4 met 20 conflicts where the table predicted 0.
1 parent c118d21 commit 8e059e2

5 files changed

Lines changed: 223 additions & 0 deletions

File tree

‎REPORT.md‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,35 @@
11
# REPORT
22

3+
## [2026-08-27] upstream 동기 근인 확정 — 게이트③ `--squash` 가 계보를 버린다 (rustjava-upstream-sync-squash-defeats-convergence)
4+
- 무엇을: S1~S4(PR #11·#13·#16·#17)가 **전건 `merged=true`** 인데도 `merge-base origin/main upstream/main`
5+
이 fork 시점 **`62cf0c6a`** 그대로이고 behind **33** 이 줄지 않던 근인을 확정했다. 근인은 게이트③
6+
제품 repo **`--squash`** 다 — 네 머지커밋의 **부모가 전건 1개**이고(커밋 7·10·15·21이 각각 1로 접힘),
7+
반면 브랜치 `34a4235` 는 부모 **2개**(`c80638a`+`3296139`)인 진짜 머지였다.
8+
⇒ ★**계보는 브랜치에 있었고 게이트③이 버렸다** — cherry-pick·브랜치 재작성 가설은 실측으로 기각.
9+
처방(갈래 ⒞의 ⒜)으로 `origin/main` 위에 `git merge -s ours 3296139` 를 얹었다. `1f356ae`·`af4f6f8`·
10+
`822504b` 는 전부 `3296139` 의 조상이라 **한 머지가 네 컷을 덮는다**.
11+
- 왜: 내용은 이미 들어와 있는데 **계보가 없어서** git 이 영원히 「33 뒤」라고 답했고, 그 결과
12+
**다음 회차가 앞 회차가 이미 닫은 충돌을 처음부터 다시 열었다** — 회차별 충돌 **2 → 5 → 11 → 20 단조증가**.
13+
계획서 §5 는 S4 를 「새 충돌 **0**」으로 예측했는데 실측은 **20**이었다. 그 표의 수는
14+
**base 가 전진한다는 전제 위의 수**였고 그 전제가 깨져 있었다.
15+
- 사용자 영향: **제품 코드 변경 0** — 트리 오브젝트 SHA 가 `origin/main` 과 **동일**(`c4f57d10…`)하므로
16+
런타임 동작은 1바이트도 바뀌지 않는다. 얻는 것은 **다음 동기 회차의 비용**이다:
17+
`merge-base` **`62cf0c6a` → `3296139c`** · behind **33 → 18** · S1~S4 컷 조상 **0/4 → 4/4**.
18+
- 검증: 트리 변경 0 근거 = **트리 SHA 동일**(`git diff 3a59776..c118d21` **0줄**).
19+
★`git diff --stat` 빈 출력은 `-s ours` 에서 **정의상 항상 참**이라 근거로 쓰지 않았다(S4 워크로그 교훈).
20+
`.rs` 변경 0 이므로 cargo 4종은 트리 불변으로 담보된다. `scripts/check-worklog-json.py` rc=0.
21+
- ★**후속 추천 (1) — 총괄 몫. 이 세션은 손대지 않았다**:
22+
게이트③ **제품 repo `--squash` 규율에 «upstream 동기 PR 예외»를 넣을지 총괄이 판정하라**
23+
(`~/orchestrator/ORCHESTRATOR.md` 2곳 · `~/orchestrator/templates/merge-ticket.tpl` 스니펫 1곳 —
24+
★**orchestrator 소관이라 RustJava 세션이 고치지 않는다**).
25+
★★**이 PR 자체가 `--squash` 로 착지하면 위 처방이 그대로 무효가 된다** — 부모 2개가 1개로 접히며
26+
`3296139` 조상 관계가 사라지고 `merge-base` 는 `62cf0c6a` 로 되돌아간다. 반드시 `gh pr merge --merge`.
27+
★**회차마다 브랜치에 `-s ours` 를 다시 넣는 현행 방식은 러닝머신이다** — S4 의 `c80638a` 가 정확히 그
28+
처방이었는데 PR #17 의 스쿼시에 함께 사라졌고, 이 리니지에서 **네 번** 반복됐다.
29+
★★**`wie` 도 같은 함정 위에 있다 — behind 1067.** 예외 판정은 RustJava 단독 문제가 아니다.
30+
- ★**후속 추천 (2)**: S5~S7 의 「새 충돌」을 **이 PR 이 `--merge` 로 착지한 «뒤»** 재측정하라 —
31+
`merge-base` 가 `3296139` 인 상태에서 잰 수라야 다음 회차의 실제 기준선이다(워크로그 `#p1`).
32+
333
## [2026-08-27] upstream 동기 S4 — 컷 `3296139` 머지 (rustjava-upstream-sync-s4)
434
- 무엇을: upstream `3296139`(#184 CLI classpath) 까지 **8커밋**을 머지했다(GlobalRef · CDC text API ·
535
monitor 인자 일반화 · classfile 오류 은닉 · tokio 1.53). 충돌 **2** 해소 —

‎STATE.md‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
# STATE
22

33
## 진행중
4+
- [rustjava-upstream-sync-squash-defeats-convergence] ★**S1~S4 가 착지하고도 fork 가 upstream 에
5+
한 걸음도 가까워지지 않은 근인을 확정하고 계보를 기록했다.** 근인 = 게이트③ 제품 repo **`--squash`**.
6+
증명은 **머지커밋 부모 수**다 — `6bfe97c4`·`11ef5010`·`4bb796de`·`3a597768` **전건 1개**(커밋 7·10·15·21이
7+
각각 1로 접힘). ★**반증 시도는 실패했다(= 가설이 맞다)**: 브랜치 `34a4235` 는 부모 **2개**
8+
(`c80638a`+`3296139`)인 진짜 머지 ⇒ **계보는 브랜치에 있었고 스쿼시가 버렸다**(cherry-pick 가설 기각).
9+
처방 = `origin/main` 위 `git merge -s ours 3296139` — **트리 오브젝트 SHA 동일**(`c4f57d10…`)로 트리 변경 0.
10+
★`git diff --stat` 빈 출력은 `-s ours` 정의상 항상 참이라 근거로 쓰지 않았다(S4 교훈).
11+
효과: `merge-base` **`62cf0c6a` → `3296139c`** · behind **33 → 18** · 컷 조상 **0/4 → 4/4**.
12+
★★**이 PR 이 `--squash` 로 착지하면 위 전부가 무효다** — 반드시 `gh pr merge --merge`.
13+
★**회차마다 `-s ours` 를 다시 넣는 지금 방식은 러닝머신이다** — S4 의 `c80638a` 가 정확히 그 처방이었는데
14+
PR #17 의 스쿼시에 함께 지워졌다(이 리니지에서 네 번 반복). **PR 대기 — 게이트③ 미착지.**
415
- [rustjava-upstream-sync-s4] upstream 컷 `3296139`(#184 GlobalRef · CLI classpath · CDC text) 머지 —
516
충돌 **2** 해소(`java/lang/thread.rs` · `jvm/src/jvm.rs`). ★**첫 조치가 `git merge -s ours --no-ff 822504b`**
617
— 그것이 ★**충돌 20 → 2**를 만들었다. **PR 대기 — 게이트③ 미착지.**

‎docs/upstream-sync-approach.md‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,24 @@ upstream 은 여기서만 `UTF-8`/`EUC-KR` 하드코딩을 유지한다 ⇒ 그
221221
★**「새 충돌」은 «해당 컷에서 처음 충돌하는 파일 수»다.** 앞 회차가 착지하면 뒤 회차의 기준선이
222222
바뀌므로 **각 회차 착수 시 재측정이 필수**다(§0 의 교훈 그대로).
223223

224+
> ★★**[2026-08-27 정정 — 이 표의 「새 충돌」은 «base 가 전진할 때»의 수다. 그 전제는 S1~S4 에서 깨져 있었다.]**
225+
> 위 「앞 회차가 착지하면 뒤 회차의 기준선이 바뀐다」는 **거짓이었다.** 게이트③이 제품 repo 를
226+
> `--squash` 로 착지시키므로 PR 브랜치의 upstream 머지 부모가 버려지고, `origin/main` 은 **내용만**
227+
> 받은 채 **계보는 fork 시점(`62cf0c6a`)에 머문다.** ⇒ `git merge-base origin/main upstream/main` 이
228+
> 전진하지 않으므로 **다음 회차는 앞 회차가 이미 닫은 충돌을 처음부터 다시 연다.**
229+
>
230+
> 실측(S1~S4 착지 «후»): 머지커밋 `6bfe97c4`·`11ef5010`·`4bb796de`·`3a597768` **전건 부모 1개**(=squash) ·
231+
> `merge-base` **`62cf0c6a` 불변** · behind **33** · 회차별 충돌 **2 → 5 → 11 → 20 단조증가**
232+
> (표의 예측치 2 → +5 → +9 → **0** 과 어긋난다 — 특히 S4 는 「0」 예측에 **20**을 만났다).
233+
>
234+
> ⇒ ★**S5~S7 의 「0」(`Cargo.lock`만)도 같은 전제 위의 수다. 그대로 믿지 마라 — «하한»으로 읽어라.**
235+
> 이 표를 쓰기 전에 **반드시** `git merge-base origin/main upstream/main` 을 먼저 재고, 그것이
236+
> 직전 컷으로 전진해 있지 않으면 **해당 회차 착수 시 `merge-tree` 로 전량 재측정**한다.
237+
>
238+
> **처분**: 계보 기록 커밋(`git merge -s ours <컷>` · 트리 변경 0)으로 `merge-base` 를 `3296139`
239+
> 까지 끌어올렸다(behind 33 → 18). ★**단 이 커밋 자체가 `--squash` 로 착지하면 무의미하다** —
240+
> 게이트③ 예외 판정은 총괄 소관(`REPORT.md` 후속 추천 참조).
241+
224242
★**S1~S3 이 이 동기화의 «전부»다** — 세 회차가 판단을 다 쓰고, 각각 **한 축씩만** 다룬다.
225243
검수자가 한 회차에서 읽어야 하는 것은 **우리 해소분**이지 upstream 원본 diff 가 아니다:
226244

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
{
2+
"schema": 1,
3+
"date": "2026-08-27",
4+
"title": "S1~S4 가 착지하고도 fork 가 upstream 에 가까워지지 않은 근인 확정(게이트③ --squash) + 계보 기록으로 behind 33 → 18",
5+
"services": [
6+
"RustJava"
7+
],
8+
"taskId": "rustjava-upstream-sync-squash-defeats-convergence",
9+
"summary": "S1~S4(PR #11·#13·#16·#17)가 전건 merged=true 인데 merge-base origin/main upstream/main 은 fork 시점 62cf0c6a 그대로였고 behind 33 이 줄지 않았다. 근인은 게이트③ 제품 repo --squash 다 — 네 머지커밋(6bfe97c4·11ef5010·4bb796de·3a597768) 전건 부모 1개로, 7·10·15·21 커밋이 각각 1커밋으로 접혔다. 가설 반증 시도는 실패했다(= 가설이 맞다): 브랜치 feat/rustjava-upstream-sync-s4 의 34a4235 는 부모 2개(c80638a + 3296139)인 진짜 머지이므로 계보는 브랜치에 있었고 스쿼시가 버린 것이다. 갈래 ⒞ 채택 — ⒜ origin/main 위에서 git merge -s ours 3296139(트리 SHA 동일 c4f57d10 = 트리 변경 0)로 네 컷 전건을 조상으로 기록해 merge-base 62cf0c6a → 3296139c · behind 33 → 18 · 컷 조상 0/4 → 4/4. ⒝ 게이트③ 규율 예외는 총괄 소관이라 손대지 않고 REPORT.md 후속 추천으로 올렸다. ★이 PR 자체가 --squash 로 착지하면 ⒜는 무효다.",
10+
"changes": [
11+
"계보 기록 — origin/main(3a59776) 위에서 git merge -s ours 3296139. 1f356ae·af4f6f8·822504b 는 전부 3296139 의 조상이라 한 머지가 네 컷을 덮는다. 트리 변경 0 근거는 트리 오브젝트 SHA 동일(c4f57d10…)이다 — git diff --stat 빈 출력은 -s ours 에서 정의상 항상 참이라 근거로 쓰지 않았다(S4 워크로그 교훈).",
12+
"docs/upstream-sync-approach.md §5 — 「앞 회차가 착지하면 뒤 회차의 기준선이 바뀐다」가 거짓이었음을 정정. 표의 「새 충돌」이 base 전진 전제 위의 수임을 명시하고, 표를 쓰기 전 merge-base 를 먼저 재고 전진해 있지 않으면 merge-tree 로 전량 재측정하도록 규율화. 예측 대 실측 불일치(S3 +9↔11 · S4 0↔20) 기재.",
13+
"docs/worklog/2026-08-27-upstream-sync-squash-convergence.{md,json} 신설.",
14+
"STATE.md · REPORT.md 갱신."
15+
],
16+
"deploy": {
17+
"sha": "",
18+
"urls": []
19+
},
20+
"verification": "재실측(회신 시점): merge-base origin/main upstream/main = 62cf0c6a(2026-06-28) · S1~S4 컷 origin/main 조상 0/4(upstream/main 조상 4/4) · rev-list --count origin/main..upstream/main = 33 · PR #11/#13/#16/#17 merged=true(커밋 7/10/15/21) · 회차별 충돌 2→5→11→20. 근인 증명: gh api 로 얻은 네 merge_commit_sha 의 git cat-file -p parent 줄 수 전건 1. 반증 시도: 브랜치 34a4235 parent 2개(c80638a·3296139) + merge-base --is-ancestor 3296139 <branch> = YES ⇒ 계보는 브랜치에 있었고 스쿼시가 버렸다. 처방 후: tree BEFORE(3a59776)=tree AFTER(c118d21)=c4f57d10bce2087cebe2e1156f716f6ba8f75335 · git diff 3a59776..c118d21 = 0줄 · merge-base → 3296139c · behind 33 → 18 · 컷 조상 4/4. ★제품 코드(.rs) 변경 0 이라 cargo 축은 트리 불변으로 담보된다(트리 SHA 가 origin/main 과 동일).",
21+
"issues": [
22+
"★이 PR 이 --squash 로 착지하면 ⒜는 무효다 — 부모 2개가 1개로 접히며 3296139 조상 관계가 다시 사라지고 merge-base 는 62cf0c6a 로 되돌아간다. 반드시 gh pr merge --merge 로 착지시켜야 한다.",
23+
"★같은 처방이 이미 한 번 지워졌다 — S4 브랜치의 c80638a(「record upstream cut 822504b as merged (tree unchanged)」)가 -s ours 계보 기록이었는데 PR #17 의 스쿼시에 함께 사라졌다. ⇒ 브랜치 처방만으로는 매 회차 무효화된다.",
24+
"머지하지 않았다 — 게이트②·③은 별 세션이다.",
25+
"upstream/main 헤드까지 -s ours 하지 않았다. S5~S7 내용은 실제로 없어 그것까지 얹으면 거짓 주장이 되고 남은 물량이 조용히 사라진다.",
26+
"★wie 도 같은 함정 위에 있다(behind 1067) — 이 repo 에서 고칠 수 없다."
27+
],
28+
"proposals": [
29+
{
30+
"title": "게이트③ 제품 repo `--squash` 규율에 upstream 동기 PR 예외를 넣을지 총괄이 판정하라",
31+
"plainSummary": "우리 fork 는 원본 저장소의 변경을 정기적으로 받아온다. 그런데 머지 방식이 «이력을 하나로 접는» 방식이라, 받아온 사실 자체가 기록되지 않는다. 그래서 다음 번에도 git 은 «아직 안 받았다»고 답하고 같은 충돌을 처음부터 다시 낸다.",
32+
"userBenefit": "동기화 회차마다 앞 회차가 이미 푼 충돌을 다시 푸는 낭비가 사라진다. 실측으로 그 낭비는 회차마다 커졌다 — 충돌 2 → 5 → 11 → 20. 예외가 없으면 남은 S5~S7 에서 더 나빠진다.",
33+
"why": "게이트③ 규율이 「제품 repo = --squash」를 못박는데(ORCHESTRATOR.md 2곳 · templates/merge-ticket.tpl), --squash 는 PR 의 부모 관계를 버리므로 upstream 커밋이 조상으로 기록될 방법이 없다. 실측: 네 머지커밋 전건 부모 1개 · merge-base 는 fork 시점 62cf0c6a 불변 · behind 33 불변. 반면 브랜치 34a4235 는 부모 2개였다 ⇒ 계보를 버린 것은 게이트③이다. ★같은 템플릿이 형제 증상을 이미 알고 있다: 「부모 PR 이 --squash 로 착지하면 자식 PR 은 공통 조상이 사라져 add/add 로 전건 충돌한다」. ★wie 도 같은 함정 위에 있다(behind 1067) — 예외는 RustJava 단독 문제가 아니다.",
34+
"tradeoff": "⑴upstream 동기 PR 만 --merge 예외로 열면 계보가 남고 다음 회차 base 가 전진하지만, 제품 repo 이력에 머지커밋이 섞여 「티켓별 1커밋」 관행이 그 회차만 깨진다(orchestrator-ops 가 이미 같은 이유로 반대 방향 예외를 쓰고 있으므로 선례는 있다). ⑵예외 없이 회차마다 -s ours 계보 커밋을 넣는 방식은 이번처럼 스쿼시에 함께 지워져 무효다 — 실제로 S4 의 c80638a 가 그렇게 사라졌다. ⑶현상 유지면 S5~S7 이 앞 회차 충돌을 전부 다시 열고, 계획서 §5 의 「충돌 0」 예측은 남은 셋에서도 무의미하다.",
35+
"effort": "S — 규율 문안 2곳(ORCHESTRATOR.md)과 스니펫 1곳(templates/merge-ticket.tpl). 판정 자체는 XS.",
36+
"target": "~/orchestrator/ORCHESTRATOR.md · ~/orchestrator/templates/merge-ticket.tpl (★orchestrator 소관 — RustJava 세션이 고치지 않는다)"
37+
},
38+
{
39+
"title": "S5~S7 의 「새 충돌」을 재측정할지 결정하라 — 표의 수는 전부 전진하는 base 위의 예측이다",
40+
"plainSummary": "남은 세 회차의 난이도 예측이 «앞 회차가 제대로 반영됐다»는 가정 위에 쓰여 있었다. 그 가정이 틀렸던 것이 이번에 밝혀졌으니, 예측을 다시 재야 계획이 쓸모 있다.",
41+
"userBenefit": "남은 회차의 크기를 실제 수로 잡을 수 있다 — 지금은 「충돌 0」으로 적힌 회차가 실제로 20충돌일 수 있고, 그러면 티켓 size/timeout 이 처음부터 틀린다(S4 가 정확히 그랬다).",
42+
"why": "§5 표는 S4~S6 을 「충돌 0 · 물량」으로 잡았는데 S4 실측은 20 이었다. 예측 대 실측이 S3(+9↔11)·S4(0↔20) 연속으로 어긋났고, 어긋난 이유가 이 회차가 확정한 근인이다. ★단 재측정은 이 PR 이 --merge 로 착지한 «뒤»에 해야 의미가 있다 — merge-base 가 3296139 인 상태에서 잰 수라야 다음 회차의 실제 기준선이다. 지금 재면 또 낡은 수가 된다.",
43+
"tradeoff": "⑴착지 후 재측정하면 정확하지만 별 회차가 하나 붙는다(git merge-tree 만 돌리면 되므로 XS 다). ⑵지금 브랜치 위에서 미리 재면 회차를 아끼지만, 게이트③이 --squash 로 착지시키면 그 수가 통째로 무효가 된다. ⑶재측정을 건너뛰면 S5 티켓이 「0충돌 물량」으로 발권되고 실제로는 설계 판단이 필요한 회차가 될 위험이 남는다.",
44+
"effort": "XS — git merge-tree --write-tree --name-only 3회 + §5 표 갱신.",
45+
"target": "docs/upstream-sync-approach.md §5"
46+
}
47+
],
48+
"resolvedIssues": [],
49+
"adoptedProposals": [
50+
"2026-08-27-upstream-sync-s3#p0"
51+
],
52+
"declinedProposals": []
53+
}

0 commit comments

Comments
 (0)