|
16 | 16 | ※그 술어가 ★**«주석 안의 토큰»도 센다**는 것도 이때 드러났다(주석 한 줄 때문에 2로 읽혔다 → 문구 교체). 형제 제안을 이어받는 회차 몫이다. |
17 | 17 | - 검증: DoD 9명령 · 아래 절. |
18 | 18 | - ★후속 추천: **퇴화 재귀에 바닥을 깔 것인가**(M · 재진입 가드 ↔ 비-예외 실패 표현 — 후자는 460자리를 조용히 바꾼다). 상세 = `docs/worklog/2026-09-19-exception-reports-instead-of-aborting.md`. |
| 19 | +## [2026-09-19] 부분 클론도 «거절»할까 — ★**아니다. 모호했던 것은 «환경»이 아니라 «호출 하나»였다**(rustjava-partial-clone-refusal-decision) |
| 20 | +- 무엇을: 채택 제안 `2026-09-18-merge-drops-no-silent-git-failure#p0`(worklog json 기록). ★**거절하지 않는다** — 대신 `symbols()` 가 실패한 `git show` 를 «부재»로 읽기 «전»에 `git ls-tree` 로 그 경로가 트리에 있는지 묻는다. ★결정을 `preflight()` docstring 에 못박았다(다음 사람이 다시 묻지 않도록). |
| 21 | +- ★★**추측하지 않고 «진짜 부분 클론»을 만들어 쟀다**(`--filter=blob:none` · 범위는 알려진 사고 머지 `e53b2142^..e53b2142`): |
| 22 | + |
| 23 | + | 클론 | promisor | 결과 | 시간 | |
| 24 | + |---|---|---|---| |
| 25 | + | 완전 | — | `6 dropped` · **rc 1** | 2.5s | |
| 26 | + | blobless | ★**도달 가능** | `6 dropped` · **rc 1** — ★**완전히 동일** | 15.7s | |
| 27 | + | blobless(신선) | ★**도달 불가** | `0 dropped` · ★★**rc 0 = green** | 8.3s | |
| 28 | + |
| 29 | +- ★★**그래서 제안은 «절반만» 맞다**: 「부분 클론이면 아무것도 없는 것처럼 보인다」는 **그 자체로는 거짓**이다 — promisor 가 닿으면 git 이 blob 을 투명하게 받아 와 답이 **바이트 동일**하다. ⇒ ★**거절은 «돌아가는 설정»을 막는 것**이고, shallow 와 달리 부분 클론은 **없는 것을 가져올 수 있다**. |
| 30 | + ★**그러나 조용한 green 은 «실재»한다** — 조건이 좁을 뿐(promisor **도달 불가**). 그 상태에서 검사기는 `✓ … (3 file(s) examined)` 를 찍고 **rc 0** 으로 끝냈다(완전 클론은 6건 보고). |
| 31 | +- ★**방법 주의(자기정정)**: 첫 오프라인 측정은 **오염됐다** — 앞선 온라인 실행이 그 blob 들을 이미 캐시해 «맞는 답»이 나왔다. 위 수는 **신선한 클론 + 읽기 «전»에 원격을 깨뜨린** 형상에서 다시 잰 것이다. |
| 32 | +- ★**위험이 실현되나 — 실측 0**: `.github` 어디에도 `filter:` 가 **없고**(`merge_drops` 는 `fetch-depth: 0`) ⇒ 오늘 이 거짓 green 은 «개발자 노트북 + blobless + 오프라인»에서만 난다. ★그것이 **거절을 고르지 않은 이유**이지, **모호함을 남길 이유는 아니다** — 닫는 비용이 git 호출 하나로 드러났기 때문이다. |
| 33 | +- ★**왜 `ls-tree` 인가(대안 둘을 각각 기각한 근거)**: ⒜**거절** — 탐지는 된다(`remote.origin.partialclonefilter = blob:none` · ★`rev-parse --is-shallow-repository` 는 **false** 라 현행 preflight 가 못 잡는다)지만 **맞는 답을 내는 경우까지 막는다** ⒝**에러 문면 대조** — 두 실패는 문면으로 갈리지만(`does not exist in` ↔ `could not fetch … from promisor remote`) **둘 다 exit 128** 이고, preflight 를 만든 회차가 이미 «git 판올림에 약하다»며 미뤘다 ⒞★**`ls-tree` 는 «트리 객체»로 답한다** — 부분 클론은 blob 이 없어도 **트리는 갖는다**. 두 클론에서 **동작 동일** 실측(있으면 1항목·없으면 빈 출력·rc 0). |
| 34 | +- ★**양방향 축**(제품 스크립트): 거짓 green 형상 — 전 **rc 0 `0 dropped`** ↔ 후 ★**rc 2 `cannot measure: …:jvm-bytecode/src/class_definition.rs is in that tree but its content could not be read…`**. ★**과차단 0**: blobless + promisor 도달 가능은 고친 뒤에도 **rc 1 · 6 dropped** · 완전 클론도 **불변**. |
| 35 | +- ★**비용 유의차 없음**: 같은 범위 3회씩 — 전 **7.78/7.99/7.05s** ↔ 후 **6.39/6.72/8.06s**(구간 겹침) · DoD 기본 범위 **0.46s → 0.33s**. 추가 호출은 `show` 가 **이미 실패한** 경로에서만 돈다. |
| 36 | +- ★**재다가 발견했고 «고치지 않았다»**: 이 검사기의 **출력 순서가 실행마다 다르다**(findings 가 set 에서 나온다). `origin/main` 판본을 `PYTHONHASHSEED=random` 으로 5회 돌려 **순서 2종**(4+1). rc·집합은 동일하고 **줄 순서만** 움직인다 ⇒ ★**선행 결함**이고, 전/후 diff 에서 잠깐 «회귀»처럼 보였기에 적는다(후속 카드). |
| 37 | +- 검증: DoD 9명령 · 아래 절. |
| 38 | +- ★후속 추천: **findings 를 정렬해 두 실행을 비교 가능하게 할 것인가**(S). 상세 = `docs/worklog/2026-09-19-partial-clone-blob-vs-absence.md`. |
| 39 | + |
| 40 | +## [2026-09-18] 리터럴이 «아닌» 이름으로 exception() 을 부르는 자리는 몇 개인가 — ★**0 이다**(rustjava-count-nonliteral-exception-call-sites) |
| 41 | +- 무엇을: 채택 제안 `2026-09-18-named-exception-classes-are-loadable#p0`(worklog json `adoptedProposals` 기록). ★**순수 측정 회차 — `.rs` 0줄 · `scripts/` 0줄.** 산출은 «수»와 «술어»다. |
| 42 | +- ★**답**: bare `exception(` **847** = 정의 **1** + ★**리터럴(java/javax) 846** + 리터럴(그 밖) **0** + ★★**비리터럴 «0»**. |
| 43 | + ⇒ 검사기가 보는 집합과 실제 호출부 집합이 **지금은 일치한다** — 사각의 «크기»는 **0**이다. |
| 44 | +- ★`literal_other` 도 **0** 이라 따로 적는다: 검사기는 `java/` 접두가 아닌 리터럴(`org/rustjava/…`)도 건너뛰는데 **그런 것도 없다** ⇒ 새는 축은 «접두»가 아니라 «런타임 조립»뿐이고, 그것이 0이다. |
| 45 | +- ★★**술어를 검사기의 것과 «같게» 맞췄다**(수가 비교 가능해야 한다): 같은 파일 집합(`target/`·`.git` 가지치기) · 같은 전파일 매칭(rustfmt 줄바꿈을 넘는다). 다른 것은 둘뿐 — ⑴`java/` 요구를 **뺐다**(「실을 수 있나」가 아니라 「이름이 있기는 한가」를 묻는다) ⑵★`exception(` 부분일치가 **다른 함수 8종**(`assert_exception(`·`suppress_io_exception(` 등 **41자리**)을 함께 쓸어담는다 — 그 첫 인자는 `jvm` 이지 클래스 이름이 아니다. ⇒ **분리했다**. 안 갈랐으면 ★**M=33 이라는 «틀린 답»**이 나온다. |
| 46 | +- ★★**「내가 찾은 게 전부다」로 주장하지 않았다 — 술어를 양방향으로 시험했다**: |
| 47 | + ⒜**대조군** — 한 줄에 든 리터럴만 세면 **812**, 이는 검사기 docstring 이 적은 **자기 초판 수**(846 − rustfmt 가 쪼갠 34)와 **정확히 일치**한다 ⇒ 파일 집합·앵커가 같다는 증거. |
| 48 | + ⒝**개악 주입**(제품 파일 `jvm/src/jvm.rs` · 측정 후 원복 · 트리 클린): 변수 · `&format!` · `const` · **raw string** → 전건 `nonliteral`(**0→4**) · 비-java 리터럴 → `literal_other`(**0→1**). ★raw string 이 «리터럴»이 아니라 «사각»으로 잡히는 것이 의도한 편향이다 — **모르는 철자는 안전 칸이 아니라 사각 칸으로 떨어진다**. |
| 49 | + ⒞**음성 탐침**: `exception (`(공백) **0** · `Jvm::exception` 값·UFCS 전달 **0** · `macro_rules!` 보유 파일 **2**(어느 쪽도 식별자를 조립하지 않는다). |
| 50 | +- ★**못 보는 것**: ⑴★**매크로는 «본문에서 한 번» 세어진다** — `arrays.rs` 의 매크로 4개가 `exception(` **3자리**를 갖고 **22회** 전개되므로 전개 기준이면 **865**다(846 아님). ★이름은 전부 리터럴이라 **답(M=0)은 안 바뀐다** — 사각이 아니라 «단위» 차이이고, 검사기도 이 회차도 소스 단위다. ⑵토큰 붙이기 매크로가 식별자 `exception` 을 조립하면 어떤 텍스트 술어도 못 본다(이 트리에선 0 — 바닥이지 증명이 아니다) ⑶「리터럴인데 오타」는 검사기의 기존 한계 그대로 ⑷`new_class(`·`find_class(` 는 제안의 요지 밖이라 세지 않았다. |
| 51 | +- ★**제안 판정**: 전제(「아무도 크기를 모른다」)는 **참이었다** — 아무도 재지 않았다. 답이 0이라는 것은 검사기의 바닥이 «허구»라는 뜻이 아니라 ★**지금은 «딱 맞는다»**는 뜻이다. 다음 회차가 `jvm.exception(&name, …)` 을 쓰는 것을 막는 것은 아무것도 없고, 위 술어가 그것을 알아챌 물건이다. |
| 52 | +- ★**게이트로 «승격하지 않았다»** — 제안이 요구한 것은 «계수»이지 «관문»이 아니고, 베이스라인 0 인 관문은 **자기 대가**(변수로 이름을 넘기는 정상 리팩터가 red 가 된다)를 갖는 별 결정이다. ⇒ 후속 제안 카드로 남겼다(계약 「범위를 넓히지 마라」). |
| 53 | +- 검증: 아래 «검증» 절 참조(DoD 9명령). |
| 54 | +- ★후속 추천: **베이스라인이 0인 지금 이 술어를 관문으로 올릴 것인가**(S). 상세 = `docs/worklog/2026-09-18-nonliteral-exception-call-sites.md`. |
19 | 55 |
|
20 | 56 | ## [2026-09-18] 「조용한 실패」를 잡는 검사기에 «조용히 통과하는 길»이 있었다 (rustjava-merge-dropped-symbols-checker-swallows-git-failures) |
21 | 57 | - 무엇을: `scripts/check-merge-dropped-symbols.py` 의 `run()` 이 git 실패를 `None` 으로 삼키고 호출부가 전부 `(… or "")` 로 받아 ★**「git 이 못 답했다」가 「없다고 답했다」로 접혔다** ⇒ `✓ (0 file(s) examined)` · **rc=0**. |
|
0 commit comments