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
29 changes: 29 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,35 @@ jobs:
echo "$out" | grep -q "__SHIM_TEST__ PASS" \
|| { echo "::error::native i386_cpu_test FAIL (E3 interpreter regression)"; exit 1; }

# ── Metal offscreen smoke — E5 substrate proof (F-NSWINDOW-E5 r10).
# Verifies that headless Metal offscreen render + pixel readback works on the
# runner (no display needed). own1: plain Apple Metal, no game asset, no Wine.
# validated_manjeom stays 0 — this is a substrate proof, NOT a game frame.
#
# Warn-only: if the runner has no GPU session → __METAL_SMOKE__ SKIP (exit 0,
# no-device path). If it has a GPU → __METAL_SMOKE__ PASS (exit 0) or FAIL
# (exit 1, but we still only warn so a transient runner issue doesn't red the
# build). The grep surfaces whether we got PASS or SKIP in the CI log.
- name: Smoke — headless Metal offscreen render (E5 substrate)
shell: bash
run: |
set -uo pipefail
SDK="$(xcrun --sdk macosx --show-sdk-path)"
clang -arch arm64 -isysroot "$SDK" -fobjc-arc -O2 -Wall -Wextra \
-framework Metal -framework Foundation \
-o "$RUNNER_TEMP/metal_offscreen_smoke" \
native/metal_offscreen_smoke.m \
|| { echo "::warning::metal_offscreen_smoke compile failed (E5 substrate — warn-only)"; exit 0; }
out="$("$RUNNER_TEMP/metal_offscreen_smoke" 2>&1)" || true
echo "$out"
if echo "$out" | grep -q "__METAL_SMOKE__ PASS"; then
echo "E5-substrate: PASS — headless Metal offscreen render confirmed on this runner"
elif echo "$out" | grep -q "__METAL_SMOKE__ SKIP"; then
echo "::warning::E5-substrate: SKIP — no GPU/Metal session on this runner (ground-truth finding, not a failure)"
else
echo "::warning::E5-substrate: FAIL or no output — see log above (warn-only)"
fi

# ── CLI smoke — own2 PASS/FAIL/PARTIAL subcommands compile + run.
- name: Smoke — gamebox CLI subcommands
shell: bash
Expand Down
10 changes: 7 additions & 3 deletions ARCHITECTURE.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,21 @@
"summary": "validated_manjeom=0(실 게임 프레임 미증명) 돌파의 명명된 사다리 = native E-series (docs/CLOSURE_ROADMAP.md §5). fleet-lab F-NSWINDOW-E5 가 추적. 각 라운드 measured 결과를 여기 update-in-place 박제 → 차세션 research 가 흩어진 메모리 대신 한 곳에서 표적을 본다.",
"children": [
{
"name": "F-NSWINDOW-E5 — E1✅ E2✅ E3✅ E4🛠️(user-entry 도달) E5",
"summary": "validated_manjeom=0 돌파 사다리(docs/CLOSURE_ROADMAP.md §5). E1 PE-parse+mmap done(CM-25a)·E2 i386 디코더 done(CM-25b)·E3 i386 인터프리터 done(실 game-binary EXECUTE)·E4 kernel32 IAT 바인딩 IN-PROGRESS(합성 prologue가 CRT→user-entry handoff 도달, insns=60, K32 import 13)·E5 first NSWindow=validated_manjeom>0 첫후보(CM-25e). 실행은 native/ C(i386_cpu.c)·lib/loader/pe_i386_*.hexa는 TSV 트래커(실행 아님)."
"name": "F-NSWINDOW-E5 — E1✅ E2✅ E3✅ E4✅(IAT name-autobind) E5🛠️(Metal substrate proven)",
"summary": "validated_manjeom=0 돌파 사다리(docs/CLOSURE_ROADMAP.md §5). E1 PE-parse+mmap done·E2 i386 디코더 done·E3 i386 인터프리터 done(실 game-binary EXECUTE)·E4 kernel32 IAT name-autobind done(합성 prologue CRT→user-entry handoff·insns=60·K32 13·IAT name-autobind)·E5 Metal substrate IN-PROGRESS: r10(#32) 헤드리스 Metal 오프스크린 렌더+readback 로컬 PASS(M4·Apple M4 device)·CI 러너 ground-truth 확인 중. 다음 r11 = D3D11 device shim → Metal 오프스크린 경로 배선."
},
{
"name": "E4 r5 measured (2026-06-26·#19/24/25/26 merged) — 18명령 실행·kernel32 5 import 바인딩",
"summary": "native/i386_cpu.c 인터프리터가 실 __scrt_common_main prologue 18명령 실행. import-stub registry 5엔트리 바인딩(GetCurrentThreadId·GetCurrentProcessId·GetTickCount·GetSystemTimeAsFileTime[버퍼쓰기 shim·LPFILETIME 8B mem_write]·QueryPerformanceCounter). 디코더 group-1 imm+mov r/m imm+byte mov+test+and/or+shift(0xC1/D1/D3) 커버(C+i386_decode.hexa RUNEQ byte-eq). EFLAGS(CF/PF/AF/ZF/SF/OF) 모델. 측정: insns 1(r2)→9(r3)→11(r4)→**18(r5)**·halt@0x5392A1=unbound IAT slot 0x538014. Blacksmith CI 게이트(i386_cpu_test PASS·ci.yml native step). own1: 로더가 자기 import 바인딩=로딩(바이패스 아님)·kernel32=OS API·Wine/QEMU 0. ⚠️ validated_manjeom 여전히 0(로더 진척·프레임 아님·E5가 프레임)."
},
{
"name": "E4 r7–r9 measured (2026-06-26·#29/#30/#31 merged) — 60명령·user-entry handoff·IAT name-autobind·CMPXCHG",
"name": "E4 r7–r9 measured (2026-06-26·#29/#30/#31 merged) — 60명령·user-entry handoff·IAT name-autobind·CMPXCHG",
"summary": "native/i386_cpu.c 인터프리터가 합성 __scrt_common_main prologue를 r7 벽(unbound IAT @0x539318, insns=44) 너머로 전진 → CRT init 종점 = `call WinMain` CRT→user-entry handoff(i386_cpu_t.user_entry_va + I386_HALT_USER_ENTRY). 디코더: 0F AF/69/6B IMUL·0F A2 CPUID·0F 31 RDTSC(r7) + 0F A3/AB/B3/BB BT/BTS/BTR/BTC(r8) — C + i386_decode.hexa RUNEQ byte-eq. import: security cookie 산술 + GetCommandLineW(0x53802C)·SetUnhandledExceptionFilter(0x538030) 바인딩, K32 11→13. 측정: insns 44(r7)→60(r8)·halt@0x539400=user_entry(call). Blacksmith CI 게이트(i386_cpu_test 25 checks PASS·-Wall -Wextra -std=c11). real-PE 경로 i386_cpu_load_pe 구조적 배선완료(섹션+entry 매핑)·미실행(IAT name-autobind 필요). ⚠️ validated_manjeom 여전히 0(합성 user-entry·실 프레임 아님). **r9(#31)**: IAT **name-based autobind** 구현 — 실 PE의 IAT를 합성 VA가 아니라 import 이름으로 native shim에 바인딩(pe_parse import_dir + IMAGE_IMPORT_BY_NAME walk + strcmp), 미매칭→I386_HALT_UNBOUND_IMPORT+이름기록. CMPXCHG 0F B0/B1 디코더+executor(RUNEQ). Run E: autobind total=3 bound=3 unbound=0·mini-run GetCurrentThreadId 슬롯통과(eax=0x1A2B). **실 PE가 첫 import 너머 실행 가능 = real-PE 경로 배선 진전**. 다음 r10 표적 = DX→Metal 브리지(헤드리스 Metal 오프스크린 readback smoke 먼저 CI 검증)."
},
{
"name": "E5 r10 measured (2026-06-26·#32) — 헤드리스 Metal 오프스크린 렌더+readback 로컬 PASS (서브스트레이트 증명)",
"summary": "native/metal_offscreen_smoke.m (ObjC+Metal+Foundation): 64×64 MTLPixelFormatBGRA8Unorm 오프스크린 텍스처·인라인 MSL(newLibraryWithSource:)·blue 클리어+red 삼각형 1 드로우·waitUntilCompleted·getBytes readback·픽셀 어서션 (px_clear=0x0000FFFF·px_triangle=0xFF0000FF·nonuniform=1). 로컬 M4 결과: __METAL_SMOKE__ PASS device=Apple M4. CI(blacksmith-6vcpu-macos-15·실 Apple-Silicon·GPU) 결과: 확인 예정(warn-only step). own1: 순수 Apple Metal·Wine 0·게임 애셋 0. 서브스트레이트 증명 — 게임 프레임 아님·validated_manjeom=0. break-walls+verify-done: \"디스플레이 불필요·Metal 헤드리스 렌더 가능\" 어서션을 실행·CI-게이트 사실로 전환. r11 표적: D3D11 device/swapchain 셰임(lib/loader/dx_d3d11.hexa 실 Metal 배선) → CreateDevice/CreateSwapChain → 이 증명된 오프스크린 경로 라우팅 + 최소 D3D11 테스트 PE 인터프리터 실행."
},
{
"name": "🧱 E5 게이트 재분류 (2026-06-26 실측 — substrate/투자 프론티어, 하드웨어 천장 아님)",
"summary": "validated_manjeom>0(실 프레임) 도달 게이트를 실측 재분류. ① real i386 D3D PE — 최소 D3D11 테스트 PE 자작 가능(own1 클린·꼭 AAA 아님). ② D3DMetal SDK — 'CI 부재'는 틀림: `brew tap apple/apple && brew install game-porting-toolkit`로 Blacksmith macos-15(실 Apple Silicon·GPU)에 설치 가능(하드웨어 무관). ③ 디스플레이 — 불필요: Metal 헤드리스(오프스크린 MTLTexture→getBytes readback)로 화면 없이 프레임 증명 가능(M4/Metal4 확인). → 진짜 벽 = 엔지니어링 거리: lib/loader/dx_d3d11.hexa 등 DX→Metal 브리지는 MTL* 이름만 적힌 텔레메트리 스캐폴드(실 Metal 호출 0건). 다음 사다리(자율가능, 실-GPU CI 위): real-PE IAT name-autobind → 넓은 opcode 커버 → D3D11 device shim → 실 MTLDevice/오프스크린 → readback. 이전 'real-asset user-only 게이트' 분류는 verify 안 한 게으른 벽(break-walls 위반)이라 정정."
Expand Down
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,31 @@ All notable changes to `gamebox` are documented in this file.

### Added

- feat(F-NSWINDOW-E5 r10): **헤드리스 Metal 오프스크린 렌더 + 픽셀 readback 스모크 (E5 서브스트레이트 증명)**
— r9 가 명시한 다음 과제(`r10 표적 = DX→Metal 브리지(헤드리스 Metal 오프스크린 readback smoke 먼저 CI 검증)`)를
완료한다. **서브스트레이트 증명 — 게임 프레임 아님; `validated_manjeom` 여전히 0.** (1) **`native/metal_offscreen_smoke.m`**
(Objective-C + Metal + Foundation): `MTLCreateSystemDefaultDevice()` 호출 → GPU 없으면
`__METAL_SMOKE__ SKIP reason=no_device` + `exit(0)`(정직 ground-truth, 실패 아님).
GPU 있으면: 64×64 `MTLPixelFormatBGRA8Unorm` 오프스크린 텍스처(`RenderTarget|ShaderRead·StorageModeShared`)
생성, `newLibraryWithSource:`로 인라인 MSL(vertex + fragment) 컴파일, 렌더 패스 = blue 클리어(RGBA 0,0,1,1)
+ red 삼각형(RGBA 1,0,0,1) 1개 드로우, `waitUntilCompleted`, `-[MTLTexture getBytes:bytesPerRow:fromRegion:mipmapLevel:]`
로 픽셀 readback. 픽셀 어서션: 클리어 영역 = `0x0000FFFF`(blue), 삼각형 영역 = `0xFF0000FF`(red),
두 픽셀이 다름(`nonuniform=1`) — 실 렌더가 일어났음. 통과 시 `__METAL_SMOKE__ PASS device=<name>
px_clear=<hex> px_triangle=<hex> nonuniform=1`, 실패 시 `__METAL_SMOKE__ FAIL reason=...`.
서드파티 없음(Metal + Foundation만). (2) **`native/build.sh`** — `metal_offscreen_smoke` 빌드 타깃
추가(ObjC ARC + Metal/Foundation 프레임워크; `-std=c11`·`-Wpedantic` 제외). ad-hoc codesign.
(3) **`.github/workflows/ci.yml`** — `Smoke — headless Metal offscreen render (E5 substrate)` 스텝
추가: E3 native 인터프리터 스텝 직후, CLI smoke 직전. compile + run → `__METAL_SMOKE__` 파싱 →
PASS/SKIP/FAIL 각각 명확히 로그. **warn-only**(컴파일 실패·GPU 없음·런타임 오류 모두 `::warning::`;
빌드를 red 내지 않음) — 러너의 GPU 유무를 학습하는 것이 목표. 로컬 실행 결과(M4 Mac):
`__METAL_SMOKE__ PASS device=Apple M4 px_clear=0x0000FFFF px_triangle=0xFF0000FF nonuniform=1`.
Blacksmith CI 러너(`blacksmith-6vcpu-macos-15`, 실 Apple-Silicon·GPU 탑재) 결과는 CI 로그에서 확인 예정.
**own1**: 순수 Apple Metal(프로젝트 자체 렌더 타깃), Wine 0·DRM bypass 0·게임 애셋 0.
gamebox 자작 삼각형 = 서브스트레이트 증명, 인터프리터를 통한 게임 프레임 아님.
**r11 목표**: D3D11 device/swapchain 셰임(`lib/loader/dx_d3d11.hexa` 실 Metal 배선) — CreateDevice/
CreateSwapChain 호출을 이 증명된 Metal 오프스크린 경로로 라우팅 + 최소 D3D11 테스트 PE(own1 클린 자작)
인터프리터 실행 게이트.

- feat(F-NSWINDOW-E5 r9): **IAT 이름 기반 자동 바인딩 + CMPXCHG 디코더·실행**
— r8 이 `INFO real_pe_path=structurally_ready needs:IAT_autobind_by_import_name`
으로 명시한 다음 과제를 완료한다. (1) **`i386_iat_autobind()`**
Expand Down
13 changes: 12 additions & 1 deletion native/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,22 @@ build_signed "pe_to_macho_shim" pe_to_macho_shim.c pe_parse.c
build_signed "i386_decode_test" i386_decode_test.c i386_decode.c pe_parse.c
build_signed "i386_cpu_test" i386_cpu_test.c i386_cpu.c i386_decode.c pe_parse.c

# metal_offscreen_smoke — Objective-C + Metal; own1: plain Apple Metal,
# no game asset, substrate proof (validated_manjeom stays 0).
# Does NOT use -std=c11 / -Wpedantic (ObjC, not C11).
echo "[build] compiling metal_offscreen_smoke (arch=arm64, sdk=macosx, ObjC+Metal)"
"$CC" -arch arm64 -isysroot "$SDK" -fobjc-arc -O2 -Wall -Wextra \
-framework Metal -framework Foundation \
-o metal_offscreen_smoke metal_offscreen_smoke.m
echo "[build] codesigning metal_offscreen_smoke (ad-hoc)"
codesign --force --sign - --timestamp=none metal_offscreen_smoke

echo "[build] verifying signatures"
codesign --verify --verbose=2 pe_to_macho_shim || true
codesign --verify --verbose=2 i386_decode_test || true
codesign -d --entitlements - pe_to_macho_shim 2>&1 | head -10 || true

codesign --verify --verbose=2 i386_cpu_test || true
codesign --verify --verbose=2 metal_offscreen_smoke || true

echo "[build] done — ./pe_to_macho_shim <pe.exe> / ./i386_decode_test <pe.exe> [count] / ./i386_cpu_test [pe.exe]"
echo "[build] done — ./pe_to_macho_shim <pe.exe> / ./i386_decode_test <pe.exe> [count] / ./i386_cpu_test [pe.exe] / ./metal_offscreen_smoke"
Loading
Loading