Skip to content

Commit 53ca340

Browse files
author
jun0
committed
[rustjava-adopt-cp-tag-passthrough-detectable-p1] docs(classfile): 원인을 실을 값은 있다 — 제안의 역사·책임·범위를 바로잡는다
낱말이 Decide 다. 판정은 「할 값 있다」이지만 제안의 세 전제가 틀렸다. 역사: 822504b 는 error.rs 를 자르지 않고 만들었다. 그 이전 ClassInfo::parse 는 Option 을 돌려줘 실패에 정보가 0 이었다 — 그 커밋은 개선이었고, 「again」·「restore」는 성립하지 않는다. 책임: upstream 이 막고 있지 않다. 우리는 5커밋 뒤이고 그중 이 파일들을 만지는 것은 0건이며, 우리 fork 는 이미 이 crate 에서 +560 줄 갈렸다. read-only 규율은 보내는 것을 금할 뿐이다. 범위: target 이 1파일인데 평탄화는 3층이다. error.rs 만 고치면 관측 변화가 0 이고, 진짜 비용은 validate_class 의 8항 || 사슬을 쪼개는 것 — 이 티켓이 금지한 리팩터다. 그래서 구현하지 않고 범위를 바로잡아 후속으로 넘긴다. 제안이 근거로 인용한 주석이 거짓이었으므로 그 자리에서 고쳤다.
1 parent 308d56b commit 53ca340

5 files changed

Lines changed: 193 additions & 3 deletions

File tree

‎REPORT.md‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,29 @@
11
# REPORT
2+
## [2026-09-17] `ClassFileError` 가 «원인»을 실어야 하는가 — ★**판정: 할 값 있다. 단 제안의 이름·이유·범위가 셋 다 틀렸다** (rustjava-adopt-cp-tag-passthrough-detectable-p1)
3+
- 무엇을: 낱말이 **`Decide`** 인 제안을 **판정**했다. ★**코드 변경은 «틀린 주석 한 곳» 정정뿐** — 구현은 후속으로 넘겼다.
4+
- 왜: 채택 제안 `2026-09-16-cp-tag-passthrough-detectable#p1`.
5+
- 사용자 영향: 없다(판정). ★바뀐 것은 ★**착지한 트리가 «거짓 전제»를 나르지 않게 된 것**이다.
6+
- ★★**제안의 «역사»가 거짓이다 — 두 겹으로**: ⑴`822504b` 는 `classfile/src/error.rs` 를 **«자르지» 않고 «만들었다»**
7+
(`new file` · 내용이 지금과 **동일한 2변형**) ⑵그 이전에는 `ClassInfo::parse` 가 **`Option<Self>`** 를 돌려줬다
8+
(실패에 정보 **0**) ⇒ ★**그 커밋은 «후퇴»가 아니라 «개선»이었고, 「again」·「restore」는 성립하지 않는다.**
9+
- ★★**「upstream 이 해야 한다」도 거짓**: `upstream/main` 기준 **5커밋 뒤**이고 그중 이 파일들을 만지는 것 **0건** ·
10+
upstream 이 `error.rs` 를 만진 커밋은 **1건(생성)** 뿐 · ★**우리는 이미 이 crate 에서 크게 갈렸다**
11+
(`constant_pool.rs` **+211/−6** · `validation.rs` **+137/−0** · `attribute.rs` **+129/−3** · `opcode.rs` **+83/−7**).
12+
※`AGENTS.md` 의 read-only 규율은 **upstream 으로 «보내는 것»**을 금할 뿐 로컬 변경을 금하지 않는다.
13+
- ★★**ⓑ 설계는 «한 enum 건너» 이미 증명돼 있다**: `ClassDefinitionError::UnsupportedFeature(&'static str)` 가
14+
**5곳**에서 쓰이며 `"ldc of a method handle"` 같은 문장을 낸다 ⇒ ★**새 발명이 아니라 «일관성 회복»**이고, 모양도 자명하다.
15+
- ★**이득(과장하지 않는다)**: kind-only 단언 **8곳**이 원인을 이름 부를 수 있게 되고, 참조 JVM 격차가 줄어든다
16+
(OpenJDK 는 `Multiple BootstrapMethods attributes…`·`argument_index 65535 has bad constant type` 를 내는데 우리는 전부 `Invalid class file`).
17+
★**그러나 「픽스처보다 강한 자물쇠」는 «절반만» 참이다** — 원인은 「어느 검사가 울렸나」를, 픽스처는 「그 검사가 관측 가능한가」를 잠근다.
18+
★**증거**: 직전 `-fix` 가 찾은 구멍(신원 4축 중 3축 미관측)은 **링크 축**이라 원인을 실었어도 **안 잡혔다**.
19+
- ★★**비용 — 제안의 `target: classfile/src/error.rs` 는 틀렸다(1파일이 아니라 3층)**: 평탄화가 아래로 두 번 더 일어난다
20+
(`InvalidFormat` → `ClassDefinitionError::InvalidClassFile`(From 이 원인을 버린다) → ★**하드코딩 문자열 2곳**).
21+
⇒ ★**`error.rs` 만 고치면 관측 변화가 «0»** 이다. ★**진짜 비용은 `validate_class` 의 8항 `||` 사슬을 쪼개는 것**이고,
22+
그것은 이 티켓이 **금지한 리팩터**다 ⇒ ★**여기서 구현하지 않고 «범위를 바로잡아» 넘겼다.**
23+
- 검증: `cargo test --all` **572 / 0 failed / 1 ignored**(주석만 바꿔 불변) · DoD 7명령 rc=0.
24+
- 후속 추천: 원인을 **3층에 관통**시키고 `validate_class` 를 **검사마다 반환**으로 쪼갠다(M) —
25+
★「⑴만 하고 멈추면 관측 변화 0 · ⑷ 없이 하면 평탄함이 «이사»할 뿐」까지 제안에 적었다.
26+
상세 = `docs/worklog/2026-09-17-classfile-error-cause-decision.md`.
227
## [2026-09-16] 부트스트랩 메서드의 «정적 인자» 인덱스를 경계 검사한다 (rustjava-adopt-bound-bootstrap-method-attr-index-p1)
328
- 무엇을: JVMS 4.7.23 의 `bootstrap_arguments` 는 상수 풀 인덱스인데 ★**아무도 그것이 실재하는지 보지 않았다.**
429
이제 풀에 «없는» 인덱스를 가리키면 **거부**한다.

‎STATE.md‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,32 @@
44
(없음 — 2026-09-16 실측: 착수 시 진행 티켓 0 · 열린 PR 0. ※「열린 PR 0」은 ★**이 회차 PR 착지 시점 기준**이다 — 회신 시점에는 그 PR 자신이 열려 있다)
55

66
## 완료
7+
- [rustjava-adopt-cp-tag-passthrough-detectable-p1] ★★**판정 — `ClassFileError` 에 «원인»을 실을 값은 있다. 단 제안의 이름·이유·범위가 «셋 다» 틀렸다.**
8+
채택 제안 `2026-09-16-cp-tag-passthrough-detectable#p1`(worklog json `adoptedProposals` 기록). 낱말이 **`Decide`** 다
9+
⇒ ★**코드 변경은 «틀린 주석 한 곳» 정정뿐** · 구현은 **범위를 바로잡아 후속으로** 넘겼다.
10+
★★**⑴역사가 거짓이다**: `822504b` 는 `error.rs` 를 **«자르지» 않고 «만들었다»**(`new file` · 지금과 동일한 2변형)이고,
11+
그 이전 `ClassInfo::parse` 는 **`Option<Self>`**(실패에 정보 **0** · `.unwrap()` 투성이)였다 ⇒ ★**그 커밋은 «개선»이었다.**
12+
⇒ ★**「carry a cause **again**」·「restoring」은 성립하지 않는다 — 이 리니지에 원인이 실렸던 시기는 «없다».**
13+
★★**⑵「upstream 이 해야 한다」도 거짓**: `upstream/main` 기준 **5커밋 뒤** · 그중 이 파일들을 만지는 것 **0건** ·
14+
upstream 의 `error.rs` 접촉은 **1건(생성)** 뿐(이 crate 에서 가장 안정된 파일) · ★**우리는 이미 이 crate 에서 크게 갈렸다**
15+
(`constant_pool.rs` +211/−6 · `validation.rs` +137/−0 · `attribute.rs` +129/−3 · `opcode.rs` +83/−7).
16+
※`AGENTS.md` read-only 는 **upstream 으로 «보내는 것»** 금지이지 로컬 변경 금지가 아니다.
17+
★★**⑶범위도 틀렸다 — `target: classfile/src/error.rs` 는 1파일인데 평탄화는 «3층»이다**:
18+
`InvalidFormat`(생산 9곳) → `ClassDefinitionError::InvalidClassFile`(**From 이 원인을 버린다**) →
19+
★**`"Invalid class file"` 하드코딩 2곳**(`src/runtime.rs:189` · `test-utils/src/lib.rs:334`).
20+
⇒ ★**`error.rs` 만 고치면 «관측 변화 0»** — 아무도 원인을 넣지 않고 아무도 읽지 않는, 이 저장소가 규탄하는 그 형태다.
21+
★★**진짜 비용은 `validate_class` 의 «8항 `||` 사슬»을 쪼개는 것**이다(원인이 갈리는 유일한 자리) —
22+
★그것은 이 티켓이 **명시적으로 금지한 리팩터**(계약 3)라 ★**여기서 구현하지 않았다.**
23+
★★**ⓑ 그런데 설계는 «한 enum 건너» 이미 증명돼 있다** — `ClassDefinitionError::UnsupportedFeature(&'static str)` 가
24+
**5곳**에서 쓰이며 `"ldc of a method handle"` 같은 문장을 낸다 ⇒ ★**새 발명이 아니라 «일관성 회복»**이고 이것이 「할 값 있다」의 근거다.
25+
★**이득을 과장하지 않는다**: kind-only 단언 **8곳**이 원인을 이름 부를 수 있고 참조 JVM 격차가 준다.
26+
★**그러나 제안의 「픽스처보다 강한 자물쇠」는 «절반만» 참** — 원인은 «어느 검사가 울렸나», 픽스처는 «그 검사가 관측 가능한가»를 잠근다.
27+
★**증거**: 직전 `-fix` 가 찾은 구멍(신원 4축 중 3축 미관측)은 **링크 축**이라 ★**원인을 실었어도 안 잡혔다** ⇒ **대체가 아니라 «더하기»다.**
28+
★**지금 고친 것**: `tests/test_class_format.rs` 머리 주석 — ★**제안이 근거로 인용한 바로 그 문장**이 거짓이었다
29+
(「cut 822504b」·「Restoring it needs upstream variants」) ⇒ 그 자리에서 정정했다.
30+
★**착지한 트리가 거짓을 나르면 다음 사람이 같은 전제로 같은 제안을 다시 만든다.**
31+
★두 번째 언급(「`ClassFileError` 가 평탄화한다」)은 **참**이라 **건드리지 않았다**(과잉 편집 0).
32+
★`cargo test --all` **572 / 0 failed / 1 ignored**(주석만 바꿔 **불변**) · DoD **7줄 전건 rc=0**.
733
- [rustjava-adopt-bound-bootstrap-method-attr-index-p1] ★★**부트스트랩 «정적 인자» 인덱스를 경계 검사한다 — 「감지되나 판정되지 않던」 자리를 닫았다.**
834
채택 제안 `2026-09-16-bound-bootstrap-method-attr-index#p1`(worklog json `adoptedProposals` 기록).
935
★**전/후**: `UnsupportedOperationException` → ★`ClassFormatError`. ★참조 JVM(OpenJDK 26.0.1) →
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"schema": "worklog/v1",
3+
"date": "2026-09-17",
4+
"taskId": "rustjava-adopt-cp-tag-passthrough-detectable-p1",
5+
"summary": "Decided whether ClassFileError should carry a cause. Verdict: worth doing, but the proposal's history, blame and scope are all wrong, and doing it properly needs a refactor this ticket forbids. Recorded the corrected scope and fixed the false comment the proposal cited.",
6+
"changes": [
7+
"tests/test_class_format.rs: the header comment claimed the variants were cut upstream at 822504b and that restoring them needs upstream changes. Both are false; replaced with what is actually true and why.",
8+
"docs/worklog/2026-09-17-classfile-error-cause-decision.{md,json}: the decision, its evidence, and the scope handed to a follow-up"
9+
],
10+
"verification": [
11+
"current state: classfile/src/error.rs still has two variants, and 8 assertions in tests/test_class_format.rs check only the ClassFormatError kind",
12+
"822504b created classfile/src/error.rs as a new file with these same two variants; before it, ClassInfo::parse returned Option, so failure carried nothing at all — the commit was an improvement, not a cut",
13+
"upstream is not the blocker: we are 5 commits behind upstream/main and none of them touch these files; upstream has touched classfile/src/error.rs exactly once (its creation); our fork already diverges by +211/-6 in constant_pool.rs, +137/-0 in validation.rs, +129/-3 in attribute.rs, +83/-7 in opcode.rs",
14+
"the pattern already exists one enum over: ClassDefinitionError::UnsupportedFeature(&'static str) is used at 5 sites and produces messages like 'ldc of a method handle'",
15+
"the flattening happens at three layers, not one: ClassFileError::InvalidFormat (9 production sites) -> ClassDefinitionError::InvalidClassFile (the From impl drops any cause) -> a hardcoded \"Invalid class file\" string at src/runtime.rs:189 and test-utils/src/lib.rs:334",
16+
"validate_class evaluates an eight-term || chain and returns one InvalidFormat, so a per-check cause requires splitting that chain — a refactor this ticket forbids",
17+
"cargo test --all: 572 passed / 0 failed / 1 ignored, unchanged (the only code change is a comment)",
18+
"DoD 7 commands all rc=0"
19+
],
20+
"issues": [
21+
"The proposal's claim that a cause would be 'a stronger lock than a carefully shaped fixture' is half true: a cause locks which check fired, a fixture locks whether the check is observable at all. The hole the sibling -fix round found was in linking, not parse errors, so a cause would not have caught it.",
22+
"Implementing only the proposal's stated target (classfile/src/error.rs) would produce no observable change, since nothing would set the cause and nothing would read it."
23+
],
24+
"adoptedProposals": [
25+
"2026-09-16-cp-tag-passthrough-detectable#p1"
26+
],
27+
"proposals": [
28+
{
29+
"title": "Thread a cause through ClassFileError, and split validate_class so it can differ",
30+
"plainSummary": "Give class file rejections a reason, all the way out to the exception message a user sees.",
31+
"userBenefit": "A rejected class file says what is wrong with it — 'unknown constant pool tag', 'bootstrap argument names nothing' — instead of the same 'Invalid class file' for every cause, which is what a real JVM does.",
32+
"why": "Decided in this round after measuring: the design already exists one enum over (ClassDefinitionError::UnsupportedFeature carries &'static str at 5 sites), upstream is not the blocker, and 8 assertions currently can only check the exception kind. The work is ClassFileError::InvalidFormat(&'static str), the same on ClassDefinitionError::InvalidClassFile so the From impl stops dropping it, the two hardcoded message sites (src/runtime.rs, test-utils/src/lib.rs), and splitting validate_class's eight-term || chain so each check can name itself.",
33+
"tradeoff": "Doing only the error type changes nothing observable, and doing it without splitting the || chain just moves the flatness rather than removing it — so this is an all-or-nothing scope, and it includes a refactor of validate_class. It also does not replace the shaped-fixture discipline: a cause says which check fired, not whether each axis of a multi-axis check is observable.",
34+
"effort": "M",
35+
"target": "classfile/src/error.rs, classfile/src/validation.rs, jvm-bytecode/src/error.rs, src/runtime.rs, test-utils/src/lib.rs"
36+
}
37+
]
38+
}

0 commit comments

Comments
 (0)