From 7a84a37f70aecf480a2f7abaab5e0d7b7ee947ba Mon Sep 17 00:00:00 2001 From: xzawed <47019855+xzawed@users.noreply.github.com> Date: Sun, 27 Sep 2026 07:44:14 +0900 Subject: [PATCH 1/2] =?UTF-8?q?docs:=20hand=20off=20the=20session=20?= =?UTF-8?q?=E2=80=94=20leftovers=20only=20closed=20records=20held=20move?= =?UTF-8?q?=20to=20live=20docs=20(=C2=A79-74)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A workflow inventoried every open item the live docs state (53) and every leftover the closed records 9-66..9-73 and four recent SPEC §5s state (67), reconciled them, and had each finding refuted-or-confirmed (9 of 9 held, several with corrected wording, numbering or home). - STATUS §5-7..§5-10: ml_abi.h defines only -1; RUSTFLAGS=-D warnings breaks modules with existing warnings (re-measured: non_snake_case and dead_code exit 1, a clean module 0); the speed of `!` checks was never measured; four known blind spots of the doc guards. - HOST_ABI naming: C macro names can collide across modules (ML_A_CONST_ERR_Q). - LANGUAGE gap block + language_gaps.rs: `enum` (Red first: the GAPS row failed on the missing bullet); the duplicate 복합 대입 is gone. Candidate list: constant-expression overflow diagnostic, enum. - In place: WBS header (Delphi is a local gate), WBS workdir bullet (paid by #19), OPEN_QUESTIONS "Claude에게" (points at the section instead of Q6~Q11), STATUS §5-4 pointers (symbols instead of drifted line numbers). - The 626-row kit moved out of the session scratchpad to D:\Source\Mathless-lab and was re-measured there (543/44/20/18, 0 rows differ); the ▶ entry says where it is. The previous 2026-09-27 entry moved byte-for-byte to start-block-055.md. Co-Authored-By: Claude Opus 5.5 (1M context) --- compiler/tests/language_gaps.rs | 7 ++++ docs/HISTORY.md | 1 + docs/HOST_ABI.md | 4 ++ docs/LANGUAGE.md | 4 +- docs/OPEN_QUESTIONS.md | 2 +- docs/STATUS.md | 43 +++++++++++++------- docs/history/9-74.md | 66 +++++++++++++++++++++++++++++++ docs/history/start-block-055.md | 20 ++++++++++ docs/history/start-block-index.md | 1 + docs/phase1/WBS.md | 5 ++- docs/slices/README.md | 3 ++ 11 files changed, 138 insertions(+), 18 deletions(-) create mode 100644 docs/history/9-74.md create mode 100644 docs/history/start-block-055.md diff --git a/compiler/tests/language_gaps.rs b/compiler/tests/language_gaps.rs index 828361f..bd0794d 100644 --- a/compiler/tests/language_gaps.rs +++ b/compiler/tests/language_gaps.rs @@ -231,6 +231,12 @@ fn data_shapes_that_do_not_exist_yet() { "host fn import", "import fn host_log(x: i32)\nexport fn f(a: i32) -> i32 { return a }", ); + // SPEC-constants §0.3/§5 left `enum` (a new type, an ABI mapping, an exhaustiveness check) + // for later; until 2026-09-27 that was written only in the closed SPEC and §9-68. + rejected( + "enum declaration", + "enum S { A }\nexport fn f(a: i32) -> i32 { return a }", + ); // Four gaps the 2026-09-26 §7 sweep met in several domains, missing from the block that // claims to hold every gap. rejected("i64 type", "export fn f(x: i64) -> i64 { return x }"); @@ -274,6 +280,7 @@ const GAPS: &[(&str, &str)] = &[ ("일반 `f64` 포맷", "f64 as string"), ("지역 변수", "string local"), ("struct", "struct declaration"), + ("`enum`", "enum declaration"), ("option", "option type"), ("for", "for"), ("else", "else"), diff --git a/docs/HISTORY.md b/docs/HISTORY.md index ba82e2a..758d8e7 100644 --- a/docs/HISTORY.md +++ b/docs/HISTORY.md @@ -40,6 +40,7 @@ --- +### 9-74. 인계 정리 (2026-09-27, E2) — **측정 키트를 저장소 밖으로 옮겨 다시 쟀고, 닫힌 기록에만 있던 잔여를 살아 있는 문서로 옮겼다** → [본문](history/9-74.md) ### 9-73. 넓은 중간값 슬라이스 (2026-09-27, E2) — **`!` 문맥의 순수 산술 식은 정확히 계산되고, 뿌리에서 한 번 좁혀진다** → [본문](history/9-73.md) ### 9-72. 헬퍼 체크 전파 슬라이스 (2026-09-26, E2) — **`!`를 위해 실행되는 산술은 어디에 쓰여 있든 검사된다** → [본문](history/9-72.md) ### 9-71. 체크드 산술 다음을 쟀다 (2026-09-26, E2) — **헬퍼 체크 전파가 조용한 오답을 가장 많이 줄인다** → [본문](history/9-71.md) diff --git a/docs/HOST_ABI.md b/docs/HOST_ABI.md index d84b45d..21c6fa7 100644 --- a/docs/HOST_ABI.md +++ b/docs/HOST_ABI.md @@ -517,6 +517,10 @@ GetProcAddress 심볼 3개 전부 성공 -> 전부 성공 - 사용자 모듈이 export하는 함수: 별도 접두어(예: `mlx_`) 또는 모듈명 네임스페이스. `ml_`와 충돌 금지(D18). - 모듈이 내보내는 이름 붙은 정수: 에러 코드는 `ML__ERR_`(Q14), `export const`는 `ML__CONST_`(SPEC-constants DP-K3). 둘 다 **값이지 심볼이 아니고** 지문에 든다. + **모듈 사이의 C 매크로 이름은 겹칠 수 있다** — 모듈 `a`의 상수 `ERR_Q`와 모듈 `a_const`의 에러 `Q`가 둘 다 + `ML_A_CONST_ERR_Q`다(에러끼리도 `a`/`ERR_X` ↔ `a_err`/`X`). 막는 가드가 없어, 값이 다른 두 헤더를 한 번역 단위에 + include하면 `C4005` 경고가 나고 참조 호스트처럼 `/WX`로 빌드하면 실패한다. Pascal 상수는 유닛 스코프라 겹치지 않는다 + (SPEC-constants §5). ## 하지 말 것 (MVP) diff --git a/docs/LANGUAGE.md b/docs/LANGUAGE.md index 3d85c37..271f2e5 100644 --- a/docs/LANGUAGE.md +++ b/docs/LANGUAGE.md @@ -313,7 +313,9 @@ 수 있으므로 **그 함수는 `!`가 된다** — 배열 인덱싱과 같은 규칙이다 (`slices/SPEC-string-slice-compare.md` DP-C2·DP-C5) - struct/record, null 안전 또는 option -- `for`, `else`, `break`/`continue`, 복합 대입, 비트 연산자 +- **`enum`·타입 있는 상수 집합** — 오늘은 이름 붙은 i32 리터럴(`const`·`export const`)뿐이다. 새 타입 · ABI 매핑 · + 완전성 검사를 여는 일이라 `slices/SPEC-constants.md` §0.3·§5가 남겼다 +- `for`, `else`, `break`/`continue`, 비트 연산자 - **호스트 함수 import**(현재는 모듈 export 단방향), 재귀 - 다른 정수 폭 **`i64`**, **수학 내장 함수**(`pow`·`exp`·`ln`·`sqrt`·`abs`), **`min`/`max`**, **지역 배열·배열 리터럴**(작업 배열) — 넷 다 우회는 된다(곱셈 루프 · 두 줄 내부 `fn` · 파라미터로 diff --git a/docs/OPEN_QUESTIONS.md b/docs/OPEN_QUESTIONS.md index b1e7ea8..85cb71e 100644 --- a/docs/OPEN_QUESTIONS.md +++ b/docs/OPEN_QUESTIONS.md @@ -185,5 +185,5 @@ ABI 정수 상태코드+out-param, 표면 Result는 sugar. 남은 하위 → Q13 ## Claude에게 -Q1~Q5는 닫혔다. 남은 결정(**Q6~Q11** — **Q12·Q13·Q14·Q15는 닫혔다**)도 제안 시 장단점 표를 쓰고, 문서를 고치기 전에 사용자 확인을 받는다. +Q1~Q5는 닫혔다. 남은 결정(위 **미뤄도 되는 것** 절의 질문 전부 — **Q12·Q13·Q14·Q15는 닫혔다**)도 제안 시 장단점 표를 쓰고, 문서를 고치기 전에 사용자 확인을 받는다. 확인 없이 DECISIONS.md를 바꾸지 않는다. diff --git a/docs/STATUS.md b/docs/STATUS.md index e898bf6..728b32a 100644 --- a/docs/STATUS.md +++ b/docs/STATUS.md @@ -102,6 +102,20 @@ 푸는 것은 가산적 변경이며 SPEC 갱신이 따라야 한다. (SPEC-calls §5.1) 4. **생성 모듈의 패닉은 프로세스를 죽이지 않고 호출한 스레드를 무한히 돌린다.** ↓ §5-4 +5·6은 갚았다(등록부). 아래 넷은 2026-09-27에 닫힌 기록·SPEC §5에서 옮겨 왔다 — 거기에만 있던 것이다(§9-74). + +7. **`runtime/ml_abi.h`는 `-1`만 정의한다.** `-2`(`ML_ST_INDEX_OUT_OF_RANGE`, #200부터)·`-3`(`ML_ST_OVERFLOW`)은 + 생성 헤더에만 `#ifndef`로 있고, 그 파일의 *"the codes below are the whole allocation"* 은 낡았다. `hygiene.rs`의 + 대조도 `-1`만 본다. 고치는 PR: 헤더에 둘을 더하고 대조를 `mlc::abi`의 세 코드로 넓힌다(SPEC-checked-arithmetic §5). +8. **주변 `RUSTFLAGS=-D warnings`에서 기존 경고가 있는 모듈은 `mlc build`가 깨진다** — snake_case가 아닌 사용자 함수 + 이름(`fn a__b` → `non_snake_case`)과 아무도 부르지 않는 내부 함수(`dead_code`)는 측정됐고, 쓰지 않는 문자열 헬퍼도 + 같은 부류다. `allow`를 더하면 모든 모듈의 생성 Rust가 바뀌어 골든과 부딪히므로 따로 정한다(SPEC-helper-check-propagation §5). +9. **`!` 문맥 검사의 실행 속도는 잰 적이 없다** — 체크드 산술 · 헬퍼 체크 전파 · 넓은 중간값이 분기 · `Result` 반환 · + i64 연산을 더했지만 잰 것은 `.text` 크기뿐이다(§9-70.4 · §9-71.4 · §9-73.3). 빠르다/느리다를 쓰기 전에 잰다. +10. **문서 가드의 알려 둔 사각 넷** — `live_documents_do_not_accumulate_correction_notes`는 날짜 없는 서술을 세지 못하고 + `" 감사"` 뒤에 경계가 없다 · `protection.rs`의 "정확히 N개"는 부분 문자열 검사다 · 함수 본문 안의 긴 `//` 주석은 + `every_guard_docstring_is_short` 밖이다(§9-66.7). + ### 5-4. 생성 모듈의 패닉은 프로세스를 죽이지 않는다 — 스레드를 무한히 돈다 여러 문서가 `i32 /0`을 두고 "`no_std`+`panic=abort`니까 **호스트를 죽인다**"라고 적어 왔다. @@ -109,9 +123,9 @@ | 무엇 | 어디 | 값 | |---|---|---| -| no_std | `compiler/src/codegen.rs:39` | `#![no_std]` | -| 패닉 핸들러 | `compiler/src/codegen.rs:58` | `#[panic_handler] fn ml_panic(_: &core::panic::PanicInfo) -> ! { loop {} }` | -| 패닉 전략 | 생성 `Cargo.toml`(`codegen.rs:286`) | `[profile.release] panic = "abort"` | +| no_std | `compiler/src/codegen.rs`(생성 크레이트 머리) | `#![no_std]` | +| 패닉 핸들러 | `compiler/src/codegen.rs`(`ml_panic`) | `#[panic_handler] fn ml_panic(_: &core::panic::PanicInfo) -> ! { loop {} }` | +| 패닉 전략 | 생성 `Cargo.toml`(`codegen.rs`의 `CARGO_TOML_PROFILE`) | `[profile.release] panic = "abort"` | `no_std`에서는 **`#[panic_handler]`가 곧 패닉 런타임**이다. `panic = "abort"`는 언와인딩 테이블을 없앨 뿐, `abort()`를 부르는 것이 아니다. 그래서 패닉은 `ml_panic`으로 들어가 **`loop {}`에 갇힌다** — @@ -227,25 +241,26 @@ > ## ▶ 여기서 시작한다 > -> ### 2026-09-27 기준 — **넓은 중간값 슬라이스가 닫혔다: `!` 문맥의 순수 산술 식은 정확히 계산된다 (§9-73)** +> ### 2026-09-27 기준 (2) — **인계 정리: 측정 키트를 저장소 밖으로 옮겼고, 닫힌 기록에만 있던 잔여를 살아 있는 문서로 옮겼다 (§9-74)** > -> SPEC을 권고안대로 확인받아 슬라이스로 닫았다(#341 SPEC · #342 구현). `!` 문맥의 순수 산술 식은 i64로 계산해 값이 -> i32가 되어야 하는 자리에서 한 번 좁힌다. 참값이 드는데 `-3`인 행 59 → 20(626행, 시험 구현과 행마다 같다). 실제 C 호스트가 -> 바꾼 `one_payment`로 곱이 i32 밖인 입력의 정답을 받는다. 지문·ABI·바인딩은 그대로다. +> 로컬 브랜치는 `main`만 남았다(실험 브랜치 둘은 번들로 백업). §9-69의 626행 코퍼스와 재측정 스크립트가 세션 임시 폴더에만 +> 있어 저장소 밖으로 옮겼고, 옮긴 자리에서 다시 재 같은 표(543 · 44 · 20 · 18)를 얻었다. 닫힌 기록과 SPEC §5에만 있던 잔여는 +> §5-7~§5-10 · `HOST_ABI.md` 네이밍 규약 · `LANGUAGE.md` 공백 블록 · `slices/README.md` 후보 목록으로 옮겼다. > > **▶ 다음 세션 — 여기서 시작한다.** 순서대로: > -> 1. **강제되는 슬라이스가 없다 — 다음은 측정이다.** 참값이 드는데 `-3`으로 남은 20행 중 17행(FULL로도 남는 행)이 -> 무엇인지 귀속하지 않았다(§9-73.7). 귀속이 `i64` 타입이나 다른 후보(`docs/slices/README.md`의 "다음 슬라이스" 절)를 -> 가리키면 그때 SPEC을 쓴다. -> 2. **작은 항목**: C# 호스트(Phase 4) · LSP(Phase 3, 큰 일). -> 3. **외부**: `X1`·`X2` — Delphi가 있는 CI 러너. 이 저장소 안에서는 닫히지 않는다. +> 1. **참값이 드는데 `-3`인 20행 중 17행을 귀속한다 — 측정.** 키트는 저장소 밖 `D:\Source\Mathless-lab\kit-626\`(이 머신 +> 전용)이고 재현 절차 · 함정은 그 README에, 20행 목록은 `loud_fits_20_at_b077cb9.txt`에 있다(3행은 배열 읽기). +> 귀속이 `i64` 타입이나 다른 후보를 가리키면 그때 SPEC을 쓴다. +> 2. **작은 부채 — 한 PR씩**: §5-7(`ml_abi.h`에 `-2`·`-3`, 대조를 세 코드로) · §5-8(`-D warnings` — 방향은 사용자 결정). +> 3. **작은 항목**: C# 호스트(Phase 4) · LSP(Phase 3, 큰 일). +> 4. **외부**: `X1`·`X2` — Delphi가 있는 CI 러너. 이 저장소 안에서는 닫히지 않는다. > > ⚠ **이 머신의 전체 게이트는 6회 중 2회 실패한다**(§9-63.5) — 실패를 보면 먼저 원인을 읽는다. > 강한 신호는 CI 두 잡이다. > -> 📌 **본문은 §9-73이다**(`docs/history/9-73.md`). 그 앞의 2026-09-26 (6) 항목(헬퍼 체크 전파 닫힘)은 -> 바이트 그대로 옮겼다 — 지금은 `docs/history/start-block-054.md`다. +> 📌 **본문은 §9-74다**(`docs/history/9-74.md`). 그 앞의 2026-09-27 항목(넓은 중간값 닫힘)은 +> 바이트 그대로 옮겼다 — 지금은 `docs/history/start-block-055.md`다. > > > ### 그 앞의 항목들 — **본문은 `docs/history/start-block-NNN.md`로 옮긴다 (2026-09-23부터)** diff --git a/docs/history/9-74.md b/docs/history/9-74.md new file mode 100644 index 0000000..4778fc0 --- /dev/null +++ b/docs/history/9-74.md @@ -0,0 +1,66 @@ +### 9-74. 인계 정리 (2026-09-27, E2) — **측정 키트를 저장소 밖으로 옮겨 다시 쟀고, 닫힌 기록에만 있던 잔여를 살아 있는 문서로 옮겼다** + +사용자 요청: *"로컬 브랜치 정리해주시고 후속및 잔여작업은 다음세션에서 할수 있게 정리"*. 워크플로 하나(에이전트 13)로 +살아 있는 문서의 열린 항목(53)과 닫힌 기록 9-66~9-73 · 최근 SPEC 넷의 §5가 남긴 잔여(67)를 뽑아 대조하고, 측정 키트의 +의존성을 추적한 뒤, 발견마다 반박 검증을 붙였다(9건 전부 성립 — 문구 · 번호 · 자리를 여럿 고쳐서). + +#### 9-74.1. 로컬 정리 + +- 실험 브랜치 `exp/wide-local`(`3ed8778`) · `exp/wide2-local`(`9f67477`)을 전체 이력 번들로 떠서 **복원 시험**(클론한 머리의 + SHA가 지우기 전과 같다) 뒤에 지웠다. 앞서 지운 `exp/checked-arith-local`의 번들(§9-71.1)도 같은 곳으로 옮겼다 — + 세션 임시 폴더에 있었다. §9-73.6이 적은 *"남아 있다"* 는 이 줄로 끝난다. +- 원격 추적 참조 30개를 걷어냈다(`git fetch --prune` — 원격에는 `main`뿐이었다). 로컬 브랜치는 `main`뿐이고 worktree도 + 하나다. + +#### 9-74.2. 측정 키트 — 세션 임시 폴더에만 있었다 + +§9-69의 626행 코퍼스와 재측정 · 집계 스크립트, 지금까지의 결과 JSON이 **이 세션의 임시 폴더(scratchpad)에만** 있었다. +STATUS ▶의 다음 할 일(17행 귀속)이 그것에 기대는데 새 세션은 그 폴더를 모른다. + +- 저장소 밖 `D:\Source\Mathless-lab\`로 옮겼다(실험 코드 · 측정 데이터는 제품 코드와 섞지 않는다): `kit-626/` 1,181파일 + 7.0MB, 실행 파일 0개. 번들 셋은 `bundles/`. 두 README가 무엇이 어디 있고 어떻게 다시 재는지 적는다. +- **옮긴 자리에서 다시 쟀다**: `main` c70e02d로 빌드한 `mlprobe`로 626행 — 맞음 543 · 조용한 오답 44 · 참값이 드는데 `-3` + 20 · 기타 18, 판정 불명 0, b077cb9 기준선(§9-73.3)과 **출력이 다른 행 0**. 기존 집계 스크립트 둘도 옮긴 자리에서 같은 + 표를 냈다. +- 에이전트가 짚은 함정을 README에 옮겼다: `RM_OUT`의 기본값이 기준 데이터를 덮어쓴다 · 집계는 변형 목록이 코드에 박혀 + 있다(그래서 목록 없는 `tally.py`를 더했다) · 실험 빌드의 출력 JSON은 다시 만들 수 없다(`main`은 실험 스위치를 읽지 않는다). +- 다음 측정의 입력으로 20행 목록을 떠 두었다. 그중 3행(stateful R4-oob1~3)이 FULL과 다른 행이다 — §9-73.7의 *"3행은 + 배열 읽기"* 가 행 이름으로 확인됐다. + +#### 9-74.3. 닫힌 기록에만 있던 잔여 — 살아 있는 자리로 + +| 잔여 | 출처 | 옮긴 자리 | +|---|---|---| +| `runtime/ml_abi.h`가 `-1`만 정의한다(`-2`는 #200부터, `-3`은 생성 헤더에만) | SPEC-checked-arithmetic §5 | STATUS §5-7 | +| 주변 `RUSTFLAGS=-D warnings`에서 기존 경고가 있는 모듈의 빌드가 깨진다 | §9-72.7 · SPEC-helper-check-propagation §5 | STATUS §5-8 | +| `!` 문맥 검사의 실행 속도는 잰 적이 없다 | 세 SPEC §5 | STATUS §5-9 | +| 문서 가드의 알려 둔 사각 넷 | §9-66.7 | STATUS §5-10 | +| 모듈 사이 C 매크로 이름이 겹칠 수 있다(`ML_A_CONST_ERR_Q`) | §9-68 · SPEC-constants §5 | `HOST_ABI.md` 네이밍 규약 | +| `enum`·타입 있는 상수 집합 | §9-68 · SPEC-constants §0.3·§5 | `LANGUAGE.md` 공백 블록 + `language_gaps.rs` + 후보 목록 | +| 상수식 오버플로 진단 | SPEC-checked-arithmetic DP-O9·§5 | `slices/README.md` 후보 목록 | + +- 검증이 고친 것: `-D warnings`의 머리말이 너무 넓었다(경고 없는 모듈은 빌드된다 — 검증 에이전트가 쟀고, 쓰지 않는 내부 + 함수의 `dead_code`도 그때 측정됐다) · `C4005`는 경고이고 실패는 `/WX` 때문이다 · 속도 항목의 출처 하나(§9-69.6)는 다른 + 이야기였다 · STATUS §5의 다음 빈 번호는 7이다 · 가드 사각을 적는 문장에 그 가드가 세는 낱말을 쓰면 가드가 빨개진다. +- `enum` 행은 테스트부터 썼다: `GAPS`에 행을 더하자 첫 빨강이 *"블록이 '`enum`'을 적지 않는다"* 였고(메시지를 읽었다), + 공백 블록에 항목을 더해 초록. + +#### 9-74.4. 제자리에서 고친 낡은 문장 + +- `docs/phase1/WBS.md` 머리말의 *"Delphi만 미검증"*(같은 파일 아래가 로컬 게이트로 닫혔다고 적는다) · 같은 파일의 + *"고정 workdir명 유지"*(#19가 갚았고 같은 파일의 표가 그렇게 적는다 — 형제 항목처럼 취소선 + 처리됨). +- `OPEN_QUESTIONS.md`의 "Claude에게"가 남은 결정을 Q6~Q11로 적어 Q16 · Q17이 빠졌다 — 번호 대신 그 절을 가리키게 했다. +- `LANGUAGE.md` 공백 블록이 복합 대입을 두 번 적었다 — 한 번으로. +- STATUS §5-4의 줄 번호 포인터 셋이 밀려 있었다(`codegen.rs:39` → 지금 140 등) — 가드가 없는 줄 번호 대신 심볼 이름으로. +- `docs/phase1/SPEC.md`도 *"Delphi 미검증"* 을 여섯 곳에 적지만 **설계 기록**이라(머리말) 고치지 않았다. + +#### 9-74.5. 잔여가 아니었던 것 (대조가 걸러 낸 것) + +지역 변수 폭(SPEC-wide-intermediates §2.6이 i32로 정했다) · C 백엔드의 실제 구현(Q6 · D19 · `LANGUAGE.md`의 요구) · +비ASCII 비교(Q17의 재검토 조건) · `export const`의 f64 · bool · string과 상수 식(`LANGUAGE.md`가 제약으로 적는다) · 무한 +함수를 호스트가 직접 부를 때의 오버플로(D17 — 채널이 없는 설계) · §9-69.6의 *"표본이 덮지 않은 것"*(표본의 경계이지 할 +일이 아니다). + +#### 9-74.6. 남은 것 + +STATUS ▶이 정본이다: 17행 귀속(키트 위치 포함) · §5-7과 §5-8 · C# 호스트 · LSP · X1 · X2. diff --git a/docs/history/start-block-055.md b/docs/history/start-block-055.md new file mode 100644 index 0000000..3acd78d --- /dev/null +++ b/docs/history/start-block-055.md @@ -0,0 +1,20 @@ +> ### 2026-09-27 기준 — **넓은 중간값 슬라이스가 닫혔다: `!` 문맥의 순수 산술 식은 정확히 계산된다 (§9-73)** +> +> SPEC을 권고안대로 확인받아 슬라이스로 닫았다(#341 SPEC · #342 구현). `!` 문맥의 순수 산술 식은 i64로 계산해 값이 +> i32가 되어야 하는 자리에서 한 번 좁힌다. 참값이 드는데 `-3`인 행 59 → 20(626행, 시험 구현과 행마다 같다). 실제 C 호스트가 +> 바꾼 `one_payment`로 곱이 i32 밖인 입력의 정답을 받는다. 지문·ABI·바인딩은 그대로다. +> +> **▶ 다음 세션 — 여기서 시작한다.** 순서대로: +> +> 1. **강제되는 슬라이스가 없다 — 다음은 측정이다.** 참값이 드는데 `-3`으로 남은 20행 중 17행(FULL로도 남는 행)이 +> 무엇인지 귀속하지 않았다(§9-73.7). 귀속이 `i64` 타입이나 다른 후보(`docs/slices/README.md`의 "다음 슬라이스" 절)를 +> 가리키면 그때 SPEC을 쓴다. +> 2. **작은 항목**: C# 호스트(Phase 4) · LSP(Phase 3, 큰 일). +> 3. **외부**: `X1`·`X2` — Delphi가 있는 CI 러너. 이 저장소 안에서는 닫히지 않는다. +> +> ⚠ **이 머신의 전체 게이트는 6회 중 2회 실패한다**(§9-63.5) — 실패를 보면 먼저 원인을 읽는다. +> 강한 신호는 CI 두 잡이다. +> +> 📌 **본문은 §9-73이다**(`docs/history/9-73.md`). 그 앞의 2026-09-26 (6) 항목(헬퍼 체크 전파 닫힘)은 +> 바이트 그대로 옮겼다 — 지금은 `docs/history/start-block-054.md`다. +> diff --git a/docs/history/start-block-index.md b/docs/history/start-block-index.md index bc810a4..4432a76 100644 --- a/docs/history/start-block-index.md +++ b/docs/history/start-block-index.md @@ -9,6 +9,7 @@ > | 날짜 | 무엇을 했나 | 본문 | > |---|---|---| +> | 2026-09-27 | **넓은 중간값 슬라이스가 닫혔다: `!` 문맥의 순수 산술 식은 정확히 계산된다** — 같은 날 인계 정리(§9-74) | §9-73 | > | 2026-09-26 (6) | **헬퍼 체크 전파 슬라이스가 닫혔다: `!`를 위해 실행되는 산술은 어디서든 검사된다** — 다음 날 넓은 중간값 슬라이스로 닫혔다(§9-73) | §9-72 | > | 2026-09-26 (5) | **체크드 산술 다음을 쟀다: 헬퍼 체크 전파가 조용한 오답을 가장 많이 줄인다** — 같은 날 슬라이스로 닫혔다(§9-72) | §9-71 | > | 2026-09-26 (4) | **체크드 정수 산술 슬라이스가 닫혔다: `!` 본문의 오버플로가 `-3`이 됐다** — 같은 날 다음 후보를 쟀다(§9-71) | §9-70 | diff --git a/docs/phase1/WBS.md b/docs/phase1/WBS.md index 3cfa55b..01c6aa6 100644 --- a/docs/phase1/WBS.md +++ b/docs/phase1/WBS.md @@ -6,7 +6,8 @@ > 진행(2026-08-31 실측): **W0~W7 ✅** · **STEP1 CLI ✅** · **W8~W17 ✅**. 아래 "W7 이후" 표가 정본이다 — > D17 에러 경로 · `let` · `i32` · `let mut` · 수용 D(C 호스트) · `while` · 단항 · `&&`/`||` · > 내부 함수와 호출 · `as`까지 전부 머지됐다. (이 줄이 W10에서 멈춰 있었다 — 2026-08-31 정정.) -> **수용 A/B/C 완료 + D는 C 호스트로 통과**(2026-08-29). **Delphi(`dcc64`)만 미검증**. +> **수용 A/B/C 완료 + D는 C 호스트로 통과**(2026-08-29). **Delphi는 로컬 게이트까지**(`MATHLESS_GATE_DELPHI`, +> 아래 게이트/블로커) — CI는 X1로 남았다. > 테스트 수·CI 구성의 정본은 `docs/STATUS.md`다(여기 숫자를 복제하면 곧 낡는다 — 실제로 두 번 낡았다). > 잔여 작업 목록의 정본은 `docs/STATUS.md` §9(**▶ 여기서 시작한다** 블록)다. > @@ -73,7 +74,7 @@ W0~W7은 원래 SPEC의 계획이었다. 아래는 그 뒤에 **별도 SPEC + - **W4 필수(Grok 지적) — 처리됨(강화):** 초기에는 codegen이 마지막 문이 `return`이 아니면 거부했으나(`block_always_returns`), 이후 **typeck로 올려** "모든 경로 return"을 프런트엔드에서 강제한다(PR #20) — 진단이 소스에 가까워짐. - **크로스 타깃 식별자 하드닝 — 처리됨:** 파라미터명이 대상 언어(Rust/C/Pascal) 예약어와 겹치면 typecheck가 명확한 에러로 거부한다(`compiler/src/reserved.rs`; 프런트엔드 단일 검사 → 모든 백엔드 보호, Pascal은 대소문자 무시). 함수명은 `mlx_` 접두어라 안전. - **잔여 하드닝(버그 아님):** - - `mlc build`(`emit_artifacts`)는 호출마다 고유 임시 빌드 트리(`mlc-build--`)를 쓰고 성공·실패와 무관하게 정리한다 → CLI 경로 경합/임시폴더 누수 해소(STEP1, Grok verify 반영). `codegen::build_cdylib`의 직접 소비자(테스트 `end_to_end`/`protection`)는 고정 `workdir`명 유지(직렬 실행이라 미실현 경합). + - `mlc build`(`emit_artifacts`)는 호출마다 고유 임시 빌드 트리(`mlc-build--`)를 쓰고 성공·실패와 무관하게 정리한다 → CLI 경로 경합/임시폴더 누수 해소(STEP1, Grok verify 반영). ~~`codegen::build_cdylib`의 직접 소비자(테스트 `end_to_end`/`protection`)는 고정 `workdir`명 유지~~ → **처리됨**(#19): 테스트는 `common::TempOut`(`%TEMP%/mlc__`, drop 때 삭제)에 빌드한다. - ~~`mlc build` 산출은 원자적이지 않다~~ → **처리됨**(#42): 세 산출물을 `out_dir` 안의 스테이지에 모두 만든 뒤 이동한다. 이동이 실패하면 이번 호출이 놓은 것을 걷어내고 밀어냈던 기존 파일을 되돌린다. 남는 실패 창은 이동 그 자체뿐이며, **롤백 도중 크래시**까지는 보장하지 않는다(저널이 필요한 범위 — 하지 않는다). - ~~모듈명에 식별자 검증이 없다~~ → **처리됨**(#42): `emit_artifacts`가 진입 즉시 모듈명을 검사한다 — 식별자 + `reserved.rs` 전 대상 + Windows 예약 장치명(`nul`/`con`/`com1`…). 이름은 생성 `Cargo.toml`의 `name = "…"`, C 헤더 가드, Delphi unit 이름, 그리고 **파일명**에 그대로 들어간다. 같은 검토에서 `reserved.rs`의 PASCAL 목록에 **`at`·`on` 누락**을 발견해 함께 채웠다 — 이는 파라미터·지역 변수명에도 영향이 있었다(E1: Delphi 문서상 예약어, dcc64 없어 컴파일 확인 불가). - ~~후속 변수(local) 도입 시 예약어 검사를 변수명에도 확장.~~ → **처리됨**: `let` 슬라이스(PR #26)가 지역 변수명에도 `reserved.rs`와 `out_value` 검사를 적용한다. diff --git a/docs/slices/README.md b/docs/slices/README.md index 04947a5..fbdd773 100644 --- a/docs/slices/README.md +++ b/docs/slices/README.md @@ -129,6 +129,9 @@ TDD 구현 → Grok 검증 → PR** 순서를 따른다(`CLAUDE.md` "개발 방 *(2026-09-25 로드맵 검토에서 더했다 — Phase 2의 다섯 항목 중 이 둘이 이 목록에 없었다.)* §7(§9-69, 12개 도메인 72규칙과 귀속 대조)이 더한 후보: **`wrapping_*` 내장 함수**(무한 헬퍼라는 탈출구(DP-O7)가 §9-72로 사라졌다 — 필요가 측정되면), **i64**(§9-71: 옵트인이라 귀속 대조에서 51행이 빠졌다), **입력 문자열의 인코딩 계약**(닫힌 DP-S2의 재개 — `OPEN_QUESTIONS.md` Q17이 (A)로 열어 두었고 재검토 조건은 거기 있다), 비트 연산자, 지역 작업 배열, 수학 내장 함수, 문자 단위 길이. +닫힌 SPEC의 §5에만 있던 후보: **상수식 오버플로 진단**(컴파일 에러 — `SPEC-checked-arithmetic.md` DP-O9가 가산적으로 +미뤘다. `SPEC-wide-intermediates.md` DP-W7대로 정확한 값을 따라야 하므로 `2147483647 + 1 - 1`은 합법이고 `2147483647 + 1`만 대상이다), +**`enum`·타입 있는 상수 집합**(`SPEC-constants.md` §0.3·§5 — `LANGUAGE.md` 공백 블록에도 있다). **struct는 §9-1이 강제되지 않는다고 결론냈다** — 고르려면 그 절을 먼저 읽는다(§9-69도 귀속 0으로 다시 확인했다). 배열도 같은 결론이었고(§9-9가 다섯 번째로), **입력은 그 사실을 SPEC 첫 절에 적은 채로 열렸다**. From 9fb2f8a79c19783dc8331800371ead135a6f09e8 Mon Sep 17 00:00:00 2001 From: xzawed <47019855+xzawed@users.noreply.github.com> Date: Sun, 27 Sep 2026 07:57:14 +0900 Subject: [PATCH 2/2] =?UTF-8?q?docs:=20=C2=A79-74=20counts=20the=20kit=20a?= =?UTF-8?q?s=20moved,=20then=20what=20was=20added?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 (1M context) --- docs/history/9-74.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/history/9-74.md b/docs/history/9-74.md index 4778fc0..6d27da9 100644 --- a/docs/history/9-74.md +++ b/docs/history/9-74.md @@ -17,8 +17,8 @@ §9-69의 626행 코퍼스와 재측정 · 집계 스크립트, 지금까지의 결과 JSON이 **이 세션의 임시 폴더(scratchpad)에만** 있었다. STATUS ▶의 다음 할 일(17행 귀속)이 그것에 기대는데 새 세션은 그 폴더를 모른다. -- 저장소 밖 `D:\Source\Mathless-lab\`로 옮겼다(실험 코드 · 측정 데이터는 제품 코드와 섞지 않는다): `kit-626/` 1,181파일 - 7.0MB, 실행 파일 0개. 번들 셋은 `bundles/`. 두 README가 무엇이 어디 있고 어떻게 다시 재는지 적는다. +- 저장소 밖 `D:\Source\Mathless-lab\`로 옮겼다(실험 코드 · 측정 데이터는 제품 코드와 섞지 않는다): `kit-626/`으로 옮긴 것이 + 1,181파일 7.0MB, 실행 파일 0개이고, 그 뒤 README · `tally.py` · 20행 목록 · 재측정 결과를 더했다. 번들 셋은 `bundles/`. 두 README가 무엇이 어디 있고 어떻게 다시 재는지 적는다. - **옮긴 자리에서 다시 쟀다**: `main` c70e02d로 빌드한 `mlprobe`로 626행 — 맞음 543 · 조용한 오답 44 · 참값이 드는데 `-3` 20 · 기타 18, 판정 불명 0, b077cb9 기준선(§9-73.3)과 **출력이 다른 행 0**. 기존 집계 스크립트 둘도 옮긴 자리에서 같은 표를 냈다.