Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions REPORT.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
# REPORT
## [2026-09-18] 「어느 bootstrap argument 가 왜 나빴나」 — ★**대전제 ⓒ 에서 끝난다: 그 일을 하는 축이 이미 떠 있다**(rustjava-adopt-loadable-bootstrap-arguments-diagnostic)
- 무엇을: 채택 제안 `2026-09-17-loadable-bootstrap-arguments#p0` 의 처분(worklog json `adoptedProposals` 기록). ★**코드 0행** — `classfile/src/{error,validation}.rs` **무접촉**.
- ★**제안의 전제는 참이다 — CLI 로 돌려서 봤다**(`main` @ `8c7b473f`): 서로 다른 세 규칙(`LdcDynamicBSMArgPastEnd` 나쁜 argument · `LdcDynamicDuplicateBSM` 중복 속성 · `LdcDynamicOldMajor` 버전 게이트)이 ★**글자 하나 다르지 않은 `java.lang.ClassFormatError: Invalid class file`** 를 낸다.
- ★★**겹침을 «두 축»으로 갈라야 한다**(초판은 「전부」로 뭉쳤고 ★그 낱말이 카드의 과소 산정을 낳았다): ★**편집 영역은 전부 겹친다** — **PR #67** 이 제안의 `target` **바로 그 두 파일**을 고치고(merge-base 대비 `error.rs` **10/1** · `validation.rs` **61/27**), ★**이 술어에 이미 사유를 준다**(`"a bootstrap method argument names nothing or is not a loadable constant"`), ★밋밋한 문면이 박힌 **두 경계 자리**(`src/runtime.rs:189`·`test-utils/src/lib.rs:334`)도 **둘 다** 고쳤다. ⇒ main 에서 시작하면 **같은 enum 을 세 번째로 고치고** 같은 커버리지 구멍을 다시 발견한다.
★**제안 자신이 그렇게 적어 두었다** — `tradeoff`: 「the two should be done together rather than twice」.
- ★**남는 것은 있다 · 다만 좁다**: `#67` 의 payload 는 **`&'static str`** 이라 ★**런타임 인덱스를 구조적으로 못 담는다** ⇒ 「기대」는 **달성**, 「인덱스」·「실제」는 **미달**. ⇒ ★**새 카드를 좁혀 냈다**(effort **S**) — 원 제안은 처분하고 잔여만 정확한 범위로 다시 세운다(안 그러면 카드와 함께 잔여도 사라진다).
- ★**제안이 적지 않은 설계 제약**: `ClassFileError` 는 **`Copy`** 이고 ★**파일 4 · 크레이트 «2»**(`classfile` 3 + `jvm-bytecode` 1)가 그것을 쓴다 — ★초판의 「네 크레이트」는 **명사가 틀렸다**(수는 맞다 · 루트 2건은 **주석**이다)(`tests/test.rs` 13 · `validation.rs` 8 · `class.rs` 7 · `jvm-bytecode/src/error.rs` 5). ★**깨지 않고도 된다** — 정적 사유 + `u16` 인덱스 + `u8` 태그면 셋 다 `Copy`. 후속이 다시 발견하지 않도록 새 카드에 적었다.
- ★**#67 위에 쌓지 않은 이유**(선택이지 누락 아님): ⑴아직 approve 아님(게이트② 재검 중) ⑵head 가 회차마다 움직임 ⑶**자식 PR** 이 되어 base 소멸 시 자동으로 닫힌다(게이트③ 계약 5).
- ★**잃는 것**: ★**main 은 #67 착지까지 밋밋한 채로 남는다**(오늘 사용자는 **규칙 이름조차** 못 받는다) · 이 회차는 제안의 값을 **전혀 전달하지 않았고** 전달한 것은 **순서**다 · #67 이 폐기되면 이 판단은 **한 회차를 버린 것**이 된다.
- 검증: `cargo test --all` **583 passed / 0 failed / 1 ignored**(불변 — 코드 무접촉 · base `8c7b473f`) · `check-dod-ci-parity` → **「OK 두 축 모두 대칭차 0 — 명령 6개 · toolchain 2개로 «둘 다 일치»」**.
- ★후속 추천: 새 카드 「**구조화된 variant 로** bootstrap argument 의 인덱스와 태그를 말한다」(★**M** · ★초판은 `S` 였다 — **실측 후 올렸다**: 잔여도 #67 과 **같은 3층**을 건넌다(중간층 `jvm-bytecode` 도 `&'static str` · 경계는 `&str`) ⇒ `target` **5파일 / 4크레이트**(`classfile`·`jvm-bytecode`·`RustJava`·`test-utils` — ★**층은 3인데 크레이트는 4다**: 경계 층 하나가 두 크레이트에 걸친다). ★`InvalidFormat` 을 넓히면 생성 **17**곳 + 값 매치 **11**곳이라 **새 variant** 를 고르되 ★**두 갈래가 생기는 대가**를 카드에 적었다) — ★**#67 «뒤»에** · 상세 = `docs/worklog/2026-09-18-bootstrap-argument-diagnostic-sequencing.md`.
## [2026-09-18] 루트 fixture 를 한 target 으로 모을 것인가 — ★**모으지 않는다**(rustjava-adopt-test-data-version-freeze-uniform-target-p0)
- 무엇을: 채택 제안 `2026-09-17-test-data-version-freeze#p0` 의 **결정**(worklog json `adoptedProposals` 기록). ★**코드 0행 · 재컴파일 0 · `.class` 바이트 0 변경** — 산출물은 `docs/test-data-target-policy.md` 와 그 근거다.
- ⑴**분포**(동결 파일이 아니라 fixture 자신에서 읽었다): 루트 **114**건 · major **52×40 · 65×62 · 66×8 · 68×1 · 70×3** — 동결 파일 머리주석과 일치.
Expand Down
6 changes: 6 additions & 0 deletions STATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
(둘 다 이것보다 오래됐고 MERGEABLE/CONFLICTING 처분이 이미 걸려 있다). 겹침은 전부 **append 형 합집합**이라 해소는 기계적이다)

## 완료
- [rustjava-adopt-loadable-bootstrap-arguments-diagnostic] ★★**대전제 ⓒ 에서 끝났다 — 그 일을 하는 축(PR #67)이 이미 떠 있다.** 채택 제안 `2026-09-17-loadable-bootstrap-arguments#p0`(worklog json 기록). ★**코드 0행.**
★**전제는 참**(CLI 실행: 세 규칙이 전부 `ClassFormatError: Invalid class file` 동일 문면) — 그러나 ★**편집 영역은 전부 겹친다**(전달된 값은 **3 중 1** — 아래): #67 이 제안 `target` 두 파일을 고치고, 이 술어에 **이미 사유를 주며**, 밋밋한 문면 **두 자리**를 둘 다 고쳤다. ★제안 `tradeoff` 자신이 「두 번 하지 말고 함께 하라」고 적었다.
★**남는 잔여는 좁다** — `&'static str` 이라 **인덱스를 못 담는다** ⇒ 「기대」 달성 · 「인덱스·실제」 미달 ⇒ ★**새 카드를 냈다**(★**M** — 초판 `S` 에서 **실측 후 올렸다**: 잔여도 **같은 3층**을 건너 `target` **5파일/4크레이트**(`classfile`·`jvm-bytecode`·`RustJava`·`test-utils` — ★층 3 ↔ 크레이트 4: 경계 층이 두 크레이트에 걸친다) · `InvalidFormat` 을 넓히면 생성 17 + 매치 11 이라 **새 variant** 를 고르고 **두 갈래의 대가**를 적었다).
★**설계 제약 기록** — `ClassFileError` 는 `Copy`(파일 4 · 크레이트 2 의존) · 정적사유+`u16`+`u8` 로 **깨지 않고 된다**.
★**잃는 것**: main 은 #67 착지까지 **밋밋한 채**(규칙 이름조차 없다) · 이 회차가 전달한 것은 **값이 아니라 순서**다.
★`--all` **583/0/1**(불변 · base `8c7b473f`).
- [rustjava-adopt-test-data-version-freeze-uniform-target-p0] ★★**루트 fixture 를 한 target 으로 모을 것인가 — «모으지 않는다».** 채택 제안 `2026-09-17-test-data-version-freeze#p0`(worklog json 기록). ★**코드 0행 · 재컴파일 0 · `.class` 0 변경** — 산출물 = `docs/test-data-target-policy.md`.
★분포 **114**건 · **52×40 · 65×62 · 66×8 · 68×1 · 70×3**(fixture 자신에서 읽음).
★★**양방향**: ⒜**버전이 답** — `StringBuilder` 3건을 21 로 재컴파일 → ★indy 생기고 StringBuilder 사라짐(★`StringConcat` 이 루트의 **유일한** indy) · `ThreadInterruption` `access$`×10 → **0 + NestMembers**(JEP 181) ⒝**아무 버전이나** — 20건 중 ★**16건 명령 시퀀스 완전 동일**.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"date": "2026-09-18",
"taskId": "rustjava-adopt-loadable-bootstrap-arguments-diagnostic",
"summary": "Stopped at the ticket's own precondition: an axis already doing most of this is in flight. PR #67 rewrites exactly the two files this proposal names, already gives this very predicate a cause string, and already replaces the flat 'Invalid class file' at both boundary sites. Doing it now on main would be a third competing edit to the same enum and would rediscover the same duplicated boundary. The proposal's residue after #67 is real but narrower than the proposal describes, and it is recorded as a new, correctly scoped card.",
"changes": [
"no code: classfile/src/error.rs and classfile/src/validation.rs untouched",
"docs/worklog only — the finding, the measurements, and a narrowed successor proposal"
],
"verification": [
"PREMISE CONFIRMED on main @ 8c7b473f, measured by running the CLI rather than by reading: three different rules all print the identical message. `rust_java -cp ./test-data/ldc LdcDynamicBSMArgPastEnd` (bad bootstrap argument), `LdcDynamicDuplicateBSM` (duplicate attribute) and `LdcDynamicOldMajor` (version gate) each answer `java.lang.ClassFormatError: Invalid class file`",
"OVERLAP, split into the two axes it was conflating. By EDIT AREA it is total: this proposal's target is classfile/src/error.rs and classfile/src/validation.rs, and PR #67 changes exactly those two (error.rs 10/1, validation.rs 61/27 against their merge base), already gives this predicate the cause 'a bootstrap method argument names nothing or is not a loadable constant', and already rewrites both boundary sites that hardcode 'Invalid class file'. By DELIVERED CAPABILITY — which is what precondition (c) actually asks — it is 1 of 3: the proposal wants expected, index and actual, and #67's &'static str payload supplies the expectation only. An earlier draft wrote 'OVERLAP IS TOTAL' unqualified, which contradicted the residue entry three lines down and is the same word that produced the under-sized effort on the card.",
"CONTRACT 2 SWEEP: the literal 'Invalid class file' is hardcoded at two boundary sites, src/runtime.rs:189 and test-utils/src/lib.rs:334. #67 rewrites both; a round starting from main would have to change both again and would hit the same test-coverage gap #67's round already reported",
"RESIDUE IS REAL BUT NARROWER: #67's payload is &'static str, which structurally cannot carry a runtime index. So after #67 lands the proposal's 'expected' is delivered by the rule wording and its 'index' and 'actual' are not",
"DESIGN CONSTRAINT the proposal does not name: ClassFileError derives Copy. Carrying an owned String would drop Copy for every consumer. Counted at 8c7b473f with git grep -c: classfile/tests/test.rs 13, classfile/src/validation.rs 8, classfile/src/class.rs 7, jvm-bytecode/src/error.rs 5 — that is 4 FILES across 2 CRATES (classfile three, jvm-bytecode one), not four crates as an earlier draft said; the two further hits under tests/ are comments, not code. A Copy-preserving shape exists — the static cause plus a u16 index plus the u8 tag found — so the successor does not need to break it.",
"cargo test --all: 583 passed / 0 failed / 1 ignored on base 8c7b473f, unchanged — this round adds no code"
],
"issues": [
"Not stacking on #67's branch was a choice, not an oversight: #67 is not approved (its gate2 re-review is in flight), its head moves each round, and a PR based on it would be a child PR whose base can vanish on merge — the hazard gate3 contract 5 exists for.",
"This leaves the flat message in place on main until #67 lands. That is the cost of not duplicating: a user bisecting a rejected class file today still gets no cause at all, not even the rule."
],
"adoptedProposals": [
"2026-09-17-loadable-bootstrap-arguments#p0"
],
"proposals": [
{
"title": "Add a structured variant that names the failing bootstrap argument's index and tag",
"plainSummary": "Once the rejection says which rule failed, give that one rule a richer error that also carries which argument number was wrong and what it actually pointed at.",
"userBenefit": "OpenJDK says 'argument_index 4 has bad constant type'. Naming the rule gets a reader to the right sentence; naming the index and the tag gets them to the right byte without bisecting the file.",
"why": "This is the measured residue of 2026-09-17-loadable-bootstrap-arguments#p0 after PR #67. That PR carries the cause as a &'static str, which cannot hold a runtime index, so of the proposal's three asks — expected, index, actual — it delivers the first and not the other two. The predicate already knows the index at the moment it returns false and throws it away.",
"tradeoff": "Measured rather than estimated, against #67's tree @56bb54fa. Widening InvalidFormat's payload would touch 17 construction sites (validation.rs 14, class.rs 3) and force all 11 value matches in classfile/tests/test.rs to change. Adding a separate variant instead touches one construction site and forces none of the 11, so that is the shape proposed — but it leaves TWO KINDS of rejection error side by side, and 'why is this one structured and that one a bare string' becomes a standing question every later rule has to answer. Either way the work crosses the same three layers, because the middle layer (jvm-bytecode ClassDefinitionError::InvalidClassFile) is also &'static str and the boundary (jvm exception(&str)) takes a plain string, so the text has to be formatted at src/runtime.rs and test-utils/src/lib.rs. ClassFileError also derives Copy and 4 files across 2 crates use it, so the payload must stay Copy: static cause plus u16 index plus u8 tag. And it must be sequenced after #67, not beside it — both touch the same enum and function.",
"effort": "M",
"target": "classfile/src/error.rs, classfile/src/validation.rs, jvm-bytecode/src/error.rs, src/runtime.rs, test-utils/src/lib.rs"
}
]
}
Loading
Loading