From ebc48813c0d16098a431fb8a643edf72ececd0e9 Mon Sep 17 00:00:00 2001 From: dancinlife Date: Sat, 27 Jun 2026 14:36:39 +0900 Subject: [PATCH] chore(changelog): CHANGELOG.md -> CHANGELOG.jsonl (append-only JSONL) History SSOT moved from freeform CHANGELOG.md to CHANGELOG.jsonl (newest-first JSONL) via sidecar changelog migrate (gamebox, isolated worktree); harness gate rewired (lint.changelog.file + docs.log + docs.allow) + doc pointers updated. Co-Authored-By: Claude Opus 4.8 (1M context) --- ARCHITECTURE.json | 4 +- ARCHITECTURE.md | 4 +- CHANGELOG.jsonl | 7 + CHANGELOG.md | 705 -------------------------------------------- CLAUDE.md | 6 +- README.md | 2 +- harness.config.json | 6 +- 7 files changed, 18 insertions(+), 716 deletions(-) create mode 100644 CHANGELOG.jsonl delete mode 100644 CHANGELOG.md diff --git a/ARCHITECTURE.json b/ARCHITECTURE.json index 8597b27..1751aeb 100644 --- a/ARCHITECTURE.json +++ b/ARCHITECTURE.json @@ -1,7 +1,7 @@ { "name": "๐Ÿ•น๏ธ gamebox โ€” Apple-native Win32 game runtime", "summary": "Run unmodified Win32 PE games natively on macOS / Apple Silicon via a hexa-only stack โ€” PE loader + Win32 API shim + DirectXโ†’Metal โ€” WITHOUT Wine (Wine 0), under a strict own1 posture (no DRM / Warden / anti-cheat bypass, no anima clone).", - "note": "This JSON tree is the DOMAIN-TREE SSOT (update-in-place, NOT append-only) โ€” it retires the former DOMAINS.tape roster + domains/*.md snapshots + domains/*.log.md logs (folded into CHANGELOG.md 2026-06-18).", + "note": "This JSON tree is the DOMAIN-TREE SSOT (update-in-place, NOT append-only) โ€” it retires the former DOMAINS.tape roster + domains/*.md snapshots + domains/*.log.md logs (folded into CHANGELOG.jsonl 2026-06-18).", "meta": { "ssot": "github.com/dancinlife/gamebox", "parent": "dancinlab", @@ -50,7 +50,7 @@ }, { "name": "โ„น๏ธ doc pointers (SSOT split)", - "summary": "Component-level final-architecture prose lives in ARCHITECTURE.md; history/decisions โ†’ CHANGELOG.md; governance โ†’ CLAUDE.md; per-game/launcher SSOT โ†’ .roadmap.* + .checkpoint.* (this doc points, never duplicates)." + "summary": "Component-level final-architecture prose lives in ARCHITECTURE.md; history/decisions โ†’ CHANGELOG.jsonl; governance โ†’ CLAUDE.md; per-game/launcher SSOT โ†’ .roadmap.* + .checkpoint.* (this doc points, never duplicates)." }, { "name": "โ„น๏ธ node schema", diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index c1b7531..8276426 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -3,7 +3,7 @@ > Single source of truth for the **final** architecture (component-level prose). > Update (overwrite) this file in place when the design changes โ€” it is **not** > append-only. History and per-change decisions live in -> [CHANGELOG.md](CHANGELOG.md). The **domain tree** (per-subsystem / per-game +> [CHANGELOG.jsonl](CHANGELOG.jsonl). The **domain tree** (per-subsystem / per-game > goals + milestones) is `ARCHITECTURE.json` (tree SSOT, human viewer > `ARCHITECTURE.html` via `python3 serve.py`) โ€” it retired the former > `DOMAINS.tape` + `domains/` snapshots on 2026-06-18. @@ -79,7 +79,7 @@ CM-26..CM-30 (full launch + first-frame + sustained-frame render) land. reason; predecessor markers are preserved verbatim for traceability. - **Harness** โ€” this repo is governed by the dancinlab harness (`.harness-engine/` submodule, `harness.config.json`). Architecture changes - update **this file** (SSOT); history goes to `CHANGELOG.md`; transient output + update **this file** (SSOT); history goes to `CHANGELOG.jsonl`; transient output goes under `scripts/scratch/`. Run `bash .harness-engine/bin/harness verify` (wraps `hexa verify`) and `bash .harness-engine/bin/harness docs check` before shipping. See [CLAUDE.md](CLAUDE.md) for the harness quick reference. diff --git a/CHANGELOG.jsonl b/CHANGELOG.jsonl new file mode 100644 index 0000000..061661a --- /dev/null +++ b/CHANGELOG.jsonl @@ -0,0 +1,7 @@ +{"ts":"2026-06-27","title":"chore(changelog): CHANGELOG.md -> CHANGELOG.jsonl (append-only JSONL)","body":"History SSOT moved from freeform CHANGELOG.md to CHANGELOG.jsonl (newest-first JSONL) via sidecar changelog migrate (gamebox, isolated worktree); gate rewired + doc pointers updated."} +{"ts":null,"title":"[Unreleased]","body":"### Added\n\n- feat(F-NSWINDOW-E5 r12): **PEโ†’D3D11โ†’Metal end-to-end: ์ฒซ own1 D3D11 PE โ†’ Metal ํ”„๋ ˆ์ž„ (์ธํ”„๋ผ ๋งˆ์ผ์Šคํ†ค)**\n โ€” r11 ์ด ์ฆ๋ช…ํ•œ D3D11โ†’Metal ๋ธŒ๋ฆฌ์ง€๋ฅผ ์ธํ„ฐํ”„๋ฆฌํ„ฐ์— ๋ฐฐ์„ ํ•˜๊ณ , ์ž์ž‘ ์ตœ์†Œ i386 PE ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ\n ์‹ค์ œ Metal ๋ Œ๋” ํ”„๋ ˆ์ž„์„ ํ”ฝ์…€๋กœ ์ฝ์–ด ๊ฒ€์ฆํ•œ๋‹ค.\n **์ •์งํ•œ ํ‰๊ฐ€(own2)**: ์ด๊ฒƒ์€ ์ธํ”„๋ผ ๋งˆ์ผ์Šคํ†ค โ€” gamebox ๋Ÿฐํƒ€์ž„์ด ์ž์ž‘ own1 D3D11 PE ๋ฅผ ์ธํ„ฐํ”„๋ฆฌํ„ฐ๋กœ\n ์‹คํ–‰ํ•ด Metal ๋ Œ๋” ํ”„๋ ˆ์ž„์„ ํ”ฝ์…€๋กœ ์ฆ๋ช…ํ•œ *์ฒซ ๋ฒˆ์งธ* ์ผ€์ด์Šค๋‹ค. ์‹ค ์ƒ์—… ๊ฒŒ์ž„(๋””์•„๋ธ”๋กœยท๋ฆฌ๋‹ˆ์ง€ ๋“ฑ)\n ์‹คํ–‰๊ณผ ๋™์ผํ•˜์ง€ ์•Š๋‹ค: ์ „์ฒด Win32/D3D11 API ์„œํ”ผ์Šคยท์‹ค ์• ์…‹ยท์‹ค ๊ฒŒ์ž„ PE ๊ฐ€ ํ•„์š”ํ•˜๋‹ค.\n **validated_manjeom**: `first_own1_authored_d3d11_pe_to_metal_frame` (์ •ํ™•ํ•œ ๋ผ๋ฒจ,\n \"์ƒ์—… ๊ฒŒ์ž„ ํ”„๋ ˆ์ž„\" ์•„๋‹˜). **own1**: Wine 0ยทDXVK 0ยทd3d11.dll ์†Œ์Šค 0ยทDRM 0ยทWarden 0ยท\n ๊ฒŒ์ž„ ์• ์…‹ 0ยทanima clone 0.\n **๋กœ์ปฌ M4 ์‹ค์ธก ๊ฒฐ๊ณผ**:\n `__E5__ PASS pe_executed=1 frame_rendered=1 px_clear=0x0000FFFF px_triangle=0xFF0000FF nonuniform=1 insns=11 imports=7`\n (1) **`native/e5_end_to_end_test.c`** โ€” E5 r12 end-to-end ํ…Œ์ŠคํŠธ (์ˆœ์ˆ˜ C):\n (a) ๋ธŒ๋ฆฌ์ง€ ์˜ค๋ธŒ์ ํŠธ ํ…Œ์ด๋ธ”(g_scยทg_devยทg_ctxยทg_texยทg_rtv ์ •์  ์ „์—ญ,\n g_skip/g_fail ์ƒํƒœ ํ”Œ๋ž˜๊ทธ); (b) 7๊ฐœ ๋ธŒ๋ฆฌ์ง€ shim(d3d11_create 2-arg stdcall 8B\n popยทget_buffer/create_rtv/omset/clear_blue/draw/present 0-arg; ๊ฐ๊ฐ gamebox\n D3D11โ†’Metal ๋ธŒ๋ฆฌ์ง€ C API ๋ž˜ํ•‘); (c) D3D11_SHIMS ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ 7์—”ํŠธ๋ฆฌ โ†’ i386_iat_autobind;\n (d) `build_e5_pe_flat()` โ€” i386 PE32 ํ‰ํƒ„ ์ด๋ฏธ์ง€ ๋นŒ๋”: .text(RVA 0x1000,\n 49๋ฐ”์ดํŠธ ์ฝ”๋“œ)+.idata(RVA 0x2000, d3d11.dll 7 named import; IMAGE_IMPORT_DESCRIPTOR\n +INT+IAT+IBN ๋ ˆ์ด์•„์›ƒ) in-memory ๊ตฌ์„ฑ; (e) main(): PE ๋นŒ๋“œโ†’autobind(total=7 bound=7\n unbound=0)โ†’CPU ์„ค์ •+์‹คํ–‰(insns=11 halt=ret)โ†’readbackโ†’ํ”ฝ์…€ ์–ด์„œ์…˜โ†’`__E5__ PASS/PARTIAL/SKIP`\n ์ถœ๋ ฅ ํ”„๋กœํ† ์ฝœ. (2) **`native/fixtures/d3d11_triangle_min.pe.txt`** โ€” ์ž์ž‘ PE ์™„์ „ ๋ ˆ์ด์•„์›ƒ\n ๋ฌธ์„œ(ํŒŒ์ผ ์˜คํ”„์…‹ยทVAยท์„น์…˜ยทIAT ์Šฌ๋กฏยทimport ์ด๋ฆ„โ†’shim ๋งคํ•‘ยท์ •์ง ํ‰๊ฐ€). (3) PE ์—”ํŠธ๋ฆฌ ์ฝ”๋“œ (49๋ฐ”์ดํŠธ,\n i386 hand-assembled, Intel SDM ๋ช…์‹œ): `6A 40 6A 40`(push height/width=64) +\n `FF 15 [slot]`ร—7(IAT call; ๊ธฐ์กด ์ธํ„ฐํ”„๋ฆฌํ„ฐ ์ปค๋ฒ„๋ฆฌ์ง€) + `33 C0 C3`(xor+ret).\n ๋””์ฝ”๋” ํ™•์žฅ ์—†์Œ(๊ธฐ์กด PUSH_IMM8ยทCALL_RMยทXOR_R_RMยทRET ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉ). (4) IAT ์Šฌ๋กฏ VA:\n 0x402080(create)ยท0x402084(get_buf)ยท0x402088(rtv)ยท0x40208C(omset)ยท0x402090(clear)ยท\n 0x402094(draw)ยท0x402098(present). (5) **`native/build.sh`** โ€” `e5_end_to_end_test` ํƒ€๊นƒ\n ์ถ”๊ฐ€(ObjC ARCยทMetal/Foundation). (6) **`.github/workflows/ci.yml`** โ€”\n `Smoke โ€” E5 end-to-end (PEโ†’D3D11โ†’Metal)` ์Šคํ… ์ถ”๊ฐ€: D3D11 ๋ธŒ๋ฆฌ์ง€ ์Šคํ… ์งํ›„.\n `__E5__ PASS/SKIP/PARTIAL/FAIL` ํŒŒ์‹ฑ, warn-only(r10/r11 ํŒจํ„ด). ARCHITECTURE.json\n blocking-frontiers r12 ์‹ค์ธก ๊ธฐ๋ก.\n **์ฒด์ธ ์„ค๋ช…(์ •์ง)**: own1 ์ž์ž‘ i386 PE(9๋ช…๋ นยท49๋ฐ”์ดํŠธ) โ†’ i386 ์ธํ„ฐํ”„๋ฆฌํ„ฐ(i386_cpu.c)\n IAT autobind(by name, own ์ž„ํฌํŠธ ๋กœ๋”ฉ=๋กœ๋”ฉ์ด์ง€ ๋ฐ”์ดํŒจ์Šค ์•„๋‹˜) โ†’ ๋ธŒ๋ฆฌ์ง€ shim layer โ†’\n gamebox D3D11โ†’Metal ๋ธŒ๋ฆฌ์ง€(d3d11_metal_bridge.m) โ†’ Apple Metal ํ—ค๋“œ๋ฆฌ์Šค ์˜คํ”„์Šคํฌ๋ฆฐ\n ๋ Œ๋”(64ร—64 BGRA8 MTLTexture) โ†’ ํ”ฝ์…€ readback(getBytes) โ†’ ์–ด์„œ์…˜(blue clear โˆง red\n triangle โˆง nonuniform). **๋‹ค์Œ ์ƒ์—… ๊ฒŒ์ž„ ๋ฐฉํ–ฅ**: Win32 API ์„œํ”ผ์Šค ํ™•์žฅยทopcode ์ปค๋ฒ„๋ฆฌ์ง€\n ํ™•์žฅยทvtable ๋””์ŠคํŒจ์น˜([reg+offset] ๊ฐ„์ ‘ call)ยท์‹ค ๊ฒŒ์ž„ PE IAT ์ถ”์ .\n\n- feat(F-NSWINDOW-E5 r11): **D3D11โ†’Metal ๋ธŒ๋ฆฌ์ง€ + ๋„ค์ดํ‹ฐ๋ธŒ ๋“œ๋ผ์ด๋ฒ„ ํ…Œ์ŠคํŠธ (๊ตฌํ˜„๋จยท๋ฏธ๋ฐฐ์„ )**\n โ€” r10 ์ด ์ฆ๋ช…ํ•œ ํ—ค๋“œ๋ฆฌ์Šค Metal ์˜คํ”„์Šคํฌ๋ฆฐ ๋ Œ๋” ์„œ๋ธŒ์ŠคํŠธ๋ ˆ์ดํŠธ ์œ„์—, D3D11-์ธํ„ฐํŽ˜์ด์Šค-ํ˜•์ƒ์˜\n Metal ๋ธŒ๋ฆฌ์ง€๋ฅผ ๊ตฌ์ถ•ํ•˜๊ณ  ๋„ค์ดํ‹ฐ๋ธŒ ๋“œ๋ผ์ด๋ฒ„ ํ…Œ์ŠคํŠธ๋กœ ๊ฒ€์ฆํ•œ๋‹ค.\n **own1**: gamebox ์ž์ฒด D3D11 ์ธํ„ฐํŽ˜์ด์Šค ํ˜•์ƒ โ†’ Apple Metal ๋ผ์šฐํŒ…. Wine 0ยทDXVK 0ยท\n d3d11.dll ์†Œ์Šค 0ยทDRM 0ยทWarden 0ยท๊ฒŒ์ž„ ์• ์…‹ 0. **validated_manjeom ์—ฌ์ „ํžˆ 0** โ€” ๋ธŒ๋ฆฌ์ง€๋Š”\n ๋„ค์ดํ‹ฐ๋ธŒ ํ…Œ์ŠคํŠธ๋กœ ์ฆ๋ช…๋์œผ๋‚˜ ์•„์ง i386 ์ธํ„ฐํ”„๋ฆฌํ„ฐ๋ฅผ ํ†ตํ•ด PE๊ฐ€ ๊ตฌ๋™ํ•˜์ง€ ์•Š์Œ.\n **๊ตฌํ˜„๋จยท๋ฏธ๋ฐฐ์„  (dead-until-wired)** ๋ผ๋ฒจ: r12์—์„œ ์ธํ„ฐํ”„๋ฆฌํ„ฐ IAT autobind ๋ฐฐ์„  ์˜ˆ์ •.\n (1) **`native/d3d11_metal_bridge.h`** โ€” COM ํ˜•์ƒ C ํ—ค๋”: `ID3D11Device`ยท\n `ID3D11DeviceContext`ยท`IDXGISwapChain`ยท`ID3D11RenderTargetView`ยท`ID3D11Texture2D`\n ๊ฐ COM ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์•ž๋‹จ vtable ํฌ์ธํ„ฐ(`lpVtbl`) + `_impl`(opaque bridge-retained\n GBMetalContext\\*)๋กœ ์ •์˜. vtable์€ ๊ตฌํ˜„๋œ ๋ฉ”์„œ๋“œ ๋ถ€๋ถ„์ง‘ํ•ฉ๋งŒ(์ปดํŒฉํŠธ): Device[0-2]=\n IUnknown ์Šคํ…/Releaseยท[3]=CreateRenderTargetView(์‹ค d3d11.dll ์ธ๋ฑ์Šค:9);\n Context[3]=OMSetRenderTargets(33)ยท[4]=ClearRenderTargetView(50)ยท[5]=Draw(13);\n SwapChain[3]=GetBuffer(9)ยท[4]=Present(8). `gamebox_D3D11CreateDeviceAndSwapChain`\n (12-ํŒŒ๋ผ๋ฏธํ„ฐ ์‹ค ์‹œ๊ทธ๋‹ˆ์ฒ˜๋ฅผ width+height๋กœ ๋‹จ์ˆœํ™”ยท๋งคํ•‘ ๋ฌธ์„œํ™”) + ํ”ฝ์…€ readback ํ—ฌํผ\n `gamebox_d3d11_readback`. Win32 ํƒ€์ž…(HRESULTยทUINTยทFLOAT ๋“ฑ) gamebox-local ์ •์˜\n (windows.h ์˜์กด ์—†์Œ). r12 wiring ๋…ธํŠธ: vtable ์ธ๋ฑ์Šค๊ฐ€ ์‹ค d3d11.dll๊ณผ ๋‹ค๋ฆ„(์ปดํŒฉํŠธ);\n ์ž์ž‘ r12 ํ…Œ์ŠคํŠธ PE๋Š” ์ด ์ธ๋ฑ์Šค๋ฅผ ์จ์•ผ ํ•จ.\n (2) **`native/d3d11_metal_bridge.m`** (Objective-C + Metal + Foundation, ARC):\n `GBMetalContext`(ObjC ํด๋ž˜์Šค) โ€” MTLDeviceยทqueueยทlibraryยทPSOยทbackBuffer(64ร—64\n MTLPixelFormatBGRA8UnormยทRenderTarget|ShaderReadยทStorageModeShared)ยทtriColorBuf\n (red=1,0,0,1) ๋ณด์œ . ๊ฐ COM ์˜ค๋ธŒ์ ํŠธ `_impl` = `CFBridgingRetain(ctx)`(๊ณต์œ  ์ปจํ…์ŠคํŠธ\n ์— ๋Œ€ํ•œ ๋ช…์‹œ์  strong ref; Release() ์‹œ CFBridgingRelease + free). MSL ์ธ๋ผ์ธ ์†Œ์Šค\n (r10 smoke์™€ ๋™์ผ ์…ฐ์ด๋”). ClearRenderTargetView โ†’ loadAction=Clear ๋…๋ฆฝ ๋ Œ๋” ํŒจ์Šค\n (CallerRGBA ์ƒ‰์ƒ, 0 ๋“œ๋กœ์šฐ); Draw โ†’ loadAction=Load ๋ Œ๋” ํŒจ์Šค(ํด๋ฆฌ์–ด ๋ณด์กด + ์‚ผ๊ฐํ˜• ๋“œ๋กœ์šฐ);\n Present โ†’ no-op(ํ—ค๋“œ๋ฆฌ์Šค); gamebox_d3d11_readback โ†’ [MTLTexture getBytes:].\n (3) **`native/d3d11_metal_bridge_test.c`** (์ˆœ์ˆ˜ C) โ€” D3D11 ์•ฑ์ด ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•œ\n vtable ํฌ์ธํ„ฐ ๊ฒฝ๋กœ: CreateDeviceAndSwapChain โ†’ scโ†’GetBuffer โ†’ devโ†’CreateRenderTargetView\n โ†’ ctxโ†’OMSetRenderTargets โ†’ ctxโ†’ClearRenderTargetView(blue) โ†’ ctxโ†’Draw(3,0) โ†’\n scโ†’Present โ†’ readback โ†’ ํ”ฝ์…€ ์–ด์„œ์…˜. MTLDevice nil โ†’ `__D3D11_BRIDGE__ SKIP\n reason=no_device` + exit 0(์ •์งยทwarn-only). ํ†ต๊ณผ ์‹œ `__D3D11_BRIDGE__ PASS\n px_clear=0x0000FFFF px_triangle=0xFF0000FF nonuniform=1` + exit 0. ์–ด์„œ์…˜ ์‹คํŒจ ์‹œ\n `__D3D11_BRIDGE__ FAIL reason=...` + exit 1. **๋กœ์ปฌ M4 ๊ฒฐ๊ณผ(๋นŒ๋“œ cleanยท-Wall -Wextra\n ๊ฒฝ๊ณ  ์—†์Œ)**: `__D3D11_BRIDGE__ PASS px_clear=0x0000FFFF px_triangle=0xFF0000FF\n nonuniform=1`. (4) **`native/build.sh`** โ€” `d3d11_bridge_test` ํƒ€๊นƒ ์ถ”๊ฐ€(ObjC ARCยท\n Metal/Foundation; `-std=c11`ยท`-Wpedantic` ์ œ์™ธ). ad-hoc codesign. (5)\n **`.github/workflows/ci.yml`** โ€” `Smoke โ€” D3D11โ†’Metal bridge (E5 r11)` ์Šคํ… ์ถ”๊ฐ€:\n r10 Metal ์„œ๋ธŒ์ŠคํŠธ๋ ˆ์ดํŠธ ์Šคํ… ์งํ›„ยทCLI smoke ์ง์ „. compile+run โ†’ `__D3D11_BRIDGE__`\n ํŒŒ์‹ฑ โ†’ PASS/SKIP/FAIL ๊ฐ ๋กœ๊ทธ. **warn-only**(์ปดํŒŒ์ผ ์‹คํŒจยทGPU ์—†์Œยท์–ด์„œ์…˜ ์‹คํŒจ ๋ชจ๋‘\n `::warning::`, ๋นŒ๋“œ red ์—†์Œ). r10๊ณผ ๋™์ผ ํŒจํ„ด.\n **r12 ์ •์˜**: ์ตœ์†Œ D3D11 ํ…Œ์ŠคํŠธ PE(own1 ์ž์ž‘ i386 PEยทown2 ํด๋ฆฐยท๊ฒŒ์ž„ ์• ์…‹ 0) + ์ธํ„ฐํ”„๋ฆฌํ„ฐ\n IAT autobind ๋ฐฐ์„  โ†’ D3D11 import(CreateDeviceAndSwapChainยทPresent ๋“ฑ)๋ฅผ ์ด ๋ธŒ๋ฆฌ์ง€ shim์—\n ๋ฐ”์ธ๋”ฉ โ†’ PE๊ฐ€ vtable ํ˜ธ์ถœ โ†’ Metal ์˜คํ”„์Šคํฌ๋ฆฐ ๋ Œ๋” โ†’ readback ํ”ฝ์…€ ์–ด์„œ์…˜ =\n **validated_manjeom>0 ๋‹ฌ์„ฑ ๊ฒŒ์ดํŠธ**. r12 ์ด๋ฆ„: `feat(F-NSWINDOW-E5 r12): ์ตœ์†Œ D3D11 ํ…Œ์ŠคํŠธ PE + ์ธํ„ฐํ”„๋ฆฌํ„ฐ end-to-end ๋ฐฐ์„  (validated_manjeom>0 ๊ฒŒ์ดํŠธ)`.\n\n- feat(F-NSWINDOW-E5 r10): **ํ—ค๋“œ๋ฆฌ์Šค Metal ์˜คํ”„์Šคํฌ๋ฆฐ ๋ Œ๋” + ํ”ฝ์…€ readback ์Šค๋ชจํฌ (E5 ์„œ๋ธŒ์ŠคํŠธ๋ ˆ์ดํŠธ ์ฆ๋ช…)**\n โ€” r9 ๊ฐ€ ๋ช…์‹œํ•œ ๋‹ค์Œ ๊ณผ์ œ(`r10 ํ‘œ์  = DXโ†’Metal ๋ธŒ๋ฆฌ์ง€(ํ—ค๋“œ๋ฆฌ์Šค Metal ์˜คํ”„์Šคํฌ๋ฆฐ readback smoke ๋จผ์ € CI ๊ฒ€์ฆ)`)๋ฅผ\n ์™„๋ฃŒํ•œ๋‹ค. **์„œ๋ธŒ์ŠคํŠธ๋ ˆ์ดํŠธ ์ฆ๋ช… โ€” ๊ฒŒ์ž„ ํ”„๋ ˆ์ž„ ์•„๋‹˜; `validated_manjeom` ์—ฌ์ „ํžˆ 0.** (1) **`native/metal_offscreen_smoke.m`**\n (Objective-C + Metal + Foundation): `MTLCreateSystemDefaultDevice()` ํ˜ธ์ถœ โ†’ GPU ์—†์œผ๋ฉด\n `__METAL_SMOKE__ SKIP reason=no_device` + `exit(0)`(์ •์ง ground-truth, ์‹คํŒจ ์•„๋‹˜).\n GPU ์žˆ์œผ๋ฉด: 64ร—64 `MTLPixelFormatBGRA8Unorm` ์˜คํ”„์Šคํฌ๋ฆฐ ํ…์Šค์ฒ˜(`RenderTarget|ShaderReadยทStorageModeShared`)\n ์ƒ์„ฑ, `newLibraryWithSource:`๋กœ ์ธ๋ผ์ธ MSL(vertex + fragment) ์ปดํŒŒ์ผ, ๋ Œ๋” ํŒจ์Šค = blue ํด๋ฆฌ์–ด(RGBA 0,0,1,1)\n + red ์‚ผ๊ฐํ˜•(RGBA 1,0,0,1) 1๊ฐœ ๋“œ๋กœ์šฐ, `waitUntilCompleted`, `-[MTLTexture getBytes:bytesPerRow:fromRegion:mipmapLevel:]`\n ๋กœ ํ”ฝ์…€ readback. ํ”ฝ์…€ ์–ด์„œ์…˜: ํด๋ฆฌ์–ด ์˜์—ญ = `0x0000FFFF`(blue), ์‚ผ๊ฐํ˜• ์˜์—ญ = `0xFF0000FF`(red),\n ๋‘ ํ”ฝ์…€์ด ๋‹ค๋ฆ„(`nonuniform=1`) โ€” ์‹ค ๋ Œ๋”๊ฐ€ ์ผ์–ด๋‚ฌ์Œ. ํ†ต๊ณผ ์‹œ `__METAL_SMOKE__ PASS device=\n px_clear= px_triangle= nonuniform=1`, ์‹คํŒจ ์‹œ `__METAL_SMOKE__ FAIL reason=...`.\n ์„œ๋“œํŒŒํ‹ฐ ์—†์Œ(Metal + Foundation๋งŒ). (2) **`native/build.sh`** โ€” `metal_offscreen_smoke` ๋นŒ๋“œ ํƒ€๊นƒ\n ์ถ”๊ฐ€(ObjC ARC + Metal/Foundation ํ”„๋ ˆ์ž„์›Œํฌ; `-std=c11`ยท`-Wpedantic` ์ œ์™ธ). ad-hoc codesign.\n (3) **`.github/workflows/ci.yml`** โ€” `Smoke โ€” headless Metal offscreen render (E5 substrate)` ์Šคํ…\n ์ถ”๊ฐ€: E3 native ์ธํ„ฐํ”„๋ฆฌํ„ฐ ์Šคํ… ์งํ›„, CLI smoke ์ง์ „. compile + run โ†’ `__METAL_SMOKE__` ํŒŒ์‹ฑ โ†’\n PASS/SKIP/FAIL ๊ฐ๊ฐ ๋ช…ํ™•ํžˆ ๋กœ๊ทธ. **warn-only**(์ปดํŒŒ์ผ ์‹คํŒจยทGPU ์—†์Œยท๋Ÿฐํƒ€์ž„ ์˜ค๋ฅ˜ ๋ชจ๋‘ `::warning::`;\n ๋นŒ๋“œ๋ฅผ red ๋‚ด์ง€ ์•Š์Œ) โ€” ๋Ÿฌ๋„ˆ์˜ GPU ์œ ๋ฌด๋ฅผ ํ•™์Šตํ•˜๋Š” ๊ฒƒ์ด ๋ชฉํ‘œ. ๋กœ์ปฌ ์‹คํ–‰ ๊ฒฐ๊ณผ(M4 Mac):\n `__METAL_SMOKE__ PASS device=Apple M4 px_clear=0x0000FFFF px_triangle=0xFF0000FF nonuniform=1`.\n Blacksmith CI ๋Ÿฌ๋„ˆ(`blacksmith-6vcpu-macos-15`, ์‹ค Apple-SiliconยทGPU ํƒ‘์žฌ) ๊ฒฐ๊ณผ๋Š” CI ๋กœ๊ทธ์—์„œ ํ™•์ธ ์˜ˆ์ •.\n **own1**: ์ˆœ์ˆ˜ Apple Metal(ํ”„๋กœ์ ํŠธ ์ž์ฒด ๋ Œ๋” ํƒ€๊นƒ), Wine 0ยทDRM bypass 0ยท๊ฒŒ์ž„ ์• ์…‹ 0.\n gamebox ์ž์ž‘ ์‚ผ๊ฐํ˜• = ์„œ๋ธŒ์ŠคํŠธ๋ ˆ์ดํŠธ ์ฆ๋ช…, ์ธํ„ฐํ”„๋ฆฌํ„ฐ๋ฅผ ํ†ตํ•œ ๊ฒŒ์ž„ ํ”„๋ ˆ์ž„ ์•„๋‹˜.\n **r11 ๋ชฉํ‘œ**: D3D11 device/swapchain ์…ฐ์ž„(`lib/loader/dx_d3d11.hexa` ์‹ค Metal ๋ฐฐ์„ ) โ€” CreateDevice/\n CreateSwapChain ํ˜ธ์ถœ์„ ์ด ์ฆ๋ช…๋œ Metal ์˜คํ”„์Šคํฌ๋ฆฐ ๊ฒฝ๋กœ๋กœ ๋ผ์šฐํŒ… + ์ตœ์†Œ D3D11 ํ…Œ์ŠคํŠธ PE(own1 ํด๋ฆฐ ์ž์ž‘)\n ์ธํ„ฐํ”„๋ฆฌํ„ฐ ์‹คํ–‰ ๊ฒŒ์ดํŠธ.\n\n- feat(F-NSWINDOW-E5 r9): **IAT ์ด๋ฆ„ ๊ธฐ๋ฐ˜ ์ž๋™ ๋ฐ”์ธ๋”ฉ + CMPXCHG ๋””์ฝ”๋”ยท์‹คํ–‰**\n โ€” r8 ์ด `INFO real_pe_path=structurally_ready needs:IAT_autobind_by_import_name`\n ์œผ๋กœ ๋ช…์‹œํ•œ ๋‹ค์Œ ๊ณผ์ œ๋ฅผ ์™„๋ฃŒํ•œ๋‹ค. (1) **`i386_iat_autobind()`**\n (`native/i386_cpu.c`): `IMAGE_IMPORT_DESCRIPTOR` โ†’ INT(OriginalFirstThunk) โ†’\n `IMAGE_IMPORT_BY_NAME`(+2 hint skip) ๋ฅผ ์ง์ ‘ ํŒŒ์‹ฑํ•ด ์ด๋ฆ„ ๋ฌธ์ž์—ด๋กœ ์…ฐ์ž„ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์™€\n `strcmp` ๋งค์นญ โ€” **์Šฌ๋กฏ VA ์‚ฌ์ „์ง€์‹ ์—†์ด** ์–ด๋–ค i386 PE ์˜ IAT ๋„ ๋ฐ”์ธ๋”ฉ ๊ฐ€๋Šฅ. ๋ฏธ๋“ฑ๋ก\n ์ด๋ฆ„์€ `fn=NULL`(์ •์ง; ๋Ÿฐ๋ฃจํ”„๋Š” `HALT_UNBOUND_IMPORT` + `last_import` ์— ์ด๋ฆ„ ๊ธฐ๋ก).\n ์„ ์–ธ์€ `native/i386_cpu.h`(`i386_shim_entry_t` typedef + ํ•จ์ˆ˜ ์„ ์–ธ, forward-decl\n `const struct i386_image *`). (2) **Import Directory RVA ํŒŒ์‹ฑ** (`native/pe_parse.c`):\n `pe_image_t` ์— `import_dir_rva`/`import_dir_size` ์ถ”๊ฐ€, DataDirectory[1] ์„ PE32\n (optional-header ์˜คํ”„์…‹ 104) ์™€ PE32+(์˜คํ”„์…‹ 120) ์–‘์ชฝ์—์„œ ์ฝ์Œ. (3) **CMPXCHG\n ๋””์ฝ”๋”**: `0F B0`(`cmpxchg r/m8,r8`) + `0F B1`(`cmpxchg r/m32,r32`) ๋ฅผ C ๋””์ฝ”๋”\n (`native/i386_decode.c`, enum ordinal 65ยท66) ์™€ byte-equal hexa ๋ฏธ๋Ÿฌ\n (`native/i386_decode.hexa`) ์–‘์ชฝ์— ์ถ”๊ฐ€(RUNEQ ๊ทœ์œจ). ์ธํ„ฐํ”„๋ฆฌํ„ฐ ์‹คํ–‰๋ถ€: EAX/AL ๊ณผ\n r/m ๋น„๊ต โ†’ ๊ฐ™์œผ๋ฉด ZF=1ยทr/mโ†reg, ๋‹ค๋ฅด๋ฉด ZF=0ยทEAX/ALโ†r/m(Intel SDM Vol.2). `rm_set8`\n / `mem_write8` ๋ณด์กฐ ํ•จ์ˆ˜ ์ถ”๊ฐ€. fn=NULL(autobind ๋ฏธ๋“ฑ๋ก ์Šฌ๋กฏ)์— ๋Œ€ํ•œ IAT ๋””์ŠคํŒจ์น˜\n halt ์ฒ˜๋ฆฌ๋„ ์—…๋ฐ์ดํŠธ(`last_import` ์ด๋ฆ„ ๋ณด์กด). (4) **Run E ํ…Œ์ŠคํŠธ**\n (`native/i386_cpu_test.c`): ํ•ฉ์„ฑ in-memory PE import ๋””๋ ‰ํ„ฐ๋ฆฌ(base `0x540000`,\n `0x1000B`): `IMAGE_IMPORT_DESCRIPTOR` 1๊ฐœ + INT 3๊ฐœ + `IMAGE_IMPORT_BY_NAME` 3๊ฐœ\n (GetCurrentThreadIdยทGetTickCountยทGetCommandLineW) ๋ฅผ ๋ ˆ์ด์•„์›ƒํ•˜๊ณ  `i386_iat_autobind`\n ํ˜ธ์ถœ โ†’ total=3ยทbound=3ยทunbound=0ยท์Šฌ๋กฏ VAยทfnยทname 18-ํ•ญ๋ชฉ ์ „์ˆ˜ ๊ฒ€์ฆ. GetCurrentThreadId\n ์Šฌ๋กฏ์„ ํ†ตํ•œ ๋ฏธ๋‹ˆ๋Ÿฐ(`FF 15 [0x540100]` โ†’ `C3`) โ†’ `halt=ret, EAX=0x1A2B, imports_bound=1`.\n CMPXCHG equal ํŒจ์Šค(EAX=ECX=`0x12345678` โ†’ ZF=1ยทECX ๋ถˆ๋ณ€)์™€ not-equal ํŒจ์Šค\n (EAX=`0xAAAAAAAA`ยทECX=`0xBBBBBBBB` โ†’ ZF=0ยทEAX=`0xBBBBBBBB`) ๊ฐ 4๊ฐœ CHECK. B/D\n sentinel ์€ `0F B1`(์ด์ œ CMPXCHG ๋กœ ์‹คํ–‰๋จ) โ†’ `0F C1 C0`(XADD, r10 ์ง„์งœ ๊ฐญ) ์œผ๋กœ\n ๊ต์ฒด. ์ธก์ • ๋ผ์ธ `__SHIM__ PARTIAL phase=e4_iat_name_autobind names_resolved=3\n unbound=0 dispatch_ok=1`, `__SHIM_TEST__ PASS`(CI ๊ฒŒ์ดํŠธ ยท Run A 25/B 4/C 5/D 3/E 18\n checks ์ „๋ถ€ green). **own1**: ํ‘œ์ค€ PE import ํ•ด์„ = ์ž์‹ ์˜ import ๋ฅผ ๋„ค์ดํ‹ฐ๋ธŒ ๊ตฌํ˜„์—\n ๋ฌถ๋Š” **๋กœ๋”ฉ**(bypass ์•„๋‹˜); ํ•ฉ์„ฑ PE ๊ตฌ์กฐยทIntel SDM CMPXCHG โ€” Wine/๋ณดํ˜ธ ์—†์Œ.\n `validated_manjeom` ์—ฌ์ „ํžˆ **0**. r10 ๋ชฉํ‘œ: DXโ†’Metal ๋ธŒ๋ฆฌ์ง€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ\n (`lib/loader/dx_d3d11.hexa` ์Šค์บํด๋“œ, 0 ์‹ค Metal ํ˜ธ์ถœ).\n\n- feat(F-NSWINDOW-E5 r8): **CRTโ†’user-entry ํ•ธ๋“œ์˜คํ”„ ๋„๋‹ฌ(ํ•ฉ์„ฑ) + BT/BTS/BTR/BTC\n ๋””์ฝ”๋” ๊ฐญ ์ข…๊ฒฐ + ๋งˆ์ง€๋ง‰ CRT import 2๊ฐœ ๋ฐ”์ธ๋”ฉ** โ€” r7 ์˜ ๋ฒฝ(๋ฏธ๋“ฑ๋ก IAT ํ˜ธ์ถœ\n @`0x539318`, insns=44)์„ **๋„˜์–ด CRT-init ์˜ ์ข…์ฐฉ์ ์ธ `call WinMain`(CRTโ†’user-entry\n ํ•ธ๋“œ์˜คํ”„)์— ๋„๋‹ฌ**ํ•œ๋‹ค. **์ด๊ฒƒ์ด ์ •์งํ•œ E4 ์™„๋ฃŒ ๋งˆ์ผ์Šคํ†ค์ด๋ฉฐ, ๋ Œ๋”๋œ ๊ฒŒ์ž„ ํ”„๋ ˆ์ž„์ด\n ์•„๋‹ˆ๋‹ค โ€” `validated_manjeom` ์€ ์—ฌ์ „ํžˆ 0.** (1) `native/i386_cpu.{c,h}` ์— ๋‘ ๊ฐœ์˜\n kernel32 ์…ฐ์ž„: `GetCommandLineW()`(0-arg โ†’ **ํ•ฉ์„ฑ in-image ์ปค๋งจ๋“œ๋ผ์ธ ํฌ์ธํ„ฐ**\n `base+0x1FE0`), `SetUnhandledExceptionFilter(fn)`(1-arg โ†’ ์ด์ „ ํ•„ํ„ฐ NULL=0). IAT\n ์Šฌ๋กฏ `0x53802C`/`0x538030` ์œผ๋กœ 13๊ฐœ(count=13). (2) `native/i386_decode.{c,h}` +\n byte-equal `.hexa` ๋ฏธ๋Ÿฌ: enum `I386_OP_BT_RM_R`(61,`0F A3`)/`_BTS`(62,`0F AB`)/\n `_BTR`(63,`0F B3`)/`_BTC`(64,`0F BB`) + 0F 2-byte ๋ถ„๊ธฐ(0F AF IMUL ๊ณผ ๋™์ผํ•œ `/r`\n ModR/M ํ˜•ํƒœ), op_name=\"bt\"/\"bts\"/\"btr\"/\"btc\". ์ธํ„ฐํ”„๋ฆฌํ„ฐ: **CF โ† bit(r/m, idx)**\n (idx=ModR/M.reg ๋ ˆ์ง€์Šคํ„ฐ, mod 32 ๋งˆ์Šคํฌ), BTS/BTR/BTC ๋Š” ์ˆ˜์ • ๋น„ํŠธ write-back โ€”\n ํ‰๋ฒ”ํ•œ Intel SDM Vol.2 ๋น„ํŠธ ์—ฐ์‚ฐ(๋ณดํ˜ธ ์•„๋‹˜). RUNEQ corpus D(0F ์ „์ˆ˜)์—์„œ Cโ†”hexa\n byte-equal ํ™•์ธ. (3) **ํ•ธ๋“œ์˜คํ”„ ๊ฒ€์ถœ**: `i386_cpu_t.user_entry_va` ํ•„๋“œ + halt\n `I386_HALT_USER_ENTRY` ์ถ”๊ฐ€ โ€” `call` ์˜ ํƒ€๊นƒ์ด `user_entry_va` ์™€ ๊ฐ™์œผ๋ฉด ๋ฆฌํ„ด ์ฃผ์†Œ๋ฅผ\n push ํ•œ ๋’ค(faithful \"about to enter\") ์ •์งํ•˜๊ฒŒ ์ •์ง€. (4) hermetic ํ…Œ์ŠคํŠธ\n (`native/i386_cpu_test.c`) Run A ๋Š” r7 ์ฒด์ธ(44) ๋’ค์— `GetCommandLineW` โ†’ `pop ecx`\n (์ž”์—ฌ push ์ •๋ฆฌ) โ†’ `mov esi,eax` โ†’ `SetUnhandledExceptionFilter` โ†’ `bt/bts/btr/btc`\n โ†’ WinMain 4-์ธ์ž stdcall ํ”„๋ ˆ์ž„ push(nShowCmd/lpCmdLine/hPrevInstance/hInstance) โ†’\n `call 0x539400`(ํ•ฉ์„ฑ user entry) ๋ฅผ ์ด์–ด ๋ถ™์—ฌ **insns 44โ†’60, halt\n `0x539318`(unbound)โ†’`0x539400`(user_entry)**, bound=13, last=SetUnhandledException-\n Filter ๋ฅผ ์ฆ๋ช…. WinMain ์ธ์ž ํ”„๋ ˆ์ž„([esp+4..0x10] = hInstanceยทhPrevInstanceยท\n lpCmdLineยทnShowCmd) + entry CALL ๋ฆฌํ„ด์ฃผ์†Œ(`0x5388AB`) ๋ฌด๊ฒฐ์„ฑ๊นŒ์ง€ ๊ฒ€์ฆ. B/D\n sentinel ์€ `0F A3`(์ด์ œ BT ๋กœ ์‹คํ–‰๋จ) โ†’ `0F B1`(CMPXCHG, ๋‹ค์Œ ์ง„์งœ ๊ฐญ, r9) ์œผ๋กœ\n ๊ต์ฒด. ์ธก์ • ๋ผ์ธ `__SHIM__ PARTIAL phase=e4_reached_user_entry insns=60 bound=13\n last=SetUnhandledExceptionFilter entry_va=0x539400 halt=user_entry halt_op=call\n (SYNTHETIC user-entry; validated_manjeom=0)` + `__SHIM__ INFO\n real_pe_path=structurally_ready needs:real_i386_PE+IAT_autobind_by_import_name+\n wider_opcode_coverage+D3DMetal+display`, `__SHIM_TEST__ PASS`(CI ๊ฒŒ์ดํŠธ, Run A 25\n checks ์ „๋ถ€ green, ๋กœ์ปฌ clang `-Wall -Wextra -Wpedantic -std=c11` ์ฒญ์ •). (5)\n **์‹ค-๋ฐ”์ด๋„ˆ๋ฆฌ ๊ฒฝ๋กœ ์ ๊ฒ€**: `i386_cpu_load_pe`(argv[1]) ๋Š” ์„น์…˜ ๋งคํ•‘ยท์—”ํŠธ๋ฆฌ ์„ค์ •ยท\n ์ด๋ฏธ์ง€ ํ• ๋‹น๊นŒ์ง€ **๊ตฌ์กฐ์ ์œผ๋กœ ๋ฐฐ์„ ๋จ** โ€” ์‹ค์ œ i386 PE ๋ฅผ ์ฃผ๋ฉด ์—”ํŠธ๋ฆฌ๋ถ€ํ„ฐ ์‹คํ–‰ ๊ฐ€๋Šฅ.\n ๋‹จ, K32_IAT ์Šฌ๋กฏ์ด hermetic ํ•ฉ์„ฑ VA(`0x538000..`)๋ผ ์‹ค์ œ PE ์˜ IAT ์™€๋Š” ๋งค์นญ๋˜์ง€\n ์•Š์œผ๋ฏ€๋กœ, ์‹คํ–‰์ด ์ฒซ import ๋ฅผ ๋„˜์œผ๋ ค๋ฉด **PE import ํ…Œ์ด๋ธ” ํŒŒ์‹ฑ + ์ด๋ฆ„ ๊ธฐ๋ฐ˜ ์ž๋™\n ๋ฐ”์ธ๋”ฉ**์ด ํ•„์š”(real-PE emit ๊ฐ€ INFO ๋กœ ๋ช…์‹œ). **own1**: ์ž๊ธฐ import ๋ฅผ ๋„ค์ดํ‹ฐ๋ธŒ\n ๊ตฌํ˜„์— ๋ฌถ๋Š” **๋กœ๋”ฉ**(์šฐํšŒ ์•„๋‹˜), ํ•ฉ์„ฑ TEB/์ปค๋งจ๋“œ๋ผ์ธ/user-entry VA ๋Š” **์ •์ง ๋ผ๋ฒจ**,\n BT ๋ฅ˜๋Š” ํ‰๋ฒ”ํ•œ CPU ๋น„ํŠธ ์—ฐ์‚ฐ โ€” Wine/๋ณดํ˜ธ ์—†์Œ. **`validated_manjeom>0`(์‹ค ํ”„๋ ˆ์ž„)\n ๊นŒ์ง€ ๋‚จ์€ ๊ฑฐ๋ฆฌ**: real-asset ๊ฒŒ์ดํŠธ(์‹ค i386 ๊ฒŒ์ž„ PE + D3DMetal SDK + ์‹ค ๋””์Šคํ”Œ๋ ˆ์ด โ€”\n ์‚ฌ์šฉ์ž๋งŒ ์ œ๊ณต ๊ฐ€๋Šฅ) + ๋‚จ์€ ์—”์ง€๋‹ˆ์–ด๋ง(์‹ค PE IAT ์ด๋ฆ„ ์ž๋™๋ฐ”์ธ๋”ฉ, ๋” ๋„“์€ opcode\n ์ปค๋ฒ„๋ฆฌ์ง€, ๊ฒŒ์ž„ ์ž์‹ ์˜ WinMain โ†’ ๋ฉ”์‹œ์ง€ ๋ฃจํ”„ โ†’ CreateWindowEx โ†’ D3Dโ†’Metal ํ”„๋ ˆ์ž„).\n ํ˜„์žฌ๋Š” **ํ•ฉ์„ฑ user-entry ๋„๋‹ฌ**๊นŒ์ง€์ด๋ฉฐ ์‹ค ํ”„๋ ˆ์ž„์€ ์ž์œจ ๋ฒ”์œ„ ๋ฐ–(real-asset-gated).\n\n- feat(F-NSWINDOW-E5 r7): **CRT import 3๊ฐœ ์ถ”๊ฐ€ ๋ฐ”์ธ๋”ฉ + IMUL/CPUID/RDTSC ๋””์ฝ”๋”\n ๊ฐญ ์ข…๊ฒฐ + `__security_init_cookie` ์‚ฐ์ˆ  ์‹คํ–‰** โ€” r6 ์˜ ๋ฒฝ(๋ฏธ๋“ฑ๋ก IAT ํ˜ธ์ถœ\n @`0x5392D4`, insns=30)์„ **๋„˜๋Š”๋‹ค**. (1) `native/i386_cpu.{c,h}` ์— ์„ธ ๊ฐœ์˜\n kernel32 ์…ฐ์ž„ ์ถ”๊ฐ€: `GetStartupInfoW(LPSTARTUPINFOW)`(1-arg ptr, push ๋œ ํฌ์ธํ„ฐ\n `[esp]` ์˜ STARTUPINFOW 0x44B ๋ฅผ 0 ์œผ๋กœ + `cb=0x44` ์Šคํƒฌํ”„ โ€” ๋ฒ„ํผ-์“ฐ๊ธฐ),\n `GetSystemInfo(LPSYSTEM_INFO)`(1-arg ptr, **bounded-synthetic** SYSTEM_INFO\n 0x24B โ€” dwPageSize=0x1000ยทnCPU=4ยทarch=INTEL, ๋‚˜๋จธ์ง€ 0), `GetProcAddress(HMODULE,\n LPCSTR)`(2-arg โ†’ **ํ•ฉ์„ฑ in-image ์Šคํ… ์ฃผ์†Œ** `base+0x1FF0`). IAT ๋“ฑ๋ก ์Šฌ๋กฏ\n `0x538000..0x538028` ๋กœ 11๊ฐœ(count=11). (2) `native/i386_decode.{c,h}` +\n byte-equal `.hexa` ๋ฏธ๋Ÿฌ: enum `I386_OP_IMUL_R_RM`(57, `0F AF`)/`_IMM`(58, `69 id`/\n `6B ib`)/`I386_OP_CPUID`(59, `0F A2`)/`I386_OP_RDTSC`(60, `0F 31`) + ๋””์ฝ”๋“œ\n ๋ถ„๊ธฐ ์ถ”๊ฐ€, op_name=\"imul\"/\"cpuid\"/\"rdtsc\". ์ธํ„ฐํ”„๋ฆฌํ„ฐ: **IMUL** ์€ 32-bit signed\n ๊ณฑ์˜ ํ•˜์œ„ 32-bit ๋ฅผ dst(ModR/M.reg)์—, int32 ์˜ค๋ฒ„ํ”Œ๋กœ๋ฉด CF=OF=1(SDM Vol.2);\n **CPUID** ๋Š” leaf(eax)๋ณ„ **ํ•ฉ์„ฑ** ํ”ผ์ฒ˜์…‹(leaf0 vendor \"GenuineIntel\"ยทmax-leaf,\n leaf1 family/feature) ์„ eax/ebx/ecx/edx ์—; **RDTSC** ๋Š” `cpu->tsc += step` ํ•ฉ์„ฑ\n ๋‹จ์กฐ ์นด์šดํ„ฐ๋ฅผ edx:eax ์— ๊ธฐ๋ก. CPUID/RDTSC ๋Š” ํ‰๋ฒ”ํ•œ CPU ๋ช…๋ น(๋ณดํ˜ธ ์•„๋‹˜). (3)\n **๋ณด์•ˆ์ฟ ํ‚ค ์‚ฐ์ˆ **: hermetic ํ”„๋กค๋กœ๊ทธ๊ฐ€ FILETIME ์—”ํŠธ๋กœํ”ผ ๋กœ๋“œ โ†’ `xor` โ†’\n `imul eax,eax,0x01000193`(์‹ ๊ทœ 0x69 IMUL) โ†’ ๊ธ€๋กœ๋ฒŒ ์Šฌ๋กฏ์— **๋น„๊ธฐ๋ณธ ์ฟ ํ‚ค** ์ €์žฅ โ†’\n `cpuid`(GenuineIntel) โ†’ `rdtsc`. (4) hermetic ํ…Œ์ŠคํŠธ(`native/i386_cpu_test.c`)\n Run A ๋Š” r6 ์ฒด์ธ ๋’ค์— `call GetStartupInfoW`(cb=0x44 ๊ฒ€์ฆ) / `call GetSystemInfo`\n (page=0x1000ยทnCPU=4 ๊ฒ€์ฆ) / `pushร—2; call GetProcAddress` / ์ฟ ํ‚ค `mov/xor/imul/mov`\n (์ฟ ํ‚ค == `(FT_lo^FT_hi)*0x01000193` ์žฌ์œ ๋„ ๊ฒ€์ฆ, โ‰ 0) / `cpuid`(ebx=\"Genu\"ยท\n ecx=\"ntel\" ๊ฒ€์ฆ) / `rdtsc`(edx:eax ํ•ฉ์„ฑ ๊ฒ€์ฆ) / ๋ฏธ๋“ฑ๋ก `call` ์„ ์ด์–ด ๋ถ™์—ฌ ๊ฒฝ๊ณ„\n ํ†ต๊ณผ๋ฅผ ์ฆ๋ช…: **insns 30โ†’44, halt `0x5392D4`โ†’`0x539318`**(reason=UNBOUND_IMPORT,\n slot `0x53802C`), bound=11, last=GetProcAddress. B/D sentinel ์€ `0F A2`(์ด์ œ ์‹คํ–‰๋จ)\n โ†’ `0F A3`(BT, ๋‹ค์Œ ์ง„์งœ ๋””์ฝ”๋” ๊ฐญ) ์œผ๋กœ ๊ต์ฒด. ์ธก์ • ๋ผ์ธ `__SHIM__ PARTIAL\n phase=e4_crt_security_cookie insns=44 bound=11 last=GetProcAddress\n halt_va=0x539318 halt=unbound_import halt_op=call unbound_slot=0x53802C`,\n `__SHIM_TEST__ PASS`(CI ๊ฒŒ์ดํŠธ, Run A 18 checks ์ „๋ถ€ green, ๋กœ์ปฌ clang\n `-Wall -Wextra -Wpedantic -std=c11` ์ฒญ์ •). **own1**: ๋กœ๋”๊ฐ€ ์ž๊ธฐ ํ”„๋กœ์„ธ์Šค์˜ **์ž๊ธฐ\n import**(kernel32 OS API)๋ฅผ ๋„ค์ดํ‹ฐ๋ธŒ ๊ตฌํ˜„์— ๋ฌถ๋Š” **๋กœ๋”ฉ** โ€” ์šฐํšŒ ์•„๋‹˜; CPUID/RDTSC\n ๋Š” ํ‰๋ฒ”ํ•œ CPU ๋ช…๋ น, ์ฟ ํ‚ค๋Š” **์ž๊ธฐ ๋ฒ„ํผ ์œ„์˜ ์ž๊ธฐ ์‚ฐ์ˆ **, ํ•ฉ์„ฑ SYSTEM_INFO/์Šคํ…์€\n ์ •์ง ๋ผ๋ฒจ. **`main`/`WinMain` ๋ฏธ๋„๋‹ฌ**: ์•„์ง CRT-init(import ๋ฐ”์ธ๋”ฉ) ๋‹จ๊ณ„์ด๋ฉฐ\n hermetic ํ”„๋กค๋กœ๊ทธ๋Š” ์‹ค์ œ ๋ฐ”์ด๋„ˆ๋ฆฌ๊ฐ€ ์•„๋‹Œ ๋ฌธ์„œํ™”๋œ SHAPE ๋ผ ์ง„์งœ `call main` ์€\n ์—†์Œ โ€” ๋‚จ์€ CRT ๋‹จ๊ณ„(์ถ”๊ฐ€ import + `__scrt_common_main_seh` โ†’ user entry). `validated_manjeom`\n ์€ ์—ฌ์ „ํžˆ **0**(๋กœ๋” ์ง„์ฒ™์ด์ง€ ๋ Œ๋”๋œ ํ”„๋ ˆ์ž„ ์•„๋‹˜). ๋‹ค์Œ r8: ๋ฏธ๋“ฑ๋ก slot `0x53802C`\n ๋ฐ”์ธ๋”ฉ + `0F A3` BT ๋””์ฝ”๋” ๊ฐญ + ์‹ค์ œ ๋ฐ”์ด๋„ˆ๋ฆฌ์—์„œ `mainCRTStartupโ†’main` ๊ฑฐ๋ฆฌ ์ธก์ •.\n\n- feat(F-NSWINDOW-E5 r6): **CRT-security import 3๊ฐœ ์ถ”๊ฐ€ ๋ฐ”์ธ๋”ฉ + 0F B6/B7/BE/BF\n MOVZX/MOVSX ๋””์ฝ”๋” ๊ฐญ ์ข…๊ฒฐ + ํ•ฉ์„ฑ TEBโ†’PEBโ†’ImageBase ์ฒด์ธ** โ€” r5 ์˜ ๋ฒฝ(๋ฏธ๋“ฑ๋ก IAT\n ํ˜ธ์ถœ @`0x5392A1`, insns=18)์„ **๋„˜๋Š”๋‹ค**. (1) `native/i386_cpu.{c,h}` ์— ์„ธ ๊ฐœ์˜\n kernel32 ์…ฐ์ž„ ์ถ”๊ฐ€: `IsProcessorFeaturePresent(DWORD)`(1-arg โ†’ BOOL 1, ๊ธฐ๋Šฅ\n present ๊ฒฐ์ •์  ์ฃผ์žฅ), `InitializeSListHead(PSLIST_HEADER)`(1-arg ptr, push ๋œ\n ํฌ์ธํ„ฐ `[esp]` ์˜ 8-byte SLIST ํ—ค๋”๋ฅผ 0 ์œผ๋กœ โ€” ๋ฒ„ํผ-์“ฐ๊ธฐ), `GetModuleHandleW(\n LPCWSTR)`(1-arg, HMODULE=๋กœ๋”๊ฐ€ ์•„๋Š” **์ž๊ธฐ ์ด๋ฏธ์ง€ ๋ฒ ์ด์Šค** ๋ฐ˜ํ™˜). IAT ๋“ฑ๋ก\n ์Šฌ๋กฏ `0x538000..0x53801C` ๋กœ 8๊ฐœ(count=8). (2) `native/i386_decode.{c,h}` +\n byte-equal `.hexa` ๋ฏธ๋Ÿฌ: 2-byte(0F) ๋งต์— enum `I386_OP_MOVZX_RM8`(53)/`_RM16`(54)/\n `I386_OP_MOVSX_RM8`(55)/`_RM16`(56) + ๋””์ฝ”๋“œ ๋ถ„๊ธฐ(B6/B7/BE/BF, ModR/M reg=dst\n r32, r/m8|r/m16 src) ์ถ”๊ฐ€, op_name=\"movzx\"/\"movsx\"; 0F ์˜ `avail<6` ๊ฐ€๋“œ๋ฅผ\n `avail<2`(+Jcc ๋งŒ `<6`)๋กœ ๋ถ„๋ฆฌํ•ด ์งง์€ movzx ๋„ ๋””์ฝ”๋“œ. ์ธํ„ฐํ”„๋ฆฌํ„ฐ๋Š” r/m8(๋ ˆ์ง€์Šคํ„ฐ\n ๋ฐ”์ดํŠธ๋งต al..bh / mem `mem_read8`)ยทr/m16 ์„ zero/sign-extend โ†’ r32, **EFLAGS ๋ถˆ๋ณ€**.\n (3) **BOUNDED-SYNTHETIC TEB**: `i386_cpu` ์— `teb_base` ํ•„๋“œ ์ถ”๊ฐ€ โ€” ๋ฉ”๋ชจ๋ฆฌ ์˜คํผ๋žœ๋“œ๊ฐ€\n FS ์„ธ๊ทธ๋จผํŠธ-override ํ”„๋ฆฌํ”ฝ์Šค(0x64, ์ด๋ฏธ ๋””์ฝ”๋“œ๋จ)๋ฅผ ๋‹ฌ๋ฉด `i386_ea` ๊ฐ€ ์œ ํšจ์ฃผ์†Œ๋ฅผ\n `teb_base+disp` ๋กœ ๋ฆฌ๋””๋ ‰ํŠธ. ํ•ฉ์„ฑ TEB(self@+0x18) โ†’ PEB(@TEB+0x30) โ†’ ImageBase\n (@PEB+8) ์˜ ๋ช‡ ๊ฐœ ํ•„๋“œ๋งŒ ์ด๋ฏธ์ง€ ๋ฉ”๋ชจ๋ฆฌ์— ๊น”์•„ ๋ณด์•ˆ์ฟ ํ‚ค/CRT-startup ํ”„๋กค๋กœ๊ทธ์˜\n `mov ecx, fs:[0x18]` ์ฒด์ธ์ด **๋ˆ๋‹ค**(OS TEB ์•„๋‹˜ยท๋ณดํ˜ธ๊ตฌ์กฐ ์•„๋‹˜, ์ •์ง ๋ผ๋ฒจ). hermetic\n ํ…Œ์ŠคํŠธ(`native/i386_cpu_test.c`) Run A ๋Š” r5 ํ•ฉ์„ฑ ํ”„๋กค๋กœ๊ทธ ๋’ค์— `push 0xA; call\n IsProcessorFeaturePresent` / `movzx ecx,al; movsx edx,cl`(์‹ ๊ทœ ๋‘-๋ฐ”์ดํŠธ ์‹ค์ฆ) /\n `push &slist; call InitializeSListHead`(8B ์ œ๋กœํ™” ๊ฒ€์ฆ, ์‚ฌ์ „ ๋”ํ‹ฐ `0xFFFFFFFF`) /\n `push 0; call GetModuleHandleW`(โ†’ ์ด๋ฏธ์ง€ ๋ฒ ์ด์Šค) / `mov ecx,fs:[0x18]; mov edx,\n [ecx+0x30]; mov eax,[edx+8]`(TEBโ†’PEBโ†’ImageBase) / ๋ฏธ๋“ฑ๋ก `call` ์„ ์ด์–ด ๋ถ™์—ฌ\n ๊ฒฝ๊ณ„ ํ†ต๊ณผ๋ฅผ ์ฆ๋ช…: **insns 18โ†’30, halt `0x5392A1`โ†’`0x5392D4`**(reason=\n UNBOUND_IMPORT, slot `0x538020`), bound=8, last=GetModuleHandleW,\n eax=ImageBase(`0x538000`)ยทecx=TEB(`0x539C00`)ยทedx=PEB(`0x539C80`) ์‹ค์ฆ,\n esp=esp0-8(์—”ํŠธ๋ฆฌ ๋ฐ˜ํ™˜์ฃผ์†Œ+๋ฏธpop push). B/D sentinel ์€ `0F B6`(์ด์ œ ์‹คํ–‰๋จ)โ†’\n `0F A2`(CPUID, ๋‹ค์Œ ์ง„์งœ ๋””์ฝ”๋” ๊ฐญ) ์œผ๋กœ ๊ต์ฒด. ์ธก์ • ๋ผ์ธ `__SHIM__ PARTIAL\n phase=e4_crt_security_teb insns=30 bound=8 last=GetModuleHandleW\n halt_va=0x5392D4 halt=unbound_import halt_op=call unbound_slot=0x538020`,\n `__SHIM_TEST__ PASS`(CI ๊ฒŒ์ดํŠธ, Run A 17 checks ์ „๋ถ€ green, ๋กœ์ปฌ clang\n `-Wall -Wextra -Wpedantic -std=c11` ์ฒญ์ •). **own1**: ๋กœ๋”๊ฐ€ ์ž๊ธฐ ํ”„๋กœ์„ธ์Šค์˜ **์ž๊ธฐ\n import**(kernel32 OS API)๋ฅผ ๋„ค์ดํ‹ฐ๋ธŒ ๊ตฌํ˜„์— ๋ฌถ๋Š” **๋กœ๋”ฉ** โ€” ์šฐํšŒ ์•„๋‹˜; TEB ๋Š” **์ž๊ธฐ\n ํ•ฉ์„ฑ ๋ธ”๋ก**(ํ•„๋“œ ๋ช‡ ๊ฐœ)์ด์ง€ OS TEB ๋„, ๋ณดํ˜ธ์žฅ์น˜๋„ ์•„๋‹˜. `validated_manjeom` ์€\n ์—ฌ์ „ํžˆ **0**(๋กœ๋” ์ง„์ฒ™์ด์ง€ ๋ Œ๋”๋œ ํ”„๋ ˆ์ž„ ์•„๋‹˜). ๋‹ค์Œ r7: ๋ฏธ๋“ฑ๋ก slot `0x538020`\n ๋ฐ”์ธ๋”ฉ(GetStartupInfoW/GetProcAddress ๋“ฑ) + `0F A2` CPUID ๋””์ฝ”๋” ๊ฐญ + ํ’€ ๋ณด์•ˆ์ฟ ํ‚ค\n ์—ฐ์‚ฐ(time/pid/tid XORยทmul) โ†’ `main`/`WinMain` ๋„๋‹ฌ, user32 `CreateWindowEx` ๊ฑฐ๋ฆฌ.\n- feat(F-NSWINDOW-E5 r5): **CRT-init import 5๊ฐœ ์—ฐ์† ๋ฐ”์ธ๋”ฉ + ์ฒซ ๋ฒ„ํผ-์“ฐ๊ธฐ ์…ฐ์ž„ +\n 0xC1 shift-group ๋””์ฝ”๋” ๊ฐญ ์ข…๊ฒฐ** โ€” r4 ์˜ ๋ฒฝ(๋ฏธ๋“ฑ๋ก IAT ํ˜ธ์ถœ @`0x53927C`,\n insns=11)์„ **๋„˜๋Š”๋‹ค**. `native/i386_cpu.{c,h}` ์— ๋„ค ๊ฐœ์˜ kernel32 ์…ฐ์ž„ ์ถ”๊ฐ€:\n `GetCurrentProcessId`(0-arg โ†’ ๊ฒฐ์ •์  PID `0xD04`), `GetTickCount`(0-arg โ†’ `0x1D4C0`),\n ๊ทธ๋ฆฌ๊ณ  **์ฒซ ๋ฒ„ํผ-์“ฐ๊ธฐํ˜• ์…ฐ์ž„** `GetSystemTimeAsFileTime(LPFILETIME)` โ€”\n ์Šคํƒ์—์„œ caller ๊ฐ€ push ํ•œ ํฌ์ธํ„ฐ ์ธ์ž(`[esp]`, ํ˜ธ์ถœ ๊ฐ€๋กœ์ฑ„๊ธฐ ์‹œ์ ์ด๋ผ ๋ฐ˜ํ™˜์ฃผ์†Œ๊ฐ€\n ์•„์ง ์•ˆ ์Œ“์ž„)๋ฅผ ์ฝ์–ด ์ด๋ฏธ์ง€ ๋ฉ”๋ชจ๋ฆฌ์— 8-byte FILETIME(`mem_write32`ร—2)์„ ๊ธฐ๋กํ•˜๊ณ \n void ๋ฐ˜ํ™˜(stdcall 1-arg, callee-pop 4) โ€” r4 ์˜ 0-arg ์…ฐ์ž„ ๋Œ€๋น„ **stubโ†’์ด๋ฏธ์ง€ ๋ฉ”๋ชจ๋ฆฌ\n ์“ฐ๊ธฐ + ์‹ค์ œ push ๋œ ํฌ์ธํ„ฐ ์ธ์ž**๋ผ๋Š” ์ƒˆ ๋Šฅ๋ ฅ์„ ํ–‰์‚ฌ. `QueryPerformanceCounter(\n LARGE_INTEGER*)` ๋„ ๋™์ผ ํŒจํ„ด(8-byte ์นด์šดํ„ฐ ๊ธฐ๋ก, BOOL=1 ๋ฐ˜ํ™˜). ์‹คํ–‰ ๋ฃจํ”„๋Š” ์ด์ œ\n bound ํ˜ธ์ถœ์„ ์—ฐ๋‹ฌ์•„ ๋””์ŠคํŒจ์น˜ํ•ด ํ”„๋กค๋กœ๊ทธ๊ฐ€ ๋‹ค์„ฏ import(GetCurrentThreadId โ†’\n GetCurrentProcessId โ†’ GetSystemTimeAsFileTime โ†’ QueryPerformanceCounter โ†’\n GetTickCount)๋ฅผ ํ†ต๊ณผํ•˜๊ณ , **์—ฌ์„ฏ ๋ฒˆ์งธยท๋ฏธ๋“ฑ๋ก IAT ํ˜ธ์ถœ @`0x5392A1`** ์—์„œ ์ •์งํ•˜๊ฒŒ\n HALT(`UNBOUND_IMPORT`, ๋‹ค์Œ ์Šฌ๋กฏ `0x538014` ๋ณด๊ณ ).\n- feat(F-NSWINDOW-E5 r5): **0xC1/0xD1/0xD3 group-2 shift/rotate ๋””์ฝ”๋”+์‹คํ–‰** โ€”\n r3 sentinel ์ด ์ง€๋ชฉํ•œ `0xC1` ๊ฐญ์„ ์ข…๊ฒฐ. `native/i386_decode.{c,h}` +\n byte-equal `.hexa` ๋ฏธ๋Ÿฌ์— enum `I386_OP_SHIFT_RM_IMM8`(50)/`_RM_1`(51)/`_RM_CL`(52)\n + ๋””์ฝ”๋“œ ๋ถ„๊ธฐ(count ์ถœ์ฒ˜: imm8 / 1 / CL) ์ถ”๊ฐ€, op_name=\"shift\". ์ธํ„ฐํ”„๋ฆฌํ„ฐ\n (`i386_cpu.c`)๋Š” ModR/M.reg ๋กœ SHL/SAL(4/6)ยทSHR(5)ยทSAR(7)ยทROL(0)ยทROR(1) ์„\n ๋ถ„๊ธฐํ•˜๊ณ  SDM ๋Œ€๋กœ count ๋ฅผ 5-bit ๋งˆ์Šคํ‚น + CF/OF/ZF/SF/PF ๊ฐฑ์‹ (count==0 โ†’ ๋ฌด๋ณ€ํ™”ยท\n ๋ฌดํ”Œ๋ž˜๊ทธ); RCL/RCR(2/3) carry-chain ์€ ๋ฏธ๋ชจ๋ธ โ†’ ์ •์งํ•œ UNSUPPORTED. RUNEQ ๋Š”\n C/hexa ์–‘์ชฝ์ด ๋™์ผํ•˜๊ฒŒ ๋ฐ”๋€Œ๋ฏ€๋กœ ๊ทธ๋ฆฐ ์œ ์ง€(corpus A ์˜ 0xC1/D1/D3 ํ–‰๋งŒ ๋™์‹œ ๋ณ€ํ™”).\n hermetic ํ…Œ์ŠคํŠธ(`native/i386_cpu_test.c`) Run A ๋Š” ํ•ฉ์„ฑ ํ”„๋กค๋กœ๊ทธ๋ฅผ 0x53927C ๊นŒ์ง€\n ์œ ์ง€ํ•˜๊ณ  ๋’ค์— `call GetCurrentProcessId` / `push &filetime; call\n GetSystemTimeAsFileTime` / `push &perfcount; call QueryPerformanceCounter` /\n `shl edx,4`(group-2 shift) / `call GetTickCount` / ๋ฏธ๋“ฑ๋ก `call` ์„ ์ด์–ด ๋ถ™์—ฌ\n ๊ฒฝ๊ณ„ ํ†ต๊ณผ๋ฅผ ์ฆ๋ช…: **insns 11โ†’18, halt `0x53927C`โ†’`0x5392A1`**(reason=\n UNBOUND_IMPORT, slot `0x538014`), bound=5, last=GetTickCount, eax=GetTickCount\n stub, edx=TID<<4=`0x1A2B0`(shift ์‹ค์ฆ), ecx=0xEF(ํ”„๋กค๋กœ๊ทธ ๋ณด์กด), esp=esp0-4,\n ๊ทธ๋ฆฌ๊ณ  **๋ฒ„ํผ ๋‘ ๊ณณ ๊ฒ€์ฆ**: `[0x539F00]`=FILETIME `01D7A1B2:C3D4E5F6`,\n `[0x539F10]`=counter `00000000:12345678`. B/D sentinel ์€ `0xC1`(์ด์ œ ์‹คํ–‰๋จ)โ†’\n `0F B6`(MOVZX, ๋‹ค์Œ ์ง„์งœ ๋””์ฝ”๋” ๊ฐญ) ์œผ๋กœ ๊ต์ฒด. ์ธก์ • ๋ผ์ธ `__SHIM__ PARTIAL\n phase=e4_kernel32_iat_bind insns=18 bound=5 last=GetTickCount halt_va=0x5392A1\n halt=unbound_import halt_op=call unbound_slot=0x538014`, `__SHIM_TEST__ PASS`\n (CI ๊ฒŒ์ดํŠธ, Run A 16 checks ์ „๋ถ€ green, ๋กœ์ปฌ clang `-Wall -Wextra -std=c11` ์ฒญ์ •).\n **own1**: ๋กœ๋”๊ฐ€ ์ž๊ธฐ ํ”„๋กœ์„ธ์Šค์˜ **์ž๊ธฐ import**(kernel32 OS API ํ‘œ๋ฉด)๋ฅผ ๋„ค์ดํ‹ฐ๋ธŒ\n ๊ตฌํ˜„์— ๋ฌถ๋Š” **๋กœ๋”ฉ** โ€” ์šฐํšŒ ์•„๋‹˜. FILETIME/perf-counter/tick/pid ๋Š” CRT init ์˜\n ๊ฒฐ์ •์  STUB ์ด์ง€ ๋ณดํ˜ธ์žฅ์น˜(DRM/Warden/anti-cheat)์™€ ๋ฌด๊ด€ํ•˜๊ณ , ๋ฒ„ํผ ์“ฐ๊ธฐ๋Š” ํ”„๋กœ๊ทธ๋žจ\n **์ž๊ธฐ ๋ฒ„ํผ**์— ํ•œ์ •. `validated_manjeom` ์€ ์—ฌ์ „ํžˆ **0**(๋กœ๋” ์ง„์ฒ™์ด์ง€ ๋ Œ๋”๋œ\n ํ”„๋ ˆ์ž„ ์•„๋‹˜). ๋‹ค์Œ r6: ๋ฏธ๋“ฑ๋ก slot `0x538014` ๋ฐ”์ธ๋”ฉ + `0F B6` MOVZX ๋””์ฝ”๋” ๊ฐญ +\n ๋” ๊นŠ์€ CRT init(๋ณด์•ˆ์ฟ ํ‚ค XOR/__security_init_cookie, TEB/PEB ์ ‘๊ทผ) โ†’ `main`/\n `WinMain` ๋„๋‹ฌ, ๊ทธ๋ฆฌ๊ณ  user32 `CreateWindowEx` ๊นŒ์ง€์˜ ๊ฑฐ๋ฆฌ ์ธก์ •.\n\n- feat(F-NSWINDOW-E5 r4): **์ฒซ E4 kernel32 IAT ๋ฐ”์ธ๋”ฉ** โ€” i386 ์ธํ„ฐํ”„๋ฆฌํ„ฐ๊ฐ€ r3 ์˜\n ๋ฒฝ(`FF 15 [disp32]` ๊ฐ„์ ‘ IAT ํ˜ธ์ถœ @`0x539274`, insns=9 ์—์„œ HALT)์„ **๋„˜๋Š”๋‹ค**.\n `native/i386_cpu.{c,h}` ์— import-stub ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ(`i386_iat_t`/`i386_import_t` +\n `i386_iat_lookup`) ์™€ ์ฒซ ๋„ค์ดํ‹ฐ๋ธŒ kernel32 ์…ฐ์ž„(`i386_shim_GetCurrentThreadId`,\n stdcall 0-arg โ†’ ๊ฒฐ์ •์  plausible TID `0x1A2B`)์„ ์ถ”๊ฐ€. ์‹คํ–‰ ๋ฃจํ”„์˜ `CALL_RM`/`JMP_RM`\n ์ผ€์ด์Šค๋Š” ์ด์ œ ์ •๊ทœ IAT thunk ํ˜•ํƒœ(ModR/M mod=00,rm=101 = `[disp32]`)๋ฅผ ์ธ์‹ํ•ด\n slot VA(=`insn.disp`)๋ฅผ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์—์„œ ์กฐํšŒํ•œ๋‹ค โ€” **๋ฐ”์ธ๋”ฉ๋˜์–ด ์žˆ์œผ๋ฉด** ๋„ค์ดํ‹ฐ๋ธŒ\n ์…ฐ์ž„์„ ๋””์ŠคํŒจ์น˜ํ•˜๊ณ  EAX ์— ๋ฐ˜ํ™˜๊ฐ’์„ ์‹ฃ๊ณ (Win32 ABI) stdcall ์ธ์ž๋ฅผ pop ํ•œ ๋’ค\n ์‹คํ–‰์„ **๊ณ„์†**ํ•œ๋‹ค. `__scrt_common_main` security-cookie init ์˜ ์ฒซ ํ˜ธ์ถœ\n GetCurrentThreadId ๊ฐ€ ๋ฐ”์ธ๋”ฉ๋˜์–ด 0x539274 ์˜ ํ˜ธ์ถœ์ด **์‹คํ–‰**๋˜๊ณ (insn 10), ๋‹ค์Œ\n `mov edx,eax`(insn 11)๊นŒ์ง€ ์ง„ํ–‰ํ•œ ๋’ค **๋‘ ๋ฒˆ์งธยท๋ฏธ๋“ฑ๋ก IAT ํ˜ธ์ถœ @`0x53927C`** ์—์„œ\n ์ •์งํ•˜๊ฒŒ HALT(`UNBOUND_IMPORT` โ€” ๋‹ค์Œ์— ๋ฐ”์ธ๋”ฉํ•  import ์Šฌ๋กฏ `0x538004` ๋ฅผ ๋ณด๊ณ ).\n hermetic ํ…Œ์ŠคํŠธ(`native/i386_cpu_test.c`) Run A ๋Š” ํ•ฉ์„ฑ ํ”„๋กค๋กœ๊ทธ๋ฅผ 0x539274 ๊นŒ์ง€\n r3 ์™€ byte-๋™์ผํ•˜๊ฒŒ ์œ ์ง€ํ•˜๊ณ  ๊ทธ ๋’ค์— bound-call/mov/unbound-call ์„ ์ด์–ด ๋ถ™์—ฌ\n ๊ฒฝ๊ณ„ ํ†ต๊ณผ๋ฅผ ์ฆ๋ช…: **insns 9โ†’11, halt 0x539274โ†’0x53927C**, eax=TID, edx=TID,\n ecx=0xEF(ํ”„๋กค๋กœ๊ทธ ๋ณด์กด), esp=esp0-4(0-arg stdcall ๊ท ํ˜•). ์ƒˆ ์ธก์ • ๋ผ์ธ\n `__SHIM__ PARTIAL phase=e4_kernel32_iat_bind insns=11 bound=GetCurrentThreadId\n halt_va=0x53927C halt=unbound_import unbound_slot=0x538004` ๋ฐœ์‹ , `__SHIM_TEST__\n PASS`(CI ๊ฒŒ์ดํŠธ, 24 checks). decoder(`i386_decode.c`/`.hexa`)๋Š” ๋ฏธ๋ณ€๊ฒฝ โ†’ RUNEQ\n ์˜ํ–ฅ ์—†์Œ. **own1**: ์ด๊ฒƒ์€ ๋กœ๋”๊ฐ€ ์ž๊ธฐ ํ”„๋กœ์„ธ์Šค์˜ **์ž๊ธฐ import** ๋ฅผ ๋„ค์ดํ‹ฐ๋ธŒ\n ๊ตฌํ˜„์— ๋ฌถ๋Š” ๊ฒƒ โ€” ๋ชจ๋“  PE ๋กœ๋”๊ฐ€ ํ•˜๋Š” **๋กœ๋”ฉ**์ด์ง€ ์šฐํšŒ๊ฐ€ ์•„๋‹ˆ๋‹ค. kernel32 ๋Š” OS\n API ํ‘œ๋ฉด์ด์ง€ ๋ณดํ˜ธ์žฅ์น˜(DRM/Warden/anti-cheat)๊ฐ€ ์•„๋‹ˆ๋ฉฐ, ๋ณธ ํ”„๋กค๋กœ๊ทธ ํ˜ธ์ถœ์€ CRT\n init ์ผ ๋ฟ ๋ณดํ˜ธ์™€ ๋ฌด๊ด€. `validated_manjeom` ์€ ์—ฌ์ „ํžˆ **0**(์ด๊ฒƒ์€ ๋กœ๋” ์ง„์ฒ™์ด์ง€\n ๋ Œ๋”๋œ ํ”„๋ ˆ์ž„์ด ์•„๋‹ˆ๋‹ค). ๋‹ค์Œ r5: ๋‘ ๋ฒˆ์งธ import(๋ฏธ๋“ฑ๋ก slot 0x538004) ๋ฐ”์ธ๋”ฉ +\n ๋ฒ„ํผ-์“ฐ๊ธฐํ˜• ์…ฐ์ž„(GetSystemTimeAsFileTime/QueryPerformanceCounter) + 0xC1 shift\n group ๋””์ฝ”๋” ๊ฐญ.\n\n### Fixed\n\n- test(purple cond.3): 2FA TOTP state machine ์˜ **window-drift / RFC 6238 ยง5.2 ยฑ1\n resync leg** gap ์ข…๊ฒฐ โ€” `c_purple_2fa_totp_proxy.hexa` ๋Š” `window_idx`(=unix_time/30)\n ๋ฅผ device ๋ณ„๋กœ ๊ธฐ๋กํ•˜์ง€๋งŒ, ํ•ฉ์„ฑ ์‹œ๋‚˜๋ฆฌ์˜ค๋Š” ๊ฑฐ์˜ ๋™์ผํ•œ window(58000000/58000001)๋งŒ\n ์จ์„œ **๋™์ผ device ๊ฐ€ clock drift ๋กœ ์ธ์ ‘ window(N, N+1)์— ๊ฑธ์ณ ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑ** ํ•˜๋Š”\n documented-but-unmodeled ์ถ•(RFC 6238 ยง5.2 โ€” ์„œ๋ฒ„ ยฑ1 resync window ์ˆ˜์šฉ)์„ ํ•œ ๋ฒˆ๋„\n ํ–‰์‚ฌํ•˜์ง€ ์•Š์•˜๋‹ค. ํ•ฉ์„ฑ ํ–‰ `record_totp(5004, 860, 58000010, 6)` +\n `record_totp(5004, 870, 58000011, 6)`(์ธ์ ‘ window) ์ถ”๊ฐ€๋กœ drift transition ์„\n ํ–‰์‚ฌํ•˜๊ณ , ํ—ฌํผ `count_by_window(idx)`(r1 ์˜ `count_by_stage` ๊ฑฐ์šธ) +\n `device_window_span(device_id)`(maxโˆ’min window = ยฑ1 resync ์ •๋Ÿ‰) ์ถ”๊ฐ€, ์˜์กด\n assertion ์ „๋ถ€ ๋‚ด๋ถ€์ •ํ•ฉ ๊ฐฑ์‹ (totp_count 3โ†’5, total_hmac_us 2550โ†’4280, avg_hmac_us\n 850โ†’856, valid_code_len 2โ†’4, stats[0..3] ๋™์ผ ๊ฐฑ์‹ , emit โ‰ฅ4โ†’โ‰ฅ7) + ์ƒˆ emit ๋งˆ์ปค\n `totp_window_drift`(span=1, resync=accepted_pm1) ๋ฐœ์‹ . CI 8ํŒŒ์ผ ์ค‘\n `test_purple_lineage_offline_shim.hexa` ์— `check_purple_cond3_totp_drift()`\n ์ถ”๊ฐ€(grep ๋งˆ์ปค + live `out.contains(\"drift_span=1\")`) + `track_b_purple_cond3_totp_drift`\n emit ๋ฐฐ์„ (test emit โ‰ฅ6โ†’โ‰ฅ7) โ†’ ๋ณ€๊ฒฝ์ด dead ๊ฐ€ ์•„๋‹ˆ๋ผ CI ๊ฒ€์ฆ๋จ. **cond.3 status ๋Š”\n partial ์œ ์ง€**(purple_launcher.blk.1 โ€” plaync online endpoint network-gated). own1:\n ํ•ฉ์„ฑ ๋ฐ์ดํ„ฐ๋งŒ, ์‹ค์ œ plaync account/network/TOTP secret 0๊ฑด, **GameGuard\n blocked-not-bypassed**.\n- fix(ci): CI ๊ฐ€ **์•„๋ฌด๊ฒƒ๋„ ๊ฒ€์ฆํ•˜์ง€ ์•Š๋˜** ๊ณตํ—ˆ ํ†ต๊ณผ๋ฅผ root-cause ๊ต์ • โ€”\n 8 ํ…Œ์ŠคํŠธ ํŒŒ์ผ์€ ์ „๋ถ€ `fn self_test()` + `main()` dispatch(own2 mandate)์ด๊ณ \n `@test` fn ์€ 0๊ฐœ์ธ๋ฐ, CI ๊ฐ€ `hexa test `(=@test ๋Ÿฌ๋„ˆ)์„ ์จ์„œ 0๊ฐœ ์‹คํ–‰ โ†’\n ๋ฌด์กฐ๊ฑด green ์ด์—ˆ๋‹ค. `hexa run self-test`(mainโ†’self_test dispatch)๋กœ\n ๊ต์ • โ†’ 8 self_test ๊ฐ€ ๋น„๋กœ์†Œ ์‹ค์ œ ์‹คํ–‰ยท๊ฒ€์ฆ๋œ๋‹ค. (๋กœ์ปฌ ์‹ค์ธก: `hexa test` ๋Š”\n ๋ฌด์ถœ๋ ฅ/ํ–‰, `hexa run self-test` ๋Š” own2 PASS ๋ผ์ธ ์ถœ๋ ฅ.)\n- test(battlenet cond.3): `test_d2r_archive_round_trip` ์—\n `check_battlenet_cond_3_oauth()` ์ถ”๊ฐ€ โ€” OAuth2 6 op_kind(ํŠนํžˆ device_code_grant)\n emit ๋งˆ์ปค๋ฅผ skeleton-validate(live + grep fallback). cond.3 deepening ์ด CI 8ํŒŒ์ผ\n ๋ฃจํ”„์—์„œ ์‹ค์ œ ๊ฒ€์ฆ๋˜๋„๋ก ๋ฐฐ์„ (wire-to-prod). cond.3 status ๋Š” partial ์œ ์ง€.\n- test(purple cond.3): plaync OAuth state machine ์˜ **token_refresh-FAIL leg** gap ์ข…๊ฒฐ โ€”\n `c_purple_plaync_oauth_proxy.hexa` self_test ๋Š” stage=3(token_refresh) ์„ `success=1`\n (refresh OK) ์œผ๋กœ๋งŒ ํ–‰์‚ฌํ–ˆ์œผ๋‚˜, header line 6(token_refresh stage) + line 29(success=0\n ์‚ฌ์œ  \"token ๋งŒ๋ฃŒ\")๊ฐ€ DOCUMENT ํ•œ **refresh_token ๋งŒ๋ฃŒ โ†’ ์žฌ๋กœ๊ทธ์ธ(stage=3 success=0)**\n leg ๋Š” MISSING ์ด์—ˆ๋‹ค. ํ•ฉ์„ฑ ํ–‰ `record_oauth(4004, 3, 90000, 0)` ์ถ”๊ฐ€๋กœ ํ–‰์‚ฌํ•˜๊ณ \n ์˜์กด assertion ์ „๋ถ€ ๋‚ด๋ถ€์ •ํ•ฉ ๊ฐฑ์‹ (oauth_count 4โ†’5, fail_count 1โ†’2, total_us\n 740000โ†’830000, count_by_stage(3) 1โ†’2, ppop_stats[2] 740000โ†’830000, emit โ‰ฅ5โ†’โ‰ฅ7) +\n ์ƒˆ emit ๋งˆ์ปค `plaync_oauth_refresh_fail` ๋ฐœ์‹ . CI 8ํŒŒ์ผ ์ค‘\n `test_purple_lineage_offline_shim.hexa` ์— `check_purple_cond3_oauth_refresh_fail()`\n ์ถ”๊ฐ€(grep ๋งˆ์ปค + live `out.contains(\"refresh_fail=1\")`) + `track_b_purple_cond3` emit\n ๋ฐฐ์„  โ†’ ๋ณ€๊ฒฝ์ด dead ๊ฐ€ ์•„๋‹ˆ๋ผ CI ๊ฒ€์ฆ๋จ. **cond.3 status ๋Š” partial ์œ ์ง€**\n (purple_launcher.blk.1 โ€” plaync online endpoint network-gated). own1: ํ•ฉ์„ฑ ๋ฐ์ดํ„ฐ๋งŒ,\n ์‹ค์ œ plaync account/network/token 0๊ฑด, **GameGuard blocked-not-bypassed**.\n- test(battlenet cond.3): `test_d2r_archive_round_trip` ์—\n `check_battlenet_cond_3_state_machines()` ์ถ”๊ฐ€ โ€” cond.3 4๊ฐœ ๋ชจ๋“ˆ ์ค‘ ๊ทธ๋™์•ˆ\n `pe_battle_net_oauth_token` ํ•˜๋‚˜๋งŒ CI-pin ๋˜์–ด ์žˆ์—ˆ๊ณ , ๋‚˜๋จธ์ง€ 3๊ฐœ perf ๋ชจ๋“ˆ์˜\n synthetic ์ƒํƒœ๊ธฐ๊ณ„ ๋งˆ์ปค(`__BNET_LOGIN__ PARTIAL โ€ฆ` / `__BNET_TOKEN__ PARTIAL โ€ฆ` /\n `__BNET_CHAT__ PARTIAL โ€ฆ`)๋Š” **๊ฐ ๋ชจ๋“ˆ ์ž์ฒด self_test ์•ˆ์—์„œ๋งŒ** ์‹คํ–‰๋  ๋ฟ 8 CI\n `[test].files` ์–ด๋””์„œ๋„ grep/๊ฒ€์ฆ๋˜์ง€ ์•Š๋˜ \"CI-dead\" ๊ฐญ์„ ๋‹ซ์Œ. ์„ธ ๋ชจ๋“ˆ์˜ ์ข…๋‹จ\n ์ƒํƒœ(`TOKEN_EXPIRY` / `REFRESH_FAIL_RETRY` / `OFFLINE`)๋ฅผ live self_test + grep\n fallback ์œผ๋กœ skeleton-validate โ†’ login_state / token_refresh / chat_presence\n ์ƒํƒœ๊ธฐ๊ณ„๊ฐ€ CI ์—์„œ ์‹ค์ œ ๊ฒ€์ฆ๋œ๋‹ค. ๊ฐ ๋ชจ๋“ˆ self_test ์˜ ๋ฌธ์„œํ™”๋œ ์ƒํƒœ(login 5,\n token 5, chat 4)๋Š” ์ด๋ฏธ ์ „๋ถ€ exercise ๋˜์–ด ์žˆ์–ด(self_test ์ถ• ๊ณ ๊ฐˆ) ๋ชจ๋“ˆ ์ž์ฒด๋Š”\n ๋ฌด๋ณ€๊ฒฝ โ€” ๊ฐญ์€ CI-๊ฒ€์ฆ ๋ถ€์žฌ์˜€๋‹ค. own1: ์‹ค OAuth endpoint 0 / ์‹ค XMPP 0 / socket 0 /\n network 0. cond.3 status ๋Š” partial ์œ ์ง€(network-gated = blk.1, ์ •์ง).\n\n### Added\n\n- feat(F-NSWINDOW-E5): i386 **์ธํ„ฐํ”„๋ฆฌํ„ฐ** ์ตœ์ดˆ ๋„์ž… โ€” ๋””์ฝ”๋“œ๋งŒ ํ•˜๋˜ E2 ๋ฅผ ๋„˜์–ด\n ์‹ค์ œ Win32 ๊ฒŒ์ž„ ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ”์ดํŠธ๋ฅผ **์‹คํ–‰**(์ƒํƒœ ๋ณ€์ด)ํ•œ๋‹ค. `native/i386_cpu.{c,h}`\n = ๋ ˆ์ง€์Šคํ„ฐ ํŒŒ์ผ(`gpr[8]`/eip/eflags, esp=gpr[4]) + ํ”Œ๋žซ VAโ†’host ๋ฉ”๋ชจ๋ฆฌ ๋ชจ๋ธ\n (`mem_read32`/`mem_write32`, ๊ฒฝ๊ณ„๊ฒ€์‚ฌ) + fetchโ†’decodeโ†’**execute**โ†’advance ๋ฃจํ”„.\n ์‹คํ–‰ op: PUSH_R / POP_R / PUSH_IMM / PUSH_RM([reg+disp]) / MOV_R_RM(8B) /\n MOV_RM_R(89) / CALL_REL(E8) / JMP_REL(E9ยทEB) / RET(C3ยทC2). ๋ฏธ์ปค๋ฒ„ opcode ๋Š”\n `I386_OP_UNKNOWN` ์œผ๋กœ **์ •์งํ•˜๊ฒŒ halt**(wall VA ๊ธฐ๋ก). ๋ถ„๊ธฐ ํƒ€๊นƒ์€ ๋””์Šค์–ด์…ˆ๋ธ”๋Ÿฌ์™€\n ๋™์ผํ•œ `eip+len+imm` ๊ณต์‹ ์žฌ์‚ฌ์šฉ. own1: ํ”„๋กœ๊ทธ๋žจ ์ž๊ธฐ ๋ฐ”์ดํŠธ + Intel SDM ์˜๋ฏธ๋ก ๋งŒ,\n Wine/CrossOver/Box86/QEMU/ReactOS ์†Œ์Šค 0.\n- test(F-NSWINDOW-E5): `native/i386_cpu_test.c` โ€” Battle.net-Setup.exe ์˜ ์‹ค์ œ\n 9-insn ์—”ํŠธ๋ฆฌ ๋ธ”๋ก(entry_va 0x5388A6) ์„ hermetic ํ”Œ๋žซ ์ด๋ฏธ์ง€์— ๋ฐ•์•„ CI ์—์„œ\n ๋ฐ”์ด๋„ˆ๋ฆฌ ์—†์ด ์‹คํ–‰(ํŒŒ์ผ ์ธ์ž ์ฃผ๋ฉด ์‹ค PE ๋„ ๋กœ๋“œยท์‹คํ–‰). ์‹ค์ธก(๋กœ์ปฌ clang ๋นŒ๋“œ,\n 19/19 [ok], `__SHIM_TEST__ PASS`): Run A(์—”ํŠธ๋ฆฌ์—์„œ ์‹คํ–‰) โ†’ CALL_REL 1๊ฐœ ์‹คํ–‰,\n ๋ฆฌํ„ด์ฃผ์†Œ 0x5388AB push, eip=์‹คํƒ€๊นƒ 0x539259 ๋กœ ๋ถ„๊ธฐ ํ›„ ๋””์ฝ”๋” ์ปค๋ฒ„๋ฆฌ์ง€ wall ์—์„œ\n halt โ†’ `__SHIM__ PARTIAL phase=entry_block_executed insns=1 halted=unknown halt_va=0x539259`.\n Run B(push/mov/push-rm), Run C(pop/pop/ret), Run D(jmp) ๊ฐ€ PUSH_RยทMOV_R_RMยท\n PUSH_RMยทPOP_RยทRETยทJMP_REL ์˜๋ฏธ๋ก ์„ ์‹ค ๋ฐ”์ดํŠธ๋กœ ๊ฒ€์ฆ. `native/build.sh` ์—\n `i386_cpu_test` ํƒ€๊นƒ ๋“ฑ๋ก(clang arm64 + ad-hoc codesign, ๊ธฐ์กด ๋นŒ๋“œ ์žฌ์‚ฌ์šฉ).\n โ†’ **๊ฒŒ์ž„ ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ”์ดํŠธ ์ตœ์ดˆ ์‹ค EXECUTION ๋งˆ์ผ์Šคํ†ค**. ๋‹ค์Œ wall(r3): VA 0x539259\n (`__scrt_common_main` ํ”„๋กค๋กœ๊ทธ)์˜ ์ฒซ ๋ฏธ์ปค๋ฒ„ opcode โ€” group-1 imm arith(0x83/0x81/\n 0x80)ยทmov r/m imm(0xC7/0xC6)ยทbyte mov(0x88/0x8A)ยทtest(0x84)ยทand/or(0x09/0x0B/\n 0x21/0x23) ๋””์ฝ”๋” ์ปค๋ฒ„๋ฆฌ์ง€ ํ™•์žฅ ๋Œ€์ƒ.\n- feat(F-NSWINDOW-E5 r3): r2 ์˜ **1-instruction wall(0x539259) ๋ŒํŒŒ** โ€” ๋””์ฝ”๋”+\n ์ธํ„ฐํ”„๋ฆฌํ„ฐ๋ฅผ `__scrt_common_main` ํ”„๋กค๋กœ๊ทธ opcode ์ง‘ํ•ฉ์œผ๋กœ ํ™•์žฅ. `native/i386_decode.{c,h}`\n ์— group-1 r/m,imm(0x80/0x81/0x83 โ€” add/or/adc/sbb/and/sub/xor/cmp by ModR/M.reg)ยท\n mov r/m,imm(0xC7 /0 id, 0xC6 /0 ib)ยทbyte mov+test(0x88/0x8A/0x84)ยทand/or(0x09/0x0B/\n 0x21/0x23) ๋””์ฝ”๋“œ(op enum 32..49 ๋ง๋ฏธ ์ถ”๊ฐ€ โ€” ๊ธฐ์กด 0..31 ordinal ๋ถˆ๋ณ€). `native/i386_cpu.{c,h}`\n ์— **EFLAGS ๋ชจ๋ธ**(CF/PF/AF/ZF/SF/OF โ€” SDM ADD/SUB/CMP/logic ์ •ํ™•) + `alu_add`/\n `alu_sub`/`alu_logic` + r/m32 read/write ํ—ฌํผ ์ถ”๊ฐ€, ์‹คํ–‰ op ํ™•์žฅ: MOV_R_IMM(B8+)ยท\n MOV_RM_IMM(C7)ยทLEA(8D)ยทINC/DEC r(40+/48+, CF ๋ณด์กด)ยทALU r/m,r+r,r/m(ADD/SUB/CMP/\n XOR/OR/AND/TEST)ยทgroup-1 imm(81/83). byte-width ํ˜•(80/C6/88/8A/84)์€ ๋””์ฝ”๋“œ๋˜๋˜\n ํญ ๋ฏธ๋ชจ๋ธ โ†’ **์ •์ง UNSUPPORTED**. ๊ฐ„์ ‘ IAT CALL(FF /2 [disp32])์€ ๋””์ฝ”๋“œ(CALL_RM)\n ๋˜๋˜ **์˜๋„์ ์œผ๋กœ ๋ฏธ์‹คํ–‰** = E4 kernel32 ๊ฒฝ๊ณ„(own1: IAT ํ•ด์„/DRM ์ƒํ˜ธ์ž‘์šฉ 0).\n- test(F-NSWINDOW-E5 r3): `native/i386_cpu_test.c` Run A ๊ฐ€ ์ด์ œ ์—”ํŠธ๋ฆฌ CALL ํ›„\n 0x539259 ์˜ `__scrt_common_main` ํ”„๋กค๋กœ๊ทธ(own1: named-family ๋กœ ์ง  ๋ฌธ์„œํ™”๋œ SHAPE โ€”\n ์‹ค ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ถ€์žฌ ํ˜ธ์ŠคํŠธ, SDM-์ •ํ™• ์ž๊ธฐ ๋ฐ”์ดํŠธ)๋ฅผ **8๊ฐœ ์ถ”๊ฐ€ ์‹คํ–‰**ํ•˜๊ณ  ์ฒซ ๊ฐ„์ ‘\n IAT CALL ์—์„œ ๋ฉˆ์ถ˜๋‹ค. **์‹ค์ธก(๋กœ์ปฌ clang, 20/20 [ok], `__SHIM_TEST__ PASS`)**:\n `__SHIM__ PARTIAL phase=scrt_common_main_prologue insns=9 halted=unsupported halt_va=0x539274 halt_op=call`\n โ€” r2 `insns=1 halt@0x539259` โ†’ r3 `insns=9 halt@0x539274`(reason=UNSUPPORTED=CALL_RM,\n E4 ๊ฒฝ๊ณ„). hermetic sentinel(0x538BABยท0x53872A)์€ ์•„์ง-๋ฏธ์ปค๋ฒ„ 0xC1(shift group-2,\n ๋‹ค์Œ r4 ๋””์ฝ”๋” ๊ฐญ)์œผ๋กœ ๊ต์ฒด โ†’ Run B/D ๋Š” ๊ณ„์† UNKNOWN wall ์—์„œ ์ •์ง halt. .hexa\n ํŠธ์œˆ(`native/i386_decode.hexa`) ๋™์ผ ๋ฏธ๋Ÿฌ โ†’ **RUNEQ M4 1042/1042 + M3 byte-equal\n (๋กœ์ปฌ ์‹ค์ธก green)**, hexa self_test PASS. own1: ์ž๊ธฐ ๋ฐ”์ดํŠธ + Intel SDM ์˜๋ฏธ๋ก ๋งŒ,\n Wine/QEMU/Box86/ReactOS 0, IAT/DRM/Warden ์ƒํ˜ธ์ž‘์šฉ 0. `validated_manjeom` ์€ ์—ฌ์ „ํžˆ\n **0**(์‹ค ๊ฒŒ์ž„ ํ”„๋ ˆ์ž„ ์•„๋‹˜ โ€” E3 ์ธํ„ฐํ”„๋ฆฌํ„ฐ ์ „์ง„์ด์ง€ ํ”„๋ ˆ์ž„ ์ฆ๊ฑฐ ์•„๋‹˜). ๋‹ค์Œ wall(r4):\n shift group-2(0xC1/0xD1/0xD3)ยทgroup-3(0xF7 test/neg/mul/div) ๋””์ฝ”๋” ํ™•์žฅ, ๋˜๋Š”\n ์ฒซ ์กฐ๊ฑด๋ถ„๊ธฐ(Jcc) EFLAGS ์†Œ๋น„, ๋˜๋Š” E4 = ๊ฐ„์ ‘ IAT CALL ์‹คํ–‰(kernel32 stub ๋ฐ”์ธ๋”ฉ) ๊ฒฝ๊ณ„.\n- feat(battlenet cond.3): `pe_battle_net_oauth_token` self_test ๊ฐ€ op_kind 6\n `device_code_grant`(`/oauth/device` RFC8628) ์„ ๋น„๋กœ์†Œ exercise โ€” ํ—ค๋”์—\n ๋ฌธ์„œํ™”๋์œผ๋‚˜ self_test ๋ฏธ์ปค๋ฒ„์˜€๋˜ ๊ฐญ์„ ๋‹ซ์Œ(6 op_kind ์ „๋ถ€ round-trip). ํ•ฉ์„ฑ\n ๋ฐ์ดํ„ฐยทtoken ์‹ค๊ฐ’ 0ยทlength-onlyยท์‹ค ๋„คํŠธ์›Œํฌ 0(own1 ์ค€์ˆ˜). ์–ด์„œ์…˜ ์ •ํ•ฉ:\n op_count 6โ†’7, total_token_lifetime_sec 345600โ†’432000, total_token_size_bytes\n 5120โ†’6144, count_by_op_kind(6) 0โ†’1, stats `[7,432000,6144,2]`, emit โ‰ฅ8.\n cond.3 status ๋Š” partial ์œ ์ง€(์‹ค OAuth ์—”๋“œํฌ์ธํŠธ network smoke ๊ฒŒ์ดํŠธ = blk.1).\n\n- docs(CLAUDE.md): CI(Blacksmith) ๊ทœ์œจ ๋ฐ•์ œ โ€” `## CI โ€” builds run on Blacksmith,\n NOT locally` ์„น์…˜ ์ถ”๊ฐ€(์›Œํฌํ”Œ๋กœ/๋Ÿฌ๋„ˆ/ํˆด์ฒด์ธ/์‹คํ–‰ ๋‚ด์šฉ + \"๋กœ์ปฌ ๋นŒ๋“œ ๋ง๊ณ  push\n ํ•˜๋ผ\" ๊ทœ์น™) + Structure ํŠธ๋ฆฌ์— `.github/workflows/` ํ•ญ๋ชฉ. ๊ฐ™์€ ๊ฒฐํ•จ(๋กœ์ปฌ ๋นŒ๋“œ๋กœ\n Mac ์ฃฝ์Œ) ์žฌ๋ฐœ ๋ฐฉ์ง€๋ฅผ ์œ„ํ•ด ๊ฑฐ๋ฒ„๋„Œ์Šค SSOT ์— ๋ช…์‹œ.\n\n\n- ci(blacksmith): `.github/workflows/ci.yml` โ€” gamebox ๋นŒ๋“œ+ํ…Œ์ŠคํŠธ๋ฅผ\n Blacksmith ํด๋ผ์šฐ๋“œ Apple-Silicon ๋Ÿฌ๋„ˆ(`blacksmith-6vcpu-macos-15`)์—์„œ ์‹คํ–‰.\n gamebox ๋Š” Apple-native(Win32 PE + D3DMetal)๋ผ ์ปดํŒŒ์ผ+apple-only ํ…Œ์ŠคํŠธ์—\n macOS ํ˜ธ์ŠคํŠธ๊ฐ€ ํ•„์š”ํ•œ๋ฐ, ๊ทธ๊ฑธ ๋กœ์ปฌ dev Mac ์—์„œ ๋Œ๋ฆฌ๋ฉด 242+ perf ๋ชจ๋“ˆ +\n 8 ํ…Œ์ŠคํŠธ๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ŠคํŒŒ์ดํฌํ•ด ๋จธ์‹ ์ด ์ฃฝ์—ˆ๋‹ค. ์ด์ œ push ๋งˆ๋‹ค ํด๋ผ์šฐ๋“œ Mac ์ด\n ๋นŒ๋“œ/ํ…Œ์ŠคํŠธ๋ฅผ ๋งก๊ณ  ๋กœ์ปฌ ๋ฐ•์Šค๋Š” `git push` ๋งŒ ํ•œ๋‹ค. ๋Ÿฌ๋„ˆ๋Š” macos-15 ํ•€\n (hexa-lang `release.yml` ์™€ ๋™์ผ ๊ทผ๊ฑฐ โ€” SDK min-OS ๋ฒ ์ด์Šค๋ผ์ธ ์•ˆ์ •). hexa\n ํˆด์ฒด์ธ์€ ๋ฆด๋ฆฌ์Šค ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ canonical ์„ค์น˜ ํ•œ ์ค„(`install.sh`)๋กœ ๊น๋‹ค. D3DMetal\n SDK ๋ถ€์žฌ๋Š” warn-only(skeleton-tier ๋กœ๋”๋Š” importable). same-org ๋ผ\n Blacksmith ํ™œ์„ฑํ™” ๋ณ„๋„ ์ž‘์—… ๋ถˆํ•„์š”(hexa-lang ์ด ์ด๋ฏธ ์‚ฌ์šฉ).\n\n### Changed\n\n- docs(architecture): restructure `ARCHITECTURE.json` into a deeper `children`\n tree per harness governance rule c4 โ€” a LOSSLESS re-shape (restructure only,\n no content change). Decomposed 10 over-long dump cells (root `summary` 527c +\n root `note` 731c + 8 node `summary` fields 263โ€“531c) that piled multiple\n distinct facts / ` ยท `-joined lists into one field. Each piled fact is now its\n own child node (short role line stays on the parent `summary`; each remaining\n sentence/list becomes a `{name, summary}` `โ„น๏ธ` info child). Node count\n 26 โ†’ 47. The two C-PORT milestones >250c are single coherent done-records\n (`milestones[]` is already the per-item list) and stay intact โ€” not dumps.\n Losslessness verified by non-whitespace char-multiset before vs after =\n identical (0 lost / 0 added; only scaffolding node-name labels added).\n `ARCHITECTURE.html` viewer + `python3 serve.py` stay renderable (generic over\n the `children` tree; new nodes use only `name`+`summary`).\n\n- chore(architecture): retire `DOMAINS.tape` + `domains/` (22 domain `.md`\n snapshots + 22 `.log.md` logs) into a single `ARCHITECTURE.json` tree SSOT\n (hexa-codex/anima pattern), with the `ARCHITECTURE.html` viewer +\n `python3 serve.py` static server (copied + adapted from `dancinlab/anima`).\n Each domain's `@goal` โ†’ node `summary`, its `- [ ]/[x]` milestones โ†’\n `milestones[]`, and the DOMAINS.tape `@link` edges โ†’ per-node `edges[]`\n (`--has-->` tree + `--uses-->`/`--targets-->` cross-edges preserved). Tree =\n 22 domains (1 meta-root GAMEBOX + 6 ๋ฉ”์ธ๊ตฌ์กฐ LOADER/WIN32/GFX/NET/PERF/NATIVE +\n C-PORT nested under NATIVE + 2 ๋Ÿฐ์ฒ˜ BNET/PURPLE + 1 sprint-meta LAUNCHPAD+ +\n 11 ๊ฒŒ์ž„), grouped under 4 section headers โ†’ 26 JSON nodes. `ARCHITECTURE.md`\n stays as the component-level prose SSOT and now points to the JSON tree.\n `native/i386_decode.hexa` C-PORT cross-link repointed from `domains/C-PORT.md`\n โ†’ the C-PORT node in `ARCHITECTURE.json` (provenance string left intact).\n Full per-domain `.log.md` history is recoverable via git log; the substantive\n entries folded below.\n\n Domain-log digest (folded from `domains/*.log.md`):\n - All 22 domains scaffolded 2026-05-31 (domain init, seeded from the gamebox\n ์ „์ˆ˜์กฐ์‚ฌ โ€” @goal + milestones from `.roadmap.*` + repo survey of\n lib/loader ยท lib/perf ยท native).\n - **C-PORT** (2026-06-03): M1 inventory+classify (4 native/*.c, 869 LOC;\n Tier-A 437 ยท Tier-B 113 ยท Tier-C 319) โ†’ M2 decode_modrm_disp port\n (RUNEQ 768/768, sha256 b4388479) โ†’ M3 decode_prefixes + i386_op_name +\n rd_s32/rd_s16 (RUNEQ 1069/1069, sha256 8e6acbb8) โ†’ M4 stateful\n i386_decode_one (RUNEQ 1042/1042, sha256 b2853d0a). Both M2 and M4 caught a\n real write-before-fail out-param divergence, fixed โ†’ byte-identical.\n - **GAMEBOX-D2R**: prerequisite @uses edges wired (LOADER/WIN32/GFX/NET +\n BNET); reconciled 3/4 โ€” D3D11/MPQ/D2S code present + offline/online\n checkpoints landed; gameplay-tracks (26 c_d2r_*) left open.\n - **GAMEBOX-BNET**: reconciled 5/6 โ€” 10 pe_battle(_)net_* + orchestrator\n present, D2R offline+online checkpoints prove the path; D2R non-blocking;\n D4/CS2 launch extension open.\n - **GAMEBOX-PURPLE**: reconciled 4/4 โ€” 7 c_purple_* + Lineage M/W purple play\n checkpoints; scope = M/W; Classic depends on PURPLE for download only.\n - **GAMEBOX-LINEAGE-CLASSIC**: wired LOADER/WIN32/GFX @uses; reconciled 3/4\n (r28 loader + native first-frame + play checkpoint + drift-resolution track\n bv); two corrections recorded โ€” PURPLE is the download channel (runtime\n native, \"no Purple shell\"), and Classic is an ONLINE MMO (not offline);\n playable gate = GameGuard (INCA) kernel AC honest-freeze.\n - **GAMEBOX-LAUNCHPAD+**: meta-domain init (`+` composition) targeting D2R +\n LINEAGE-CLASSIC; @has + @targets edges wired; shared \"playable\" smoke bar\n (bootโ†’titleโ†’charโ†’in-world) defined with online/anti-cheat honest-freeze.\n\n### Removed\n\n- `DOMAINS.tape` (domain roster + tree graph) โ€” superseded by\n `ARCHITECTURE.json` (`meta` + per-node `edges[]`).\n- `domains/` (22 `*.md` domain snapshots + 22 `*.log.md` logs) โ€” `*.md` folded\n into `ARCHITECTURE.json` nodes; `*.log.md` digested into the entry above\n (full text recoverable via git log).\n\n- chore(harness): perfect harness setup โ€” engine submodule bumped to latest on\n `harness-hardcore`; authored `ARCHITECTURE.md` SSOT (overview + component map +\n data flow + governance/verify, English) over the stub; authored harness-standard\n `CLAUDE.md` (H1 + blurb + `## Structure` tree + governance + `## Harness` +\n quick reference) over the SPECKIT stub; added a `docs` discipline block to\n `harness.config.json` (`architecture`/`log`/`scratchDir` + `scopeDirs: [\"\"]`\n root-only + `allow` list covering README/CHANGELOG/ARCHITECTURE/CLAUDE/AGENTS\n plus `RELEASE_NOTES_v1.0.*` and `TAPE-AUDIT.md`). `harness docs check` now\n reports `docs: ok` with 0 CLAUDE-MD violations. `.claude/settings.json` already\n carried the full guarded harness hook set (pre bash / pre write / post edit /\n prompt / prefs ยท easy ยท recommend inject / SessionStart) โ€” preserved as-is."} +{"ts":null,"title":"[1.0.4] โ€” 2026-05-05","body":"### Added\n\n- Track CK โ€” `docs/VAC_HONEST_FREEZE.md` mk1 narrative (Valve Anti-Cheat user-mode AC + Trusted Mode; resolves cs2.cond.3 deferred hook).\n- Track CL โ€” `docs/EAC_KERNEL_HONEST_FREEZE.md` mk1 narrative (EAC kernel + anti-tamper class; 3-cross-class delta_force + elden_ring base+DLC + nightreign).\n- Track CM โ€” Nightreign lib module fan-out at skeleton-tier:\n - `lib/loader/pe_elden_ring_nightreign_specific_track.hexa` (216 LOC)\n - `lib/perf/c_nightreign_co_op_session_init.hexa` (133 LOC)\n - `lib/perf/c_nightreign_matchmaking_probe.hexa` (129 LOC)\n - `lib/perf/c_nightreign_dx12_first_frame_co_op_variant.hexa` (131 LOC)\n - Total 609 LOC; retired_intentional posture inherited from blk.1 + blk.2.\n- Track CN โ€” `gamebox/doc/gamebox_hexa_interp_closure_perpetual_deferral_ack_track_cn_landed_2026_05_05.ai.md` (formally closes CJ ยง11 hook 4 as perpetually deferred; multi-year horizon).\n- 4 NEW `gamebox_*` markers (CK + CL + CM + CN).\n- 4 NEW `gamebox/doc/` handoff docs (CK + CL + CM + CN).\n\n### Changed\n\n- `hexa.toml` version: `1.0.3` โ†’ `1.0.4`.\n- `README.md` Version badge: `version-1.0.3` โ†’ `version-1.0.4`.\n- `.roadmap.elden_ring_nightreign`: `loader_count: 0 โ†’ 1`, `perf_count: 0 โ†’ 3`, NEW `loader_pattern` + `perf_pattern` + `ai_native_handoff_track_cm` fields, NEW comment header line 6 documenting Track CM skeleton-tier fan-out (Track BY documentation-only narrative line 5 preserved verbatim).\n\n### Cumulative deltas (v1.0.3 โ†’ v1.0.4)\n\n- gamebox-native markers: 15 โ†’ 19\n- Honest freeze docs: 3 โ†’ 5 (Track-E predecessor + CK + CL)\n- lib/loader files: 455 โ†’ 456 (+1 nightreign loader)\n- lib/perf files: 242 โ†’ 245 (+3 nightreign perf)\n- Forensic verdict: UNCHANGED (`SKELETON_TIER_100PCT_WIN32_VALIDATED_MANJEOM_0`)\n- validated_manjeom: UNCHANGED (0 โ€” skeleton-tier per Track BL/BM forensic baseline)\n\n### Posture\n\n- own1: Wine 0 / hexa-only / no DRM bypass / no AC bypass (5 classes covered: VAC + GameGuard + EAC kernel + EAC anti-tamper + Warden) / no FromSoft matchmaking bypass / no anima clone / `destructive_ops: 0` (maintained).\n- own2: 4 CM modules emit RETIRED_INTENTIONAL posture annotation; CN explicit no-fake-PASS / no-fake-real-run-completion declaration; skeleton-tier vs real-tier distinction explicit; spec freeze ONLY scope explicit per CK + CL."} +{"ts":null,"title":"[1.0.3] โ€” 2026-05-05","body":"### Added\n\n- Track CE โ€” `gamebox/doc/gamebox_closure_orchestrator_selftest_paper_mode_track_ce_landed_2026_05_05.ai.md` (S1-S11 paper-mode trace; BZ ยง11 hook partial resolution).\n- Track CF โ€” `gamebox/doc/gamebox_hexa_toml_modules_audit_track_cf_landed_2026_05_05.ai.md` (40 entries audit; 1 drift item flagged for CG).\n- Track CG โ€” `gamebox/doc/gamebox_c_d2r_archive_round_trip_drift_fix_track_cg_landed_2026_05_05.ai.md` (orphan reference option-b removal).\n- Track CH โ€” `gamebox/doc/gamebox_session_aggregate_v3_track_ch_landed_2026_05_05.ai.md` (first standalone-repo session aggregate covering BT-CG).\n- hexa.toml `gamebox_perf_top_families` explanatory comment block (CG).\n- 4 NEW `gamebox_*` markers (CE / CF / CG / CH).\n- `.gitignore` pattern: `resource_op_[0-9]*.marker` (CE post-mortem).\n\n### Changed\n\n- `hexa.toml` version: `1.0.2` โ†’ `1.0.3`.\n- `hexa.toml` `gamebox_perf_top_families`: orphan `c_d2r_archive_round_trip` entry removed (CG).\n- `README.md` Version badge: `version-1.0.2` โ†’ `version-1.0.3`.\n- `README.md` perf families table: `c_d2r_archive_round_trip` row removed (CG).\n\n### Cumulative deltas (v1.0.2 โ†’ v1.0.3)\n\n- gamebox-native markers: 9 โ†’ 15 (BT-CH)\n- RFC 016 audit cumulative null floor: 28 โ†’ 34 cycles\n- hexa.toml audit drift items: 1 โ†’ 0\n- Forensic verdict: UNCHANGED (`SKELETON_TIER_100PCT_WIN32_VALIDATED_MANJEOM_0`)\n- validated_manjeom: UNCHANGED (0)\n\n### Posture\n\n- own1: Wine 0 / hexa-only / no DRM / no AC / no anima clone / `destructive_ops: 0` (CG was reference-removal not file-deletion).\n- own2: paper-mode vs real-run distinction explicit; drift fix option chosen documented; v3 vs v1/v2 distinction explicit."} +{"ts":null,"title":"[1.0.2] โ€” 2026-05-05","body":"### Added\n\n- **Layout migration** (`1d28b4c refactor(layout 2026-05-05)`): canonical `/doc/` layout โ€” `airgenome/doc/` (75 predecessor handoffs) + `gamebox/doc/` (9 native handoffs incl. CB-CC).\n- Track BX โ€” per_game README ยง9 sections for 6 offline-relevant files (lineage_classic_r28 + d2r + battlenet + lineage_w + lineage_m + purple_launcher).\n- Track BY โ€” README Game Coverage refresh: wow row removed (historical preserve), elden_ring DLC scope clarified (Shadow of the Erdtree 2024-06-21), elden_ring_nightreign added (2025-05-30 standalone multiplayer co-op spinoff, documentation-only fan-out).\n- NEW `.roadmap.elden_ring_nightreign` (documentation-only, 0 lib modules at land-time).\n- NEW `docs/per_game/elden_ring_nightreign_README.ai.md` T1 baseline.\n- `dlc_scope` + `spinoff_cross_link` + `ai_native_handoff_track_by` fields on `.roadmap.elden_ring`.\n- Track BZ โ€” `gamebox/doc/gamebox_closure_orchestrator_paper_invocation_track_bz_landed_2026_05_05.ai.md` (real-invocation attempt + paper-mode derivation; hexa interp blocker).\n- Track CA โ€” `gamebox/doc/gamebox_hexa_upstream_rfc_016_reassessment_track_ca_landed_2026_05_05.ai.md` + `docs/HEXA_UPSTREAM_RFC_016_REASSESSMENT_TRACK_CA_2026_05_05.md` (28-cycle null floor reaffirmed).\n- Track CB โ€” README \"Native markers\" + \"Resolver telemetry markers (gitignored)\" subsections.\n- Track CC โ€” per_game README ยง9 sections for 4 retired_intentional files (cs2 + delta_force + diablo4 + elden_ring); elden_ring ยง9 surfaces DLC scope narrative.\n- `.gitignore` patterns for hexa-resolver runtime telemetry markers.\n- 8 NEW `gamebox_*` markers post-v1.0.0 (BT through CC).\n\n### Changed\n\n- README.md TL;DR header: `.roadmap` 14 โ†’ 15 (14 active + 1 historical), `.checkpoint` met 1 โ†’ 3.\n- README.md architecture caption: terse 7-figure โ†’ detailed inventory (455 .hexa files, 9 tests, 88 markers across 3 classes).\n- README.md Loaders heading: `(35 modules)` โ†’ `(59 named groups across 455 .hexa files)`.\n- `.roadmap.elden_ring` goal: scope = base game + Shadow of the Erdtree DLC.\n- `docs/airgenome_*.ai.md` (75) โ†’ `airgenome/doc/` per layout migration.\n- `docs/gamebox_*.ai.md` (7) โ†’ `gamebox/doc/` per layout migration.\n- `state/markers/*.marker` cross-references updated (193 files / 621 lines via sed sweep in `1d28b4c`).\n- `hexa.toml` version: `1.0.1` โ†’ `1.0.2`.\n- README version badge: `version-1.0.1` โ†’ `version-1.0.2`.\n\n### Posture\n\n- Forensic verdict UNCHANGED: `SKELETON_TIER_100PCT_WIN32_VALIDATED_MANJEOM_0`.\n- `validated_manjeom` UNCHANGED: 0 (no real game frames).\n- own1: Wine 0 / hexa-only / no DRM / no AC / no GameGuard / no EAC / no FromSoft matchmaking bypass / no anima clone / `destructive_ops: 0`.\n- own2: honest emit; per_game ยง9 sections explicit about retired_intentional stable + cross-cutting impact + validated_manjeom carry."} +{"ts":null,"title":"[1.0.1] โ€” 2026-05-05","body":"### Added\n\n- Track BU โ€” README \"Game Coverage\" section (+40 LOC; 11 .roadmap targets table + per-game index + 7 cross-roadmap checkpoint table + honest scope footer).\n- Track BU โ€” `met_iso` / `met_via` / `evidence[]` fields on `.checkpoint.win32_50pct_coverage` + `.checkpoint.win32_full_coverage`.\n- Track BV โ€” `met_iso` / `met_via` / `evidence[]` fields on `.checkpoint.lineage_classic_r28_play`.\n- Track BV โ€” 9 NEW `status_flipped_*` fields across `.roadmap.lineage_classic_r28` cond.1/cond.2/cond.3.\n- 4 NEW handoff docs + markers (BU + BV).\n\n### Changed\n\n- `.checkpoint.win32_50pct_coverage` status: `unmet 30.34/50` โ†’ `met 100/50` (BU).\n- `.checkpoint.win32_full_coverage` status: `unmet 30.34/100` โ†’ `met 100/100` (BU).\n- `.checkpoint.lineage_classic_r28_play` status: `partial 0/3` โ†’ `met 3/3` (BV, sideways-PASS).\n- `.roadmap.lineage_classic_r28` cond.1/cond.2/cond.3 actual status: `partial` โ†’ `retired_intentional` (BV cascading flip).\n- `hexa.toml` version: `1.0.0` โ†’ `1.0.1`.\n- 3 checkpoint `blockers` arrays renamed `blockers_resolved` (verbatim list preserved).\n\n### Drift resolution\n\n- Track BO snapshot v2 drift_count: 3 โ†’ 0 (all 3 items resolved across BU + BV).\n\n### Posture\n\n- Forensic verdict UNCHANGED: `SKELETON_TIER_100PCT_WIN32_VALIDATED_MANJEOM_0`.\n- `validated_manjeom` UNCHANGED: 0 (no real game frames evidenced).\n- own1: Wine 0 / hexa-only / DRM bypass 0 / Warden bypass 0 / anti-cheat bypass 0 / GameGuard bypass 0 / anima clone 0.\n- own2: PASS/FAIL/PARTIAL/RETIRED_INTENTIONAL emit honest; status flip rationale per checkpoint cited."} +{"ts":null,"title":"[1.0.0] โ€” 2026-05-05","body":"### Initial extraction\n\n- **Forensic verdict**: `SKELETON_TIER_100PCT_WIN32_VALIDATED_MANJEOM_0`\n- **Source**: `dancinlife/airgenome-gamebox` 67-cycle session (2026-05-03 to 2026-05-05; deleted 2026-05-05 per closure-cycle directive, history not transferred per D3 fresh-start policy)\n- **Reference layout**: `dancinlab/sim-universe` v1.0.0 (sibling repo)\n\n### Inventory\n\n- 35 loader modules under `lib/loader/` (32 PE *_core + 5 runtime + 5 DX + 9 Battle.net + 6 calling-conv + 2 launchers; some overlap)\n - 435/435 Win32 fn skeleton coverage (Track BP, 2026-05-05)\n- 242 perf modules under `lib/perf/` across 104 unique families\n - 18+ families at 100% manjeom (Track BL/BM forensic)\n- 14 `.roadmap.*` files (mk2 SSOT)\n- 7 `.checkpoint.*` files (mk2 checkpoint mechanism); 1 met: `win32_50pct_coverage` (Track BR derivation guard)\n- 2 tools under `tool/` (`roadmap_op.hexa` 14-subcmd anima parity broken intentional + `closure_orchestrator.hexa` weighted_threshold awareness)\n- 8 tests under `tests/`\n- 75 predecessor markers under `state/markers/airgenome_gamebox_*.marker` (preserved verbatim per own2 traceability)\n- 4 hexa-lang upstream RFCs merged (rfc_012/_013/_014 PR #47 + rfc_015 PR #48)\n\n### Posture\n\n- **own1**: Wine 0 / hexa-only / DRM bypass 0 / Warden bypass 0 / anti-cheat bypass 0 / anima clone 0\n- **own2**: PASS/FAIL emit honest, PARTIAL/RETIRED_INTENTIONAL emit explicit\n- **L1-L5 online expansion lock-in carry** (EULA / Warden / multi-year / D2R-single / parallel) per `.roadmap.battlenet`\n- **License**: Apache-2.0"} diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index fbacd57..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,705 +0,0 @@ -# Changelog - -All notable changes to `gamebox` are documented in this file. - -## [Unreleased] - -### Added - -- feat(F-NSWINDOW-E5 r12): **PEโ†’D3D11โ†’Metal end-to-end: ์ฒซ own1 D3D11 PE โ†’ Metal ํ”„๋ ˆ์ž„ (์ธํ”„๋ผ ๋งˆ์ผ์Šคํ†ค)** - โ€” r11 ์ด ์ฆ๋ช…ํ•œ D3D11โ†’Metal ๋ธŒ๋ฆฌ์ง€๋ฅผ ์ธํ„ฐํ”„๋ฆฌํ„ฐ์— ๋ฐฐ์„ ํ•˜๊ณ , ์ž์ž‘ ์ตœ์†Œ i386 PE ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ - ์‹ค์ œ Metal ๋ Œ๋” ํ”„๋ ˆ์ž„์„ ํ”ฝ์…€๋กœ ์ฝ์–ด ๊ฒ€์ฆํ•œ๋‹ค. - **์ •์งํ•œ ํ‰๊ฐ€(own2)**: ์ด๊ฒƒ์€ ์ธํ”„๋ผ ๋งˆ์ผ์Šคํ†ค โ€” gamebox ๋Ÿฐํƒ€์ž„์ด ์ž์ž‘ own1 D3D11 PE ๋ฅผ ์ธํ„ฐํ”„๋ฆฌํ„ฐ๋กœ - ์‹คํ–‰ํ•ด Metal ๋ Œ๋” ํ”„๋ ˆ์ž„์„ ํ”ฝ์…€๋กœ ์ฆ๋ช…ํ•œ *์ฒซ ๋ฒˆ์งธ* ์ผ€์ด์Šค๋‹ค. ์‹ค ์ƒ์—… ๊ฒŒ์ž„(๋””์•„๋ธ”๋กœยท๋ฆฌ๋‹ˆ์ง€ ๋“ฑ) - ์‹คํ–‰๊ณผ ๋™์ผํ•˜์ง€ ์•Š๋‹ค: ์ „์ฒด Win32/D3D11 API ์„œํ”ผ์Šคยท์‹ค ์• ์…‹ยท์‹ค ๊ฒŒ์ž„ PE ๊ฐ€ ํ•„์š”ํ•˜๋‹ค. - **validated_manjeom**: `first_own1_authored_d3d11_pe_to_metal_frame` (์ •ํ™•ํ•œ ๋ผ๋ฒจ, - "์ƒ์—… ๊ฒŒ์ž„ ํ”„๋ ˆ์ž„" ์•„๋‹˜). **own1**: Wine 0ยทDXVK 0ยทd3d11.dll ์†Œ์Šค 0ยทDRM 0ยทWarden 0ยท - ๊ฒŒ์ž„ ์• ์…‹ 0ยทanima clone 0. - **๋กœ์ปฌ M4 ์‹ค์ธก ๊ฒฐ๊ณผ**: - `__E5__ PASS pe_executed=1 frame_rendered=1 px_clear=0x0000FFFF px_triangle=0xFF0000FF nonuniform=1 insns=11 imports=7` - (1) **`native/e5_end_to_end_test.c`** โ€” E5 r12 end-to-end ํ…Œ์ŠคํŠธ (์ˆœ์ˆ˜ C): - (a) ๋ธŒ๋ฆฌ์ง€ ์˜ค๋ธŒ์ ํŠธ ํ…Œ์ด๋ธ”(g_scยทg_devยทg_ctxยทg_texยทg_rtv ์ •์  ์ „์—ญ, - g_skip/g_fail ์ƒํƒœ ํ”Œ๋ž˜๊ทธ); (b) 7๊ฐœ ๋ธŒ๋ฆฌ์ง€ shim(d3d11_create 2-arg stdcall 8B - popยทget_buffer/create_rtv/omset/clear_blue/draw/present 0-arg; ๊ฐ๊ฐ gamebox - D3D11โ†’Metal ๋ธŒ๋ฆฌ์ง€ C API ๋ž˜ํ•‘); (c) D3D11_SHIMS ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ 7์—”ํŠธ๋ฆฌ โ†’ i386_iat_autobind; - (d) `build_e5_pe_flat()` โ€” i386 PE32 ํ‰ํƒ„ ์ด๋ฏธ์ง€ ๋นŒ๋”: .text(RVA 0x1000, - 49๋ฐ”์ดํŠธ ์ฝ”๋“œ)+.idata(RVA 0x2000, d3d11.dll 7 named import; IMAGE_IMPORT_DESCRIPTOR - +INT+IAT+IBN ๋ ˆ์ด์•„์›ƒ) in-memory ๊ตฌ์„ฑ; (e) main(): PE ๋นŒ๋“œโ†’autobind(total=7 bound=7 - unbound=0)โ†’CPU ์„ค์ •+์‹คํ–‰(insns=11 halt=ret)โ†’readbackโ†’ํ”ฝ์…€ ์–ด์„œ์…˜โ†’`__E5__ PASS/PARTIAL/SKIP` - ์ถœ๋ ฅ ํ”„๋กœํ† ์ฝœ. (2) **`native/fixtures/d3d11_triangle_min.pe.txt`** โ€” ์ž์ž‘ PE ์™„์ „ ๋ ˆ์ด์•„์›ƒ - ๋ฌธ์„œ(ํŒŒ์ผ ์˜คํ”„์…‹ยทVAยท์„น์…˜ยทIAT ์Šฌ๋กฏยทimport ์ด๋ฆ„โ†’shim ๋งคํ•‘ยท์ •์ง ํ‰๊ฐ€). (3) PE ์—”ํŠธ๋ฆฌ ์ฝ”๋“œ (49๋ฐ”์ดํŠธ, - i386 hand-assembled, Intel SDM ๋ช…์‹œ): `6A 40 6A 40`(push height/width=64) + - `FF 15 [slot]`ร—7(IAT call; ๊ธฐ์กด ์ธํ„ฐํ”„๋ฆฌํ„ฐ ์ปค๋ฒ„๋ฆฌ์ง€) + `33 C0 C3`(xor+ret). - ๋””์ฝ”๋” ํ™•์žฅ ์—†์Œ(๊ธฐ์กด PUSH_IMM8ยทCALL_RMยทXOR_R_RMยทRET ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉ). (4) IAT ์Šฌ๋กฏ VA: - 0x402080(create)ยท0x402084(get_buf)ยท0x402088(rtv)ยท0x40208C(omset)ยท0x402090(clear)ยท - 0x402094(draw)ยท0x402098(present). (5) **`native/build.sh`** โ€” `e5_end_to_end_test` ํƒ€๊นƒ - ์ถ”๊ฐ€(ObjC ARCยทMetal/Foundation). (6) **`.github/workflows/ci.yml`** โ€” - `Smoke โ€” E5 end-to-end (PEโ†’D3D11โ†’Metal)` ์Šคํ… ์ถ”๊ฐ€: D3D11 ๋ธŒ๋ฆฌ์ง€ ์Šคํ… ์งํ›„. - `__E5__ PASS/SKIP/PARTIAL/FAIL` ํŒŒ์‹ฑ, warn-only(r10/r11 ํŒจํ„ด). ARCHITECTURE.json - blocking-frontiers r12 ์‹ค์ธก ๊ธฐ๋ก. - **์ฒด์ธ ์„ค๋ช…(์ •์ง)**: own1 ์ž์ž‘ i386 PE(9๋ช…๋ นยท49๋ฐ”์ดํŠธ) โ†’ i386 ์ธํ„ฐํ”„๋ฆฌํ„ฐ(i386_cpu.c) - IAT autobind(by name, own ์ž„ํฌํŠธ ๋กœ๋”ฉ=๋กœ๋”ฉ์ด์ง€ ๋ฐ”์ดํŒจ์Šค ์•„๋‹˜) โ†’ ๋ธŒ๋ฆฌ์ง€ shim layer โ†’ - gamebox D3D11โ†’Metal ๋ธŒ๋ฆฌ์ง€(d3d11_metal_bridge.m) โ†’ Apple Metal ํ—ค๋“œ๋ฆฌ์Šค ์˜คํ”„์Šคํฌ๋ฆฐ - ๋ Œ๋”(64ร—64 BGRA8 MTLTexture) โ†’ ํ”ฝ์…€ readback(getBytes) โ†’ ์–ด์„œ์…˜(blue clear โˆง red - triangle โˆง nonuniform). **๋‹ค์Œ ์ƒ์—… ๊ฒŒ์ž„ ๋ฐฉํ–ฅ**: Win32 API ์„œํ”ผ์Šค ํ™•์žฅยทopcode ์ปค๋ฒ„๋ฆฌ์ง€ - ํ™•์žฅยทvtable ๋””์ŠคํŒจ์น˜([reg+offset] ๊ฐ„์ ‘ call)ยท์‹ค ๊ฒŒ์ž„ PE IAT ์ถ”์ . - -- feat(F-NSWINDOW-E5 r11): **D3D11โ†’Metal ๋ธŒ๋ฆฌ์ง€ + ๋„ค์ดํ‹ฐ๋ธŒ ๋“œ๋ผ์ด๋ฒ„ ํ…Œ์ŠคํŠธ (๊ตฌํ˜„๋จยท๋ฏธ๋ฐฐ์„ )** - โ€” r10 ์ด ์ฆ๋ช…ํ•œ ํ—ค๋“œ๋ฆฌ์Šค Metal ์˜คํ”„์Šคํฌ๋ฆฐ ๋ Œ๋” ์„œ๋ธŒ์ŠคํŠธ๋ ˆ์ดํŠธ ์œ„์—, D3D11-์ธํ„ฐํŽ˜์ด์Šค-ํ˜•์ƒ์˜ - Metal ๋ธŒ๋ฆฌ์ง€๋ฅผ ๊ตฌ์ถ•ํ•˜๊ณ  ๋„ค์ดํ‹ฐ๋ธŒ ๋“œ๋ผ์ด๋ฒ„ ํ…Œ์ŠคํŠธ๋กœ ๊ฒ€์ฆํ•œ๋‹ค. - **own1**: gamebox ์ž์ฒด D3D11 ์ธํ„ฐํŽ˜์ด์Šค ํ˜•์ƒ โ†’ Apple Metal ๋ผ์šฐํŒ…. Wine 0ยทDXVK 0ยท - d3d11.dll ์†Œ์Šค 0ยทDRM 0ยทWarden 0ยท๊ฒŒ์ž„ ์• ์…‹ 0. **validated_manjeom ์—ฌ์ „ํžˆ 0** โ€” ๋ธŒ๋ฆฌ์ง€๋Š” - ๋„ค์ดํ‹ฐ๋ธŒ ํ…Œ์ŠคํŠธ๋กœ ์ฆ๋ช…๋์œผ๋‚˜ ์•„์ง i386 ์ธํ„ฐํ”„๋ฆฌํ„ฐ๋ฅผ ํ†ตํ•ด PE๊ฐ€ ๊ตฌ๋™ํ•˜์ง€ ์•Š์Œ. - **๊ตฌํ˜„๋จยท๋ฏธ๋ฐฐ์„  (dead-until-wired)** ๋ผ๋ฒจ: r12์—์„œ ์ธํ„ฐํ”„๋ฆฌํ„ฐ IAT autobind ๋ฐฐ์„  ์˜ˆ์ •. - (1) **`native/d3d11_metal_bridge.h`** โ€” COM ํ˜•์ƒ C ํ—ค๋”: `ID3D11Device`ยท - `ID3D11DeviceContext`ยท`IDXGISwapChain`ยท`ID3D11RenderTargetView`ยท`ID3D11Texture2D` - ๊ฐ COM ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์•ž๋‹จ vtable ํฌ์ธํ„ฐ(`lpVtbl`) + `_impl`(opaque bridge-retained - GBMetalContext\*)๋กœ ์ •์˜. vtable์€ ๊ตฌํ˜„๋œ ๋ฉ”์„œ๋“œ ๋ถ€๋ถ„์ง‘ํ•ฉ๋งŒ(์ปดํŒฉํŠธ): Device[0-2]= - IUnknown ์Šคํ…/Releaseยท[3]=CreateRenderTargetView(์‹ค d3d11.dll ์ธ๋ฑ์Šค:9); - Context[3]=OMSetRenderTargets(33)ยท[4]=ClearRenderTargetView(50)ยท[5]=Draw(13); - SwapChain[3]=GetBuffer(9)ยท[4]=Present(8). `gamebox_D3D11CreateDeviceAndSwapChain` - (12-ํŒŒ๋ผ๋ฏธํ„ฐ ์‹ค ์‹œ๊ทธ๋‹ˆ์ฒ˜๋ฅผ width+height๋กœ ๋‹จ์ˆœํ™”ยท๋งคํ•‘ ๋ฌธ์„œํ™”) + ํ”ฝ์…€ readback ํ—ฌํผ - `gamebox_d3d11_readback`. Win32 ํƒ€์ž…(HRESULTยทUINTยทFLOAT ๋“ฑ) gamebox-local ์ •์˜ - (windows.h ์˜์กด ์—†์Œ). r12 wiring ๋…ธํŠธ: vtable ์ธ๋ฑ์Šค๊ฐ€ ์‹ค d3d11.dll๊ณผ ๋‹ค๋ฆ„(์ปดํŒฉํŠธ); - ์ž์ž‘ r12 ํ…Œ์ŠคํŠธ PE๋Š” ์ด ์ธ๋ฑ์Šค๋ฅผ ์จ์•ผ ํ•จ. - (2) **`native/d3d11_metal_bridge.m`** (Objective-C + Metal + Foundation, ARC): - `GBMetalContext`(ObjC ํด๋ž˜์Šค) โ€” MTLDeviceยทqueueยทlibraryยทPSOยทbackBuffer(64ร—64 - MTLPixelFormatBGRA8UnormยทRenderTarget|ShaderReadยทStorageModeShared)ยทtriColorBuf - (red=1,0,0,1) ๋ณด์œ . ๊ฐ COM ์˜ค๋ธŒ์ ํŠธ `_impl` = `CFBridgingRetain(ctx)`(๊ณต์œ  ์ปจํ…์ŠคํŠธ - ์— ๋Œ€ํ•œ ๋ช…์‹œ์  strong ref; Release() ์‹œ CFBridgingRelease + free). MSL ์ธ๋ผ์ธ ์†Œ์Šค - (r10 smoke์™€ ๋™์ผ ์…ฐ์ด๋”). ClearRenderTargetView โ†’ loadAction=Clear ๋…๋ฆฝ ๋ Œ๋” ํŒจ์Šค - (CallerRGBA ์ƒ‰์ƒ, 0 ๋“œ๋กœ์šฐ); Draw โ†’ loadAction=Load ๋ Œ๋” ํŒจ์Šค(ํด๋ฆฌ์–ด ๋ณด์กด + ์‚ผ๊ฐํ˜• ๋“œ๋กœ์šฐ); - Present โ†’ no-op(ํ—ค๋“œ๋ฆฌ์Šค); gamebox_d3d11_readback โ†’ [MTLTexture getBytes:]. - (3) **`native/d3d11_metal_bridge_test.c`** (์ˆœ์ˆ˜ C) โ€” D3D11 ์•ฑ์ด ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•œ - vtable ํฌ์ธํ„ฐ ๊ฒฝ๋กœ: CreateDeviceAndSwapChain โ†’ scโ†’GetBuffer โ†’ devโ†’CreateRenderTargetView - โ†’ ctxโ†’OMSetRenderTargets โ†’ ctxโ†’ClearRenderTargetView(blue) โ†’ ctxโ†’Draw(3,0) โ†’ - scโ†’Present โ†’ readback โ†’ ํ”ฝ์…€ ์–ด์„œ์…˜. MTLDevice nil โ†’ `__D3D11_BRIDGE__ SKIP - reason=no_device` + exit 0(์ •์งยทwarn-only). ํ†ต๊ณผ ์‹œ `__D3D11_BRIDGE__ PASS - px_clear=0x0000FFFF px_triangle=0xFF0000FF nonuniform=1` + exit 0. ์–ด์„œ์…˜ ์‹คํŒจ ์‹œ - `__D3D11_BRIDGE__ FAIL reason=...` + exit 1. **๋กœ์ปฌ M4 ๊ฒฐ๊ณผ(๋นŒ๋“œ cleanยท-Wall -Wextra - ๊ฒฝ๊ณ  ์—†์Œ)**: `__D3D11_BRIDGE__ PASS px_clear=0x0000FFFF px_triangle=0xFF0000FF - nonuniform=1`. (4) **`native/build.sh`** โ€” `d3d11_bridge_test` ํƒ€๊นƒ ์ถ”๊ฐ€(ObjC ARCยท - Metal/Foundation; `-std=c11`ยท`-Wpedantic` ์ œ์™ธ). ad-hoc codesign. (5) - **`.github/workflows/ci.yml`** โ€” `Smoke โ€” D3D11โ†’Metal bridge (E5 r11)` ์Šคํ… ์ถ”๊ฐ€: - r10 Metal ์„œ๋ธŒ์ŠคํŠธ๋ ˆ์ดํŠธ ์Šคํ… ์งํ›„ยทCLI smoke ์ง์ „. compile+run โ†’ `__D3D11_BRIDGE__` - ํŒŒ์‹ฑ โ†’ PASS/SKIP/FAIL ๊ฐ ๋กœ๊ทธ. **warn-only**(์ปดํŒŒ์ผ ์‹คํŒจยทGPU ์—†์Œยท์–ด์„œ์…˜ ์‹คํŒจ ๋ชจ๋‘ - `::warning::`, ๋นŒ๋“œ red ์—†์Œ). r10๊ณผ ๋™์ผ ํŒจํ„ด. - **r12 ์ •์˜**: ์ตœ์†Œ D3D11 ํ…Œ์ŠคํŠธ PE(own1 ์ž์ž‘ i386 PEยทown2 ํด๋ฆฐยท๊ฒŒ์ž„ ์• ์…‹ 0) + ์ธํ„ฐํ”„๋ฆฌํ„ฐ - IAT autobind ๋ฐฐ์„  โ†’ D3D11 import(CreateDeviceAndSwapChainยทPresent ๋“ฑ)๋ฅผ ์ด ๋ธŒ๋ฆฌ์ง€ shim์— - ๋ฐ”์ธ๋”ฉ โ†’ PE๊ฐ€ vtable ํ˜ธ์ถœ โ†’ Metal ์˜คํ”„์Šคํฌ๋ฆฐ ๋ Œ๋” โ†’ readback ํ”ฝ์…€ ์–ด์„œ์…˜ = - **validated_manjeom>0 ๋‹ฌ์„ฑ ๊ฒŒ์ดํŠธ**. r12 ์ด๋ฆ„: `feat(F-NSWINDOW-E5 r12): ์ตœ์†Œ D3D11 ํ…Œ์ŠคํŠธ PE + ์ธํ„ฐํ”„๋ฆฌํ„ฐ end-to-end ๋ฐฐ์„  (validated_manjeom>0 ๊ฒŒ์ดํŠธ)`. - -- 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= - px_clear= px_triangle= 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()`** - (`native/i386_cpu.c`): `IMAGE_IMPORT_DESCRIPTOR` โ†’ INT(OriginalFirstThunk) โ†’ - `IMAGE_IMPORT_BY_NAME`(+2 hint skip) ๋ฅผ ์ง์ ‘ ํŒŒ์‹ฑํ•ด ์ด๋ฆ„ ๋ฌธ์ž์—ด๋กœ ์…ฐ์ž„ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์™€ - `strcmp` ๋งค์นญ โ€” **์Šฌ๋กฏ VA ์‚ฌ์ „์ง€์‹ ์—†์ด** ์–ด๋–ค i386 PE ์˜ IAT ๋„ ๋ฐ”์ธ๋”ฉ ๊ฐ€๋Šฅ. ๋ฏธ๋“ฑ๋ก - ์ด๋ฆ„์€ `fn=NULL`(์ •์ง; ๋Ÿฐ๋ฃจํ”„๋Š” `HALT_UNBOUND_IMPORT` + `last_import` ์— ์ด๋ฆ„ ๊ธฐ๋ก). - ์„ ์–ธ์€ `native/i386_cpu.h`(`i386_shim_entry_t` typedef + ํ•จ์ˆ˜ ์„ ์–ธ, forward-decl - `const struct i386_image *`). (2) **Import Directory RVA ํŒŒ์‹ฑ** (`native/pe_parse.c`): - `pe_image_t` ์— `import_dir_rva`/`import_dir_size` ์ถ”๊ฐ€, DataDirectory[1] ์„ PE32 - (optional-header ์˜คํ”„์…‹ 104) ์™€ PE32+(์˜คํ”„์…‹ 120) ์–‘์ชฝ์—์„œ ์ฝ์Œ. (3) **CMPXCHG - ๋””์ฝ”๋”**: `0F B0`(`cmpxchg r/m8,r8`) + `0F B1`(`cmpxchg r/m32,r32`) ๋ฅผ C ๋””์ฝ”๋” - (`native/i386_decode.c`, enum ordinal 65ยท66) ์™€ byte-equal hexa ๋ฏธ๋Ÿฌ - (`native/i386_decode.hexa`) ์–‘์ชฝ์— ์ถ”๊ฐ€(RUNEQ ๊ทœ์œจ). ์ธํ„ฐํ”„๋ฆฌํ„ฐ ์‹คํ–‰๋ถ€: EAX/AL ๊ณผ - r/m ๋น„๊ต โ†’ ๊ฐ™์œผ๋ฉด ZF=1ยทr/mโ†reg, ๋‹ค๋ฅด๋ฉด ZF=0ยทEAX/ALโ†r/m(Intel SDM Vol.2). `rm_set8` - / `mem_write8` ๋ณด์กฐ ํ•จ์ˆ˜ ์ถ”๊ฐ€. fn=NULL(autobind ๋ฏธ๋“ฑ๋ก ์Šฌ๋กฏ)์— ๋Œ€ํ•œ IAT ๋””์ŠคํŒจ์น˜ - halt ์ฒ˜๋ฆฌ๋„ ์—…๋ฐ์ดํŠธ(`last_import` ์ด๋ฆ„ ๋ณด์กด). (4) **Run E ํ…Œ์ŠคํŠธ** - (`native/i386_cpu_test.c`): ํ•ฉ์„ฑ in-memory PE import ๋””๋ ‰ํ„ฐ๋ฆฌ(base `0x540000`, - `0x1000B`): `IMAGE_IMPORT_DESCRIPTOR` 1๊ฐœ + INT 3๊ฐœ + `IMAGE_IMPORT_BY_NAME` 3๊ฐœ - (GetCurrentThreadIdยทGetTickCountยทGetCommandLineW) ๋ฅผ ๋ ˆ์ด์•„์›ƒํ•˜๊ณ  `i386_iat_autobind` - ํ˜ธ์ถœ โ†’ total=3ยทbound=3ยทunbound=0ยท์Šฌ๋กฏ VAยทfnยทname 18-ํ•ญ๋ชฉ ์ „์ˆ˜ ๊ฒ€์ฆ. GetCurrentThreadId - ์Šฌ๋กฏ์„ ํ†ตํ•œ ๋ฏธ๋‹ˆ๋Ÿฐ(`FF 15 [0x540100]` โ†’ `C3`) โ†’ `halt=ret, EAX=0x1A2B, imports_bound=1`. - CMPXCHG equal ํŒจ์Šค(EAX=ECX=`0x12345678` โ†’ ZF=1ยทECX ๋ถˆ๋ณ€)์™€ not-equal ํŒจ์Šค - (EAX=`0xAAAAAAAA`ยทECX=`0xBBBBBBBB` โ†’ ZF=0ยทEAX=`0xBBBBBBBB`) ๊ฐ 4๊ฐœ CHECK. B/D - sentinel ์€ `0F B1`(์ด์ œ CMPXCHG ๋กœ ์‹คํ–‰๋จ) โ†’ `0F C1 C0`(XADD, r10 ์ง„์งœ ๊ฐญ) ์œผ๋กœ - ๊ต์ฒด. ์ธก์ • ๋ผ์ธ `__SHIM__ PARTIAL phase=e4_iat_name_autobind names_resolved=3 - unbound=0 dispatch_ok=1`, `__SHIM_TEST__ PASS`(CI ๊ฒŒ์ดํŠธ ยท Run A 25/B 4/C 5/D 3/E 18 - checks ์ „๋ถ€ green). **own1**: ํ‘œ์ค€ PE import ํ•ด์„ = ์ž์‹ ์˜ import ๋ฅผ ๋„ค์ดํ‹ฐ๋ธŒ ๊ตฌํ˜„์— - ๋ฌถ๋Š” **๋กœ๋”ฉ**(bypass ์•„๋‹˜); ํ•ฉ์„ฑ PE ๊ตฌ์กฐยทIntel SDM CMPXCHG โ€” Wine/๋ณดํ˜ธ ์—†์Œ. - `validated_manjeom` ์—ฌ์ „ํžˆ **0**. r10 ๋ชฉํ‘œ: DXโ†’Metal ๋ธŒ๋ฆฌ์ง€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ - (`lib/loader/dx_d3d11.hexa` ์Šค์บํด๋“œ, 0 ์‹ค Metal ํ˜ธ์ถœ). - -- feat(F-NSWINDOW-E5 r8): **CRTโ†’user-entry ํ•ธ๋“œ์˜คํ”„ ๋„๋‹ฌ(ํ•ฉ์„ฑ) + BT/BTS/BTR/BTC - ๋””์ฝ”๋” ๊ฐญ ์ข…๊ฒฐ + ๋งˆ์ง€๋ง‰ CRT import 2๊ฐœ ๋ฐ”์ธ๋”ฉ** โ€” r7 ์˜ ๋ฒฝ(๋ฏธ๋“ฑ๋ก IAT ํ˜ธ์ถœ - @`0x539318`, insns=44)์„ **๋„˜์–ด CRT-init ์˜ ์ข…์ฐฉ์ ์ธ `call WinMain`(CRTโ†’user-entry - ํ•ธ๋“œ์˜คํ”„)์— ๋„๋‹ฌ**ํ•œ๋‹ค. **์ด๊ฒƒ์ด ์ •์งํ•œ E4 ์™„๋ฃŒ ๋งˆ์ผ์Šคํ†ค์ด๋ฉฐ, ๋ Œ๋”๋œ ๊ฒŒ์ž„ ํ”„๋ ˆ์ž„์ด - ์•„๋‹ˆ๋‹ค โ€” `validated_manjeom` ์€ ์—ฌ์ „ํžˆ 0.** (1) `native/i386_cpu.{c,h}` ์— ๋‘ ๊ฐœ์˜ - kernel32 ์…ฐ์ž„: `GetCommandLineW()`(0-arg โ†’ **ํ•ฉ์„ฑ in-image ์ปค๋งจ๋“œ๋ผ์ธ ํฌ์ธํ„ฐ** - `base+0x1FE0`), `SetUnhandledExceptionFilter(fn)`(1-arg โ†’ ์ด์ „ ํ•„ํ„ฐ NULL=0). IAT - ์Šฌ๋กฏ `0x53802C`/`0x538030` ์œผ๋กœ 13๊ฐœ(count=13). (2) `native/i386_decode.{c,h}` + - byte-equal `.hexa` ๋ฏธ๋Ÿฌ: enum `I386_OP_BT_RM_R`(61,`0F A3`)/`_BTS`(62,`0F AB`)/ - `_BTR`(63,`0F B3`)/`_BTC`(64,`0F BB`) + 0F 2-byte ๋ถ„๊ธฐ(0F AF IMUL ๊ณผ ๋™์ผํ•œ `/r` - ModR/M ํ˜•ํƒœ), op_name="bt"/"bts"/"btr"/"btc". ์ธํ„ฐํ”„๋ฆฌํ„ฐ: **CF โ† bit(r/m, idx)** - (idx=ModR/M.reg ๋ ˆ์ง€์Šคํ„ฐ, mod 32 ๋งˆ์Šคํฌ), BTS/BTR/BTC ๋Š” ์ˆ˜์ • ๋น„ํŠธ write-back โ€” - ํ‰๋ฒ”ํ•œ Intel SDM Vol.2 ๋น„ํŠธ ์—ฐ์‚ฐ(๋ณดํ˜ธ ์•„๋‹˜). RUNEQ corpus D(0F ์ „์ˆ˜)์—์„œ Cโ†”hexa - byte-equal ํ™•์ธ. (3) **ํ•ธ๋“œ์˜คํ”„ ๊ฒ€์ถœ**: `i386_cpu_t.user_entry_va` ํ•„๋“œ + halt - `I386_HALT_USER_ENTRY` ์ถ”๊ฐ€ โ€” `call` ์˜ ํƒ€๊นƒ์ด `user_entry_va` ์™€ ๊ฐ™์œผ๋ฉด ๋ฆฌํ„ด ์ฃผ์†Œ๋ฅผ - push ํ•œ ๋’ค(faithful "about to enter") ์ •์งํ•˜๊ฒŒ ์ •์ง€. (4) hermetic ํ…Œ์ŠคํŠธ - (`native/i386_cpu_test.c`) Run A ๋Š” r7 ์ฒด์ธ(44) ๋’ค์— `GetCommandLineW` โ†’ `pop ecx` - (์ž”์—ฌ push ์ •๋ฆฌ) โ†’ `mov esi,eax` โ†’ `SetUnhandledExceptionFilter` โ†’ `bt/bts/btr/btc` - โ†’ WinMain 4-์ธ์ž stdcall ํ”„๋ ˆ์ž„ push(nShowCmd/lpCmdLine/hPrevInstance/hInstance) โ†’ - `call 0x539400`(ํ•ฉ์„ฑ user entry) ๋ฅผ ์ด์–ด ๋ถ™์—ฌ **insns 44โ†’60, halt - `0x539318`(unbound)โ†’`0x539400`(user_entry)**, bound=13, last=SetUnhandledException- - Filter ๋ฅผ ์ฆ๋ช…. WinMain ์ธ์ž ํ”„๋ ˆ์ž„([esp+4..0x10] = hInstanceยทhPrevInstanceยท - lpCmdLineยทnShowCmd) + entry CALL ๋ฆฌํ„ด์ฃผ์†Œ(`0x5388AB`) ๋ฌด๊ฒฐ์„ฑ๊นŒ์ง€ ๊ฒ€์ฆ. B/D - sentinel ์€ `0F A3`(์ด์ œ BT ๋กœ ์‹คํ–‰๋จ) โ†’ `0F B1`(CMPXCHG, ๋‹ค์Œ ์ง„์งœ ๊ฐญ, r9) ์œผ๋กœ - ๊ต์ฒด. ์ธก์ • ๋ผ์ธ `__SHIM__ PARTIAL phase=e4_reached_user_entry insns=60 bound=13 - last=SetUnhandledExceptionFilter entry_va=0x539400 halt=user_entry halt_op=call - (SYNTHETIC user-entry; validated_manjeom=0)` + `__SHIM__ INFO - real_pe_path=structurally_ready needs:real_i386_PE+IAT_autobind_by_import_name+ - wider_opcode_coverage+D3DMetal+display`, `__SHIM_TEST__ PASS`(CI ๊ฒŒ์ดํŠธ, Run A 25 - checks ์ „๋ถ€ green, ๋กœ์ปฌ clang `-Wall -Wextra -Wpedantic -std=c11` ์ฒญ์ •). (5) - **์‹ค-๋ฐ”์ด๋„ˆ๋ฆฌ ๊ฒฝ๋กœ ์ ๊ฒ€**: `i386_cpu_load_pe`(argv[1]) ๋Š” ์„น์…˜ ๋งคํ•‘ยท์—”ํŠธ๋ฆฌ ์„ค์ •ยท - ์ด๋ฏธ์ง€ ํ• ๋‹น๊นŒ์ง€ **๊ตฌ์กฐ์ ์œผ๋กœ ๋ฐฐ์„ ๋จ** โ€” ์‹ค์ œ i386 PE ๋ฅผ ์ฃผ๋ฉด ์—”ํŠธ๋ฆฌ๋ถ€ํ„ฐ ์‹คํ–‰ ๊ฐ€๋Šฅ. - ๋‹จ, K32_IAT ์Šฌ๋กฏ์ด hermetic ํ•ฉ์„ฑ VA(`0x538000..`)๋ผ ์‹ค์ œ PE ์˜ IAT ์™€๋Š” ๋งค์นญ๋˜์ง€ - ์•Š์œผ๋ฏ€๋กœ, ์‹คํ–‰์ด ์ฒซ import ๋ฅผ ๋„˜์œผ๋ ค๋ฉด **PE import ํ…Œ์ด๋ธ” ํŒŒ์‹ฑ + ์ด๋ฆ„ ๊ธฐ๋ฐ˜ ์ž๋™ - ๋ฐ”์ธ๋”ฉ**์ด ํ•„์š”(real-PE emit ๊ฐ€ INFO ๋กœ ๋ช…์‹œ). **own1**: ์ž๊ธฐ import ๋ฅผ ๋„ค์ดํ‹ฐ๋ธŒ - ๊ตฌํ˜„์— ๋ฌถ๋Š” **๋กœ๋”ฉ**(์šฐํšŒ ์•„๋‹˜), ํ•ฉ์„ฑ TEB/์ปค๋งจ๋“œ๋ผ์ธ/user-entry VA ๋Š” **์ •์ง ๋ผ๋ฒจ**, - BT ๋ฅ˜๋Š” ํ‰๋ฒ”ํ•œ CPU ๋น„ํŠธ ์—ฐ์‚ฐ โ€” Wine/๋ณดํ˜ธ ์—†์Œ. **`validated_manjeom>0`(์‹ค ํ”„๋ ˆ์ž„) - ๊นŒ์ง€ ๋‚จ์€ ๊ฑฐ๋ฆฌ**: real-asset ๊ฒŒ์ดํŠธ(์‹ค i386 ๊ฒŒ์ž„ PE + D3DMetal SDK + ์‹ค ๋””์Šคํ”Œ๋ ˆ์ด โ€” - ์‚ฌ์šฉ์ž๋งŒ ์ œ๊ณต ๊ฐ€๋Šฅ) + ๋‚จ์€ ์—”์ง€๋‹ˆ์–ด๋ง(์‹ค PE IAT ์ด๋ฆ„ ์ž๋™๋ฐ”์ธ๋”ฉ, ๋” ๋„“์€ opcode - ์ปค๋ฒ„๋ฆฌ์ง€, ๊ฒŒ์ž„ ์ž์‹ ์˜ WinMain โ†’ ๋ฉ”์‹œ์ง€ ๋ฃจํ”„ โ†’ CreateWindowEx โ†’ D3Dโ†’Metal ํ”„๋ ˆ์ž„). - ํ˜„์žฌ๋Š” **ํ•ฉ์„ฑ user-entry ๋„๋‹ฌ**๊นŒ์ง€์ด๋ฉฐ ์‹ค ํ”„๋ ˆ์ž„์€ ์ž์œจ ๋ฒ”์œ„ ๋ฐ–(real-asset-gated). - -- feat(F-NSWINDOW-E5 r7): **CRT import 3๊ฐœ ์ถ”๊ฐ€ ๋ฐ”์ธ๋”ฉ + IMUL/CPUID/RDTSC ๋””์ฝ”๋” - ๊ฐญ ์ข…๊ฒฐ + `__security_init_cookie` ์‚ฐ์ˆ  ์‹คํ–‰** โ€” r6 ์˜ ๋ฒฝ(๋ฏธ๋“ฑ๋ก IAT ํ˜ธ์ถœ - @`0x5392D4`, insns=30)์„ **๋„˜๋Š”๋‹ค**. (1) `native/i386_cpu.{c,h}` ์— ์„ธ ๊ฐœ์˜ - kernel32 ์…ฐ์ž„ ์ถ”๊ฐ€: `GetStartupInfoW(LPSTARTUPINFOW)`(1-arg ptr, push ๋œ ํฌ์ธํ„ฐ - `[esp]` ์˜ STARTUPINFOW 0x44B ๋ฅผ 0 ์œผ๋กœ + `cb=0x44` ์Šคํƒฌํ”„ โ€” ๋ฒ„ํผ-์“ฐ๊ธฐ), - `GetSystemInfo(LPSYSTEM_INFO)`(1-arg ptr, **bounded-synthetic** SYSTEM_INFO - 0x24B โ€” dwPageSize=0x1000ยทnCPU=4ยทarch=INTEL, ๋‚˜๋จธ์ง€ 0), `GetProcAddress(HMODULE, - LPCSTR)`(2-arg โ†’ **ํ•ฉ์„ฑ in-image ์Šคํ… ์ฃผ์†Œ** `base+0x1FF0`). IAT ๋“ฑ๋ก ์Šฌ๋กฏ - `0x538000..0x538028` ๋กœ 11๊ฐœ(count=11). (2) `native/i386_decode.{c,h}` + - byte-equal `.hexa` ๋ฏธ๋Ÿฌ: enum `I386_OP_IMUL_R_RM`(57, `0F AF`)/`_IMM`(58, `69 id`/ - `6B ib`)/`I386_OP_CPUID`(59, `0F A2`)/`I386_OP_RDTSC`(60, `0F 31`) + ๋””์ฝ”๋“œ - ๋ถ„๊ธฐ ์ถ”๊ฐ€, op_name="imul"/"cpuid"/"rdtsc". ์ธํ„ฐํ”„๋ฆฌํ„ฐ: **IMUL** ์€ 32-bit signed - ๊ณฑ์˜ ํ•˜์œ„ 32-bit ๋ฅผ dst(ModR/M.reg)์—, int32 ์˜ค๋ฒ„ํ”Œ๋กœ๋ฉด CF=OF=1(SDM Vol.2); - **CPUID** ๋Š” leaf(eax)๋ณ„ **ํ•ฉ์„ฑ** ํ”ผ์ฒ˜์…‹(leaf0 vendor "GenuineIntel"ยทmax-leaf, - leaf1 family/feature) ์„ eax/ebx/ecx/edx ์—; **RDTSC** ๋Š” `cpu->tsc += step` ํ•ฉ์„ฑ - ๋‹จ์กฐ ์นด์šดํ„ฐ๋ฅผ edx:eax ์— ๊ธฐ๋ก. CPUID/RDTSC ๋Š” ํ‰๋ฒ”ํ•œ CPU ๋ช…๋ น(๋ณดํ˜ธ ์•„๋‹˜). (3) - **๋ณด์•ˆ์ฟ ํ‚ค ์‚ฐ์ˆ **: hermetic ํ”„๋กค๋กœ๊ทธ๊ฐ€ FILETIME ์—”ํŠธ๋กœํ”ผ ๋กœ๋“œ โ†’ `xor` โ†’ - `imul eax,eax,0x01000193`(์‹ ๊ทœ 0x69 IMUL) โ†’ ๊ธ€๋กœ๋ฒŒ ์Šฌ๋กฏ์— **๋น„๊ธฐ๋ณธ ์ฟ ํ‚ค** ์ €์žฅ โ†’ - `cpuid`(GenuineIntel) โ†’ `rdtsc`. (4) hermetic ํ…Œ์ŠคํŠธ(`native/i386_cpu_test.c`) - Run A ๋Š” r6 ์ฒด์ธ ๋’ค์— `call GetStartupInfoW`(cb=0x44 ๊ฒ€์ฆ) / `call GetSystemInfo` - (page=0x1000ยทnCPU=4 ๊ฒ€์ฆ) / `pushร—2; call GetProcAddress` / ์ฟ ํ‚ค `mov/xor/imul/mov` - (์ฟ ํ‚ค == `(FT_lo^FT_hi)*0x01000193` ์žฌ์œ ๋„ ๊ฒ€์ฆ, โ‰ 0) / `cpuid`(ebx="Genu"ยท - ecx="ntel" ๊ฒ€์ฆ) / `rdtsc`(edx:eax ํ•ฉ์„ฑ ๊ฒ€์ฆ) / ๋ฏธ๋“ฑ๋ก `call` ์„ ์ด์–ด ๋ถ™์—ฌ ๊ฒฝ๊ณ„ - ํ†ต๊ณผ๋ฅผ ์ฆ๋ช…: **insns 30โ†’44, halt `0x5392D4`โ†’`0x539318`**(reason=UNBOUND_IMPORT, - slot `0x53802C`), bound=11, last=GetProcAddress. B/D sentinel ์€ `0F A2`(์ด์ œ ์‹คํ–‰๋จ) - โ†’ `0F A3`(BT, ๋‹ค์Œ ์ง„์งœ ๋””์ฝ”๋” ๊ฐญ) ์œผ๋กœ ๊ต์ฒด. ์ธก์ • ๋ผ์ธ `__SHIM__ PARTIAL - phase=e4_crt_security_cookie insns=44 bound=11 last=GetProcAddress - halt_va=0x539318 halt=unbound_import halt_op=call unbound_slot=0x53802C`, - `__SHIM_TEST__ PASS`(CI ๊ฒŒ์ดํŠธ, Run A 18 checks ์ „๋ถ€ green, ๋กœ์ปฌ clang - `-Wall -Wextra -Wpedantic -std=c11` ์ฒญ์ •). **own1**: ๋กœ๋”๊ฐ€ ์ž๊ธฐ ํ”„๋กœ์„ธ์Šค์˜ **์ž๊ธฐ - import**(kernel32 OS API)๋ฅผ ๋„ค์ดํ‹ฐ๋ธŒ ๊ตฌํ˜„์— ๋ฌถ๋Š” **๋กœ๋”ฉ** โ€” ์šฐํšŒ ์•„๋‹˜; CPUID/RDTSC - ๋Š” ํ‰๋ฒ”ํ•œ CPU ๋ช…๋ น, ์ฟ ํ‚ค๋Š” **์ž๊ธฐ ๋ฒ„ํผ ์œ„์˜ ์ž๊ธฐ ์‚ฐ์ˆ **, ํ•ฉ์„ฑ SYSTEM_INFO/์Šคํ…์€ - ์ •์ง ๋ผ๋ฒจ. **`main`/`WinMain` ๋ฏธ๋„๋‹ฌ**: ์•„์ง CRT-init(import ๋ฐ”์ธ๋”ฉ) ๋‹จ๊ณ„์ด๋ฉฐ - hermetic ํ”„๋กค๋กœ๊ทธ๋Š” ์‹ค์ œ ๋ฐ”์ด๋„ˆ๋ฆฌ๊ฐ€ ์•„๋‹Œ ๋ฌธ์„œํ™”๋œ SHAPE ๋ผ ์ง„์งœ `call main` ์€ - ์—†์Œ โ€” ๋‚จ์€ CRT ๋‹จ๊ณ„(์ถ”๊ฐ€ import + `__scrt_common_main_seh` โ†’ user entry). `validated_manjeom` - ์€ ์—ฌ์ „ํžˆ **0**(๋กœ๋” ์ง„์ฒ™์ด์ง€ ๋ Œ๋”๋œ ํ”„๋ ˆ์ž„ ์•„๋‹˜). ๋‹ค์Œ r8: ๋ฏธ๋“ฑ๋ก slot `0x53802C` - ๋ฐ”์ธ๋”ฉ + `0F A3` BT ๋””์ฝ”๋” ๊ฐญ + ์‹ค์ œ ๋ฐ”์ด๋„ˆ๋ฆฌ์—์„œ `mainCRTStartupโ†’main` ๊ฑฐ๋ฆฌ ์ธก์ •. - -- feat(F-NSWINDOW-E5 r6): **CRT-security import 3๊ฐœ ์ถ”๊ฐ€ ๋ฐ”์ธ๋”ฉ + 0F B6/B7/BE/BF - MOVZX/MOVSX ๋””์ฝ”๋” ๊ฐญ ์ข…๊ฒฐ + ํ•ฉ์„ฑ TEBโ†’PEBโ†’ImageBase ์ฒด์ธ** โ€” r5 ์˜ ๋ฒฝ(๋ฏธ๋“ฑ๋ก IAT - ํ˜ธ์ถœ @`0x5392A1`, insns=18)์„ **๋„˜๋Š”๋‹ค**. (1) `native/i386_cpu.{c,h}` ์— ์„ธ ๊ฐœ์˜ - kernel32 ์…ฐ์ž„ ์ถ”๊ฐ€: `IsProcessorFeaturePresent(DWORD)`(1-arg โ†’ BOOL 1, ๊ธฐ๋Šฅ - present ๊ฒฐ์ •์  ์ฃผ์žฅ), `InitializeSListHead(PSLIST_HEADER)`(1-arg ptr, push ๋œ - ํฌ์ธํ„ฐ `[esp]` ์˜ 8-byte SLIST ํ—ค๋”๋ฅผ 0 ์œผ๋กœ โ€” ๋ฒ„ํผ-์“ฐ๊ธฐ), `GetModuleHandleW( - LPCWSTR)`(1-arg, HMODULE=๋กœ๋”๊ฐ€ ์•„๋Š” **์ž๊ธฐ ์ด๋ฏธ์ง€ ๋ฒ ์ด์Šค** ๋ฐ˜ํ™˜). IAT ๋“ฑ๋ก - ์Šฌ๋กฏ `0x538000..0x53801C` ๋กœ 8๊ฐœ(count=8). (2) `native/i386_decode.{c,h}` + - byte-equal `.hexa` ๋ฏธ๋Ÿฌ: 2-byte(0F) ๋งต์— enum `I386_OP_MOVZX_RM8`(53)/`_RM16`(54)/ - `I386_OP_MOVSX_RM8`(55)/`_RM16`(56) + ๋””์ฝ”๋“œ ๋ถ„๊ธฐ(B6/B7/BE/BF, ModR/M reg=dst - r32, r/m8|r/m16 src) ์ถ”๊ฐ€, op_name="movzx"/"movsx"; 0F ์˜ `avail<6` ๊ฐ€๋“œ๋ฅผ - `avail<2`(+Jcc ๋งŒ `<6`)๋กœ ๋ถ„๋ฆฌํ•ด ์งง์€ movzx ๋„ ๋””์ฝ”๋“œ. ์ธํ„ฐํ”„๋ฆฌํ„ฐ๋Š” r/m8(๋ ˆ์ง€์Šคํ„ฐ - ๋ฐ”์ดํŠธ๋งต al..bh / mem `mem_read8`)ยทr/m16 ์„ zero/sign-extend โ†’ r32, **EFLAGS ๋ถˆ๋ณ€**. - (3) **BOUNDED-SYNTHETIC TEB**: `i386_cpu` ์— `teb_base` ํ•„๋“œ ์ถ”๊ฐ€ โ€” ๋ฉ”๋ชจ๋ฆฌ ์˜คํผ๋žœ๋“œ๊ฐ€ - FS ์„ธ๊ทธ๋จผํŠธ-override ํ”„๋ฆฌํ”ฝ์Šค(0x64, ์ด๋ฏธ ๋””์ฝ”๋“œ๋จ)๋ฅผ ๋‹ฌ๋ฉด `i386_ea` ๊ฐ€ ์œ ํšจ์ฃผ์†Œ๋ฅผ - `teb_base+disp` ๋กœ ๋ฆฌ๋””๋ ‰ํŠธ. ํ•ฉ์„ฑ TEB(self@+0x18) โ†’ PEB(@TEB+0x30) โ†’ ImageBase - (@PEB+8) ์˜ ๋ช‡ ๊ฐœ ํ•„๋“œ๋งŒ ์ด๋ฏธ์ง€ ๋ฉ”๋ชจ๋ฆฌ์— ๊น”์•„ ๋ณด์•ˆ์ฟ ํ‚ค/CRT-startup ํ”„๋กค๋กœ๊ทธ์˜ - `mov ecx, fs:[0x18]` ์ฒด์ธ์ด **๋ˆ๋‹ค**(OS TEB ์•„๋‹˜ยท๋ณดํ˜ธ๊ตฌ์กฐ ์•„๋‹˜, ์ •์ง ๋ผ๋ฒจ). hermetic - ํ…Œ์ŠคํŠธ(`native/i386_cpu_test.c`) Run A ๋Š” r5 ํ•ฉ์„ฑ ํ”„๋กค๋กœ๊ทธ ๋’ค์— `push 0xA; call - IsProcessorFeaturePresent` / `movzx ecx,al; movsx edx,cl`(์‹ ๊ทœ ๋‘-๋ฐ”์ดํŠธ ์‹ค์ฆ) / - `push &slist; call InitializeSListHead`(8B ์ œ๋กœํ™” ๊ฒ€์ฆ, ์‚ฌ์ „ ๋”ํ‹ฐ `0xFFFFFFFF`) / - `push 0; call GetModuleHandleW`(โ†’ ์ด๋ฏธ์ง€ ๋ฒ ์ด์Šค) / `mov ecx,fs:[0x18]; mov edx, - [ecx+0x30]; mov eax,[edx+8]`(TEBโ†’PEBโ†’ImageBase) / ๋ฏธ๋“ฑ๋ก `call` ์„ ์ด์–ด ๋ถ™์—ฌ - ๊ฒฝ๊ณ„ ํ†ต๊ณผ๋ฅผ ์ฆ๋ช…: **insns 18โ†’30, halt `0x5392A1`โ†’`0x5392D4`**(reason= - UNBOUND_IMPORT, slot `0x538020`), bound=8, last=GetModuleHandleW, - eax=ImageBase(`0x538000`)ยทecx=TEB(`0x539C00`)ยทedx=PEB(`0x539C80`) ์‹ค์ฆ, - esp=esp0-8(์—”ํŠธ๋ฆฌ ๋ฐ˜ํ™˜์ฃผ์†Œ+๋ฏธpop push). B/D sentinel ์€ `0F B6`(์ด์ œ ์‹คํ–‰๋จ)โ†’ - `0F A2`(CPUID, ๋‹ค์Œ ์ง„์งœ ๋””์ฝ”๋” ๊ฐญ) ์œผ๋กœ ๊ต์ฒด. ์ธก์ • ๋ผ์ธ `__SHIM__ PARTIAL - phase=e4_crt_security_teb insns=30 bound=8 last=GetModuleHandleW - halt_va=0x5392D4 halt=unbound_import halt_op=call unbound_slot=0x538020`, - `__SHIM_TEST__ PASS`(CI ๊ฒŒ์ดํŠธ, Run A 17 checks ์ „๋ถ€ green, ๋กœ์ปฌ clang - `-Wall -Wextra -Wpedantic -std=c11` ์ฒญ์ •). **own1**: ๋กœ๋”๊ฐ€ ์ž๊ธฐ ํ”„๋กœ์„ธ์Šค์˜ **์ž๊ธฐ - import**(kernel32 OS API)๋ฅผ ๋„ค์ดํ‹ฐ๋ธŒ ๊ตฌํ˜„์— ๋ฌถ๋Š” **๋กœ๋”ฉ** โ€” ์šฐํšŒ ์•„๋‹˜; TEB ๋Š” **์ž๊ธฐ - ํ•ฉ์„ฑ ๋ธ”๋ก**(ํ•„๋“œ ๋ช‡ ๊ฐœ)์ด์ง€ OS TEB ๋„, ๋ณดํ˜ธ์žฅ์น˜๋„ ์•„๋‹˜. `validated_manjeom` ์€ - ์—ฌ์ „ํžˆ **0**(๋กœ๋” ์ง„์ฒ™์ด์ง€ ๋ Œ๋”๋œ ํ”„๋ ˆ์ž„ ์•„๋‹˜). ๋‹ค์Œ r7: ๋ฏธ๋“ฑ๋ก slot `0x538020` - ๋ฐ”์ธ๋”ฉ(GetStartupInfoW/GetProcAddress ๋“ฑ) + `0F A2` CPUID ๋””์ฝ”๋” ๊ฐญ + ํ’€ ๋ณด์•ˆ์ฟ ํ‚ค - ์—ฐ์‚ฐ(time/pid/tid XORยทmul) โ†’ `main`/`WinMain` ๋„๋‹ฌ, user32 `CreateWindowEx` ๊ฑฐ๋ฆฌ. -- feat(F-NSWINDOW-E5 r5): **CRT-init import 5๊ฐœ ์—ฐ์† ๋ฐ”์ธ๋”ฉ + ์ฒซ ๋ฒ„ํผ-์“ฐ๊ธฐ ์…ฐ์ž„ + - 0xC1 shift-group ๋””์ฝ”๋” ๊ฐญ ์ข…๊ฒฐ** โ€” r4 ์˜ ๋ฒฝ(๋ฏธ๋“ฑ๋ก IAT ํ˜ธ์ถœ @`0x53927C`, - insns=11)์„ **๋„˜๋Š”๋‹ค**. `native/i386_cpu.{c,h}` ์— ๋„ค ๊ฐœ์˜ kernel32 ์…ฐ์ž„ ์ถ”๊ฐ€: - `GetCurrentProcessId`(0-arg โ†’ ๊ฒฐ์ •์  PID `0xD04`), `GetTickCount`(0-arg โ†’ `0x1D4C0`), - ๊ทธ๋ฆฌ๊ณ  **์ฒซ ๋ฒ„ํผ-์“ฐ๊ธฐํ˜• ์…ฐ์ž„** `GetSystemTimeAsFileTime(LPFILETIME)` โ€” - ์Šคํƒ์—์„œ caller ๊ฐ€ push ํ•œ ํฌ์ธํ„ฐ ์ธ์ž(`[esp]`, ํ˜ธ์ถœ ๊ฐ€๋กœ์ฑ„๊ธฐ ์‹œ์ ์ด๋ผ ๋ฐ˜ํ™˜์ฃผ์†Œ๊ฐ€ - ์•„์ง ์•ˆ ์Œ“์ž„)๋ฅผ ์ฝ์–ด ์ด๋ฏธ์ง€ ๋ฉ”๋ชจ๋ฆฌ์— 8-byte FILETIME(`mem_write32`ร—2)์„ ๊ธฐ๋กํ•˜๊ณ  - void ๋ฐ˜ํ™˜(stdcall 1-arg, callee-pop 4) โ€” r4 ์˜ 0-arg ์…ฐ์ž„ ๋Œ€๋น„ **stubโ†’์ด๋ฏธ์ง€ ๋ฉ”๋ชจ๋ฆฌ - ์“ฐ๊ธฐ + ์‹ค์ œ push ๋œ ํฌ์ธํ„ฐ ์ธ์ž**๋ผ๋Š” ์ƒˆ ๋Šฅ๋ ฅ์„ ํ–‰์‚ฌ. `QueryPerformanceCounter( - LARGE_INTEGER*)` ๋„ ๋™์ผ ํŒจํ„ด(8-byte ์นด์šดํ„ฐ ๊ธฐ๋ก, BOOL=1 ๋ฐ˜ํ™˜). ์‹คํ–‰ ๋ฃจํ”„๋Š” ์ด์ œ - bound ํ˜ธ์ถœ์„ ์—ฐ๋‹ฌ์•„ ๋””์ŠคํŒจ์น˜ํ•ด ํ”„๋กค๋กœ๊ทธ๊ฐ€ ๋‹ค์„ฏ import(GetCurrentThreadId โ†’ - GetCurrentProcessId โ†’ GetSystemTimeAsFileTime โ†’ QueryPerformanceCounter โ†’ - GetTickCount)๋ฅผ ํ†ต๊ณผํ•˜๊ณ , **์—ฌ์„ฏ ๋ฒˆ์งธยท๋ฏธ๋“ฑ๋ก IAT ํ˜ธ์ถœ @`0x5392A1`** ์—์„œ ์ •์งํ•˜๊ฒŒ - HALT(`UNBOUND_IMPORT`, ๋‹ค์Œ ์Šฌ๋กฏ `0x538014` ๋ณด๊ณ ). -- feat(F-NSWINDOW-E5 r5): **0xC1/0xD1/0xD3 group-2 shift/rotate ๋””์ฝ”๋”+์‹คํ–‰** โ€” - r3 sentinel ์ด ์ง€๋ชฉํ•œ `0xC1` ๊ฐญ์„ ์ข…๊ฒฐ. `native/i386_decode.{c,h}` + - byte-equal `.hexa` ๋ฏธ๋Ÿฌ์— enum `I386_OP_SHIFT_RM_IMM8`(50)/`_RM_1`(51)/`_RM_CL`(52) - + ๋””์ฝ”๋“œ ๋ถ„๊ธฐ(count ์ถœ์ฒ˜: imm8 / 1 / CL) ์ถ”๊ฐ€, op_name="shift". ์ธํ„ฐํ”„๋ฆฌํ„ฐ - (`i386_cpu.c`)๋Š” ModR/M.reg ๋กœ SHL/SAL(4/6)ยทSHR(5)ยทSAR(7)ยทROL(0)ยทROR(1) ์„ - ๋ถ„๊ธฐํ•˜๊ณ  SDM ๋Œ€๋กœ count ๋ฅผ 5-bit ๋งˆ์Šคํ‚น + CF/OF/ZF/SF/PF ๊ฐฑ์‹ (count==0 โ†’ ๋ฌด๋ณ€ํ™”ยท - ๋ฌดํ”Œ๋ž˜๊ทธ); RCL/RCR(2/3) carry-chain ์€ ๋ฏธ๋ชจ๋ธ โ†’ ์ •์งํ•œ UNSUPPORTED. RUNEQ ๋Š” - C/hexa ์–‘์ชฝ์ด ๋™์ผํ•˜๊ฒŒ ๋ฐ”๋€Œ๋ฏ€๋กœ ๊ทธ๋ฆฐ ์œ ์ง€(corpus A ์˜ 0xC1/D1/D3 ํ–‰๋งŒ ๋™์‹œ ๋ณ€ํ™”). - hermetic ํ…Œ์ŠคํŠธ(`native/i386_cpu_test.c`) Run A ๋Š” ํ•ฉ์„ฑ ํ”„๋กค๋กœ๊ทธ๋ฅผ 0x53927C ๊นŒ์ง€ - ์œ ์ง€ํ•˜๊ณ  ๋’ค์— `call GetCurrentProcessId` / `push &filetime; call - GetSystemTimeAsFileTime` / `push &perfcount; call QueryPerformanceCounter` / - `shl edx,4`(group-2 shift) / `call GetTickCount` / ๋ฏธ๋“ฑ๋ก `call` ์„ ์ด์–ด ๋ถ™์—ฌ - ๊ฒฝ๊ณ„ ํ†ต๊ณผ๋ฅผ ์ฆ๋ช…: **insns 11โ†’18, halt `0x53927C`โ†’`0x5392A1`**(reason= - UNBOUND_IMPORT, slot `0x538014`), bound=5, last=GetTickCount, eax=GetTickCount - stub, edx=TID<<4=`0x1A2B0`(shift ์‹ค์ฆ), ecx=0xEF(ํ”„๋กค๋กœ๊ทธ ๋ณด์กด), esp=esp0-4, - ๊ทธ๋ฆฌ๊ณ  **๋ฒ„ํผ ๋‘ ๊ณณ ๊ฒ€์ฆ**: `[0x539F00]`=FILETIME `01D7A1B2:C3D4E5F6`, - `[0x539F10]`=counter `00000000:12345678`. B/D sentinel ์€ `0xC1`(์ด์ œ ์‹คํ–‰๋จ)โ†’ - `0F B6`(MOVZX, ๋‹ค์Œ ์ง„์งœ ๋””์ฝ”๋” ๊ฐญ) ์œผ๋กœ ๊ต์ฒด. ์ธก์ • ๋ผ์ธ `__SHIM__ PARTIAL - phase=e4_kernel32_iat_bind insns=18 bound=5 last=GetTickCount halt_va=0x5392A1 - halt=unbound_import halt_op=call unbound_slot=0x538014`, `__SHIM_TEST__ PASS` - (CI ๊ฒŒ์ดํŠธ, Run A 16 checks ์ „๋ถ€ green, ๋กœ์ปฌ clang `-Wall -Wextra -std=c11` ์ฒญ์ •). - **own1**: ๋กœ๋”๊ฐ€ ์ž๊ธฐ ํ”„๋กœ์„ธ์Šค์˜ **์ž๊ธฐ import**(kernel32 OS API ํ‘œ๋ฉด)๋ฅผ ๋„ค์ดํ‹ฐ๋ธŒ - ๊ตฌํ˜„์— ๋ฌถ๋Š” **๋กœ๋”ฉ** โ€” ์šฐํšŒ ์•„๋‹˜. FILETIME/perf-counter/tick/pid ๋Š” CRT init ์˜ - ๊ฒฐ์ •์  STUB ์ด์ง€ ๋ณดํ˜ธ์žฅ์น˜(DRM/Warden/anti-cheat)์™€ ๋ฌด๊ด€ํ•˜๊ณ , ๋ฒ„ํผ ์“ฐ๊ธฐ๋Š” ํ”„๋กœ๊ทธ๋žจ - **์ž๊ธฐ ๋ฒ„ํผ**์— ํ•œ์ •. `validated_manjeom` ์€ ์—ฌ์ „ํžˆ **0**(๋กœ๋” ์ง„์ฒ™์ด์ง€ ๋ Œ๋”๋œ - ํ”„๋ ˆ์ž„ ์•„๋‹˜). ๋‹ค์Œ r6: ๋ฏธ๋“ฑ๋ก slot `0x538014` ๋ฐ”์ธ๋”ฉ + `0F B6` MOVZX ๋””์ฝ”๋” ๊ฐญ + - ๋” ๊นŠ์€ CRT init(๋ณด์•ˆ์ฟ ํ‚ค XOR/__security_init_cookie, TEB/PEB ์ ‘๊ทผ) โ†’ `main`/ - `WinMain` ๋„๋‹ฌ, ๊ทธ๋ฆฌ๊ณ  user32 `CreateWindowEx` ๊นŒ์ง€์˜ ๊ฑฐ๋ฆฌ ์ธก์ •. - -- feat(F-NSWINDOW-E5 r4): **์ฒซ E4 kernel32 IAT ๋ฐ”์ธ๋”ฉ** โ€” i386 ์ธํ„ฐํ”„๋ฆฌํ„ฐ๊ฐ€ r3 ์˜ - ๋ฒฝ(`FF 15 [disp32]` ๊ฐ„์ ‘ IAT ํ˜ธ์ถœ @`0x539274`, insns=9 ์—์„œ HALT)์„ **๋„˜๋Š”๋‹ค**. - `native/i386_cpu.{c,h}` ์— import-stub ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ(`i386_iat_t`/`i386_import_t` + - `i386_iat_lookup`) ์™€ ์ฒซ ๋„ค์ดํ‹ฐ๋ธŒ kernel32 ์…ฐ์ž„(`i386_shim_GetCurrentThreadId`, - stdcall 0-arg โ†’ ๊ฒฐ์ •์  plausible TID `0x1A2B`)์„ ์ถ”๊ฐ€. ์‹คํ–‰ ๋ฃจํ”„์˜ `CALL_RM`/`JMP_RM` - ์ผ€์ด์Šค๋Š” ์ด์ œ ์ •๊ทœ IAT thunk ํ˜•ํƒœ(ModR/M mod=00,rm=101 = `[disp32]`)๋ฅผ ์ธ์‹ํ•ด - slot VA(=`insn.disp`)๋ฅผ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์—์„œ ์กฐํšŒํ•œ๋‹ค โ€” **๋ฐ”์ธ๋”ฉ๋˜์–ด ์žˆ์œผ๋ฉด** ๋„ค์ดํ‹ฐ๋ธŒ - ์…ฐ์ž„์„ ๋””์ŠคํŒจ์น˜ํ•˜๊ณ  EAX ์— ๋ฐ˜ํ™˜๊ฐ’์„ ์‹ฃ๊ณ (Win32 ABI) stdcall ์ธ์ž๋ฅผ pop ํ•œ ๋’ค - ์‹คํ–‰์„ **๊ณ„์†**ํ•œ๋‹ค. `__scrt_common_main` security-cookie init ์˜ ์ฒซ ํ˜ธ์ถœ - GetCurrentThreadId ๊ฐ€ ๋ฐ”์ธ๋”ฉ๋˜์–ด 0x539274 ์˜ ํ˜ธ์ถœ์ด **์‹คํ–‰**๋˜๊ณ (insn 10), ๋‹ค์Œ - `mov edx,eax`(insn 11)๊นŒ์ง€ ์ง„ํ–‰ํ•œ ๋’ค **๋‘ ๋ฒˆ์งธยท๋ฏธ๋“ฑ๋ก IAT ํ˜ธ์ถœ @`0x53927C`** ์—์„œ - ์ •์งํ•˜๊ฒŒ HALT(`UNBOUND_IMPORT` โ€” ๋‹ค์Œ์— ๋ฐ”์ธ๋”ฉํ•  import ์Šฌ๋กฏ `0x538004` ๋ฅผ ๋ณด๊ณ ). - hermetic ํ…Œ์ŠคํŠธ(`native/i386_cpu_test.c`) Run A ๋Š” ํ•ฉ์„ฑ ํ”„๋กค๋กœ๊ทธ๋ฅผ 0x539274 ๊นŒ์ง€ - r3 ์™€ byte-๋™์ผํ•˜๊ฒŒ ์œ ์ง€ํ•˜๊ณ  ๊ทธ ๋’ค์— bound-call/mov/unbound-call ์„ ์ด์–ด ๋ถ™์—ฌ - ๊ฒฝ๊ณ„ ํ†ต๊ณผ๋ฅผ ์ฆ๋ช…: **insns 9โ†’11, halt 0x539274โ†’0x53927C**, eax=TID, edx=TID, - ecx=0xEF(ํ”„๋กค๋กœ๊ทธ ๋ณด์กด), esp=esp0-4(0-arg stdcall ๊ท ํ˜•). ์ƒˆ ์ธก์ • ๋ผ์ธ - `__SHIM__ PARTIAL phase=e4_kernel32_iat_bind insns=11 bound=GetCurrentThreadId - halt_va=0x53927C halt=unbound_import unbound_slot=0x538004` ๋ฐœ์‹ , `__SHIM_TEST__ - PASS`(CI ๊ฒŒ์ดํŠธ, 24 checks). decoder(`i386_decode.c`/`.hexa`)๋Š” ๋ฏธ๋ณ€๊ฒฝ โ†’ RUNEQ - ์˜ํ–ฅ ์—†์Œ. **own1**: ์ด๊ฒƒ์€ ๋กœ๋”๊ฐ€ ์ž๊ธฐ ํ”„๋กœ์„ธ์Šค์˜ **์ž๊ธฐ import** ๋ฅผ ๋„ค์ดํ‹ฐ๋ธŒ - ๊ตฌํ˜„์— ๋ฌถ๋Š” ๊ฒƒ โ€” ๋ชจ๋“  PE ๋กœ๋”๊ฐ€ ํ•˜๋Š” **๋กœ๋”ฉ**์ด์ง€ ์šฐํšŒ๊ฐ€ ์•„๋‹ˆ๋‹ค. kernel32 ๋Š” OS - API ํ‘œ๋ฉด์ด์ง€ ๋ณดํ˜ธ์žฅ์น˜(DRM/Warden/anti-cheat)๊ฐ€ ์•„๋‹ˆ๋ฉฐ, ๋ณธ ํ”„๋กค๋กœ๊ทธ ํ˜ธ์ถœ์€ CRT - init ์ผ ๋ฟ ๋ณดํ˜ธ์™€ ๋ฌด๊ด€. `validated_manjeom` ์€ ์—ฌ์ „ํžˆ **0**(์ด๊ฒƒ์€ ๋กœ๋” ์ง„์ฒ™์ด์ง€ - ๋ Œ๋”๋œ ํ”„๋ ˆ์ž„์ด ์•„๋‹ˆ๋‹ค). ๋‹ค์Œ r5: ๋‘ ๋ฒˆ์งธ import(๋ฏธ๋“ฑ๋ก slot 0x538004) ๋ฐ”์ธ๋”ฉ + - ๋ฒ„ํผ-์“ฐ๊ธฐํ˜• ์…ฐ์ž„(GetSystemTimeAsFileTime/QueryPerformanceCounter) + 0xC1 shift - group ๋””์ฝ”๋” ๊ฐญ. - -### Fixed - -- test(purple cond.3): 2FA TOTP state machine ์˜ **window-drift / RFC 6238 ยง5.2 ยฑ1 - resync leg** gap ์ข…๊ฒฐ โ€” `c_purple_2fa_totp_proxy.hexa` ๋Š” `window_idx`(=unix_time/30) - ๋ฅผ device ๋ณ„๋กœ ๊ธฐ๋กํ•˜์ง€๋งŒ, ํ•ฉ์„ฑ ์‹œ๋‚˜๋ฆฌ์˜ค๋Š” ๊ฑฐ์˜ ๋™์ผํ•œ window(58000000/58000001)๋งŒ - ์จ์„œ **๋™์ผ device ๊ฐ€ clock drift ๋กœ ์ธ์ ‘ window(N, N+1)์— ๊ฑธ์ณ ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑ** ํ•˜๋Š” - documented-but-unmodeled ์ถ•(RFC 6238 ยง5.2 โ€” ์„œ๋ฒ„ ยฑ1 resync window ์ˆ˜์šฉ)์„ ํ•œ ๋ฒˆ๋„ - ํ–‰์‚ฌํ•˜์ง€ ์•Š์•˜๋‹ค. ํ•ฉ์„ฑ ํ–‰ `record_totp(5004, 860, 58000010, 6)` + - `record_totp(5004, 870, 58000011, 6)`(์ธ์ ‘ window) ์ถ”๊ฐ€๋กœ drift transition ์„ - ํ–‰์‚ฌํ•˜๊ณ , ํ—ฌํผ `count_by_window(idx)`(r1 ์˜ `count_by_stage` ๊ฑฐ์šธ) + - `device_window_span(device_id)`(maxโˆ’min window = ยฑ1 resync ์ •๋Ÿ‰) ์ถ”๊ฐ€, ์˜์กด - assertion ์ „๋ถ€ ๋‚ด๋ถ€์ •ํ•ฉ ๊ฐฑ์‹ (totp_count 3โ†’5, total_hmac_us 2550โ†’4280, avg_hmac_us - 850โ†’856, valid_code_len 2โ†’4, stats[0..3] ๋™์ผ ๊ฐฑ์‹ , emit โ‰ฅ4โ†’โ‰ฅ7) + ์ƒˆ emit ๋งˆ์ปค - `totp_window_drift`(span=1, resync=accepted_pm1) ๋ฐœ์‹ . CI 8ํŒŒ์ผ ์ค‘ - `test_purple_lineage_offline_shim.hexa` ์— `check_purple_cond3_totp_drift()` - ์ถ”๊ฐ€(grep ๋งˆ์ปค + live `out.contains("drift_span=1")`) + `track_b_purple_cond3_totp_drift` - emit ๋ฐฐ์„ (test emit โ‰ฅ6โ†’โ‰ฅ7) โ†’ ๋ณ€๊ฒฝ์ด dead ๊ฐ€ ์•„๋‹ˆ๋ผ CI ๊ฒ€์ฆ๋จ. **cond.3 status ๋Š” - partial ์œ ์ง€**(purple_launcher.blk.1 โ€” plaync online endpoint network-gated). own1: - ํ•ฉ์„ฑ ๋ฐ์ดํ„ฐ๋งŒ, ์‹ค์ œ plaync account/network/TOTP secret 0๊ฑด, **GameGuard - blocked-not-bypassed**. -- fix(ci): CI ๊ฐ€ **์•„๋ฌด๊ฒƒ๋„ ๊ฒ€์ฆํ•˜์ง€ ์•Š๋˜** ๊ณตํ—ˆ ํ†ต๊ณผ๋ฅผ root-cause ๊ต์ • โ€” - 8 ํ…Œ์ŠคํŠธ ํŒŒ์ผ์€ ์ „๋ถ€ `fn self_test()` + `main()` dispatch(own2 mandate)์ด๊ณ  - `@test` fn ์€ 0๊ฐœ์ธ๋ฐ, CI ๊ฐ€ `hexa test `(=@test ๋Ÿฌ๋„ˆ)์„ ์จ์„œ 0๊ฐœ ์‹คํ–‰ โ†’ - ๋ฌด์กฐ๊ฑด green ์ด์—ˆ๋‹ค. `hexa run self-test`(mainโ†’self_test dispatch)๋กœ - ๊ต์ • โ†’ 8 self_test ๊ฐ€ ๋น„๋กœ์†Œ ์‹ค์ œ ์‹คํ–‰ยท๊ฒ€์ฆ๋œ๋‹ค. (๋กœ์ปฌ ์‹ค์ธก: `hexa test` ๋Š” - ๋ฌด์ถœ๋ ฅ/ํ–‰, `hexa run self-test` ๋Š” own2 PASS ๋ผ์ธ ์ถœ๋ ฅ.) -- test(battlenet cond.3): `test_d2r_archive_round_trip` ์— - `check_battlenet_cond_3_oauth()` ์ถ”๊ฐ€ โ€” OAuth2 6 op_kind(ํŠนํžˆ device_code_grant) - emit ๋งˆ์ปค๋ฅผ skeleton-validate(live + grep fallback). cond.3 deepening ์ด CI 8ํŒŒ์ผ - ๋ฃจํ”„์—์„œ ์‹ค์ œ ๊ฒ€์ฆ๋˜๋„๋ก ๋ฐฐ์„ (wire-to-prod). cond.3 status ๋Š” partial ์œ ์ง€. -- test(purple cond.3): plaync OAuth state machine ์˜ **token_refresh-FAIL leg** gap ์ข…๊ฒฐ โ€” - `c_purple_plaync_oauth_proxy.hexa` self_test ๋Š” stage=3(token_refresh) ์„ `success=1` - (refresh OK) ์œผ๋กœ๋งŒ ํ–‰์‚ฌํ–ˆ์œผ๋‚˜, header line 6(token_refresh stage) + line 29(success=0 - ์‚ฌ์œ  "token ๋งŒ๋ฃŒ")๊ฐ€ DOCUMENT ํ•œ **refresh_token ๋งŒ๋ฃŒ โ†’ ์žฌ๋กœ๊ทธ์ธ(stage=3 success=0)** - leg ๋Š” MISSING ์ด์—ˆ๋‹ค. ํ•ฉ์„ฑ ํ–‰ `record_oauth(4004, 3, 90000, 0)` ์ถ”๊ฐ€๋กœ ํ–‰์‚ฌํ•˜๊ณ  - ์˜์กด assertion ์ „๋ถ€ ๋‚ด๋ถ€์ •ํ•ฉ ๊ฐฑ์‹ (oauth_count 4โ†’5, fail_count 1โ†’2, total_us - 740000โ†’830000, count_by_stage(3) 1โ†’2, ppop_stats[2] 740000โ†’830000, emit โ‰ฅ5โ†’โ‰ฅ7) + - ์ƒˆ emit ๋งˆ์ปค `plaync_oauth_refresh_fail` ๋ฐœ์‹ . CI 8ํŒŒ์ผ ์ค‘ - `test_purple_lineage_offline_shim.hexa` ์— `check_purple_cond3_oauth_refresh_fail()` - ์ถ”๊ฐ€(grep ๋งˆ์ปค + live `out.contains("refresh_fail=1")`) + `track_b_purple_cond3` emit - ๋ฐฐ์„  โ†’ ๋ณ€๊ฒฝ์ด dead ๊ฐ€ ์•„๋‹ˆ๋ผ CI ๊ฒ€์ฆ๋จ. **cond.3 status ๋Š” partial ์œ ์ง€** - (purple_launcher.blk.1 โ€” plaync online endpoint network-gated). own1: ํ•ฉ์„ฑ ๋ฐ์ดํ„ฐ๋งŒ, - ์‹ค์ œ plaync account/network/token 0๊ฑด, **GameGuard blocked-not-bypassed**. -- test(battlenet cond.3): `test_d2r_archive_round_trip` ์— - `check_battlenet_cond_3_state_machines()` ์ถ”๊ฐ€ โ€” cond.3 4๊ฐœ ๋ชจ๋“ˆ ์ค‘ ๊ทธ๋™์•ˆ - `pe_battle_net_oauth_token` ํ•˜๋‚˜๋งŒ CI-pin ๋˜์–ด ์žˆ์—ˆ๊ณ , ๋‚˜๋จธ์ง€ 3๊ฐœ perf ๋ชจ๋“ˆ์˜ - synthetic ์ƒํƒœ๊ธฐ๊ณ„ ๋งˆ์ปค(`__BNET_LOGIN__ PARTIAL โ€ฆ` / `__BNET_TOKEN__ PARTIAL โ€ฆ` / - `__BNET_CHAT__ PARTIAL โ€ฆ`)๋Š” **๊ฐ ๋ชจ๋“ˆ ์ž์ฒด self_test ์•ˆ์—์„œ๋งŒ** ์‹คํ–‰๋  ๋ฟ 8 CI - `[test].files` ์–ด๋””์„œ๋„ grep/๊ฒ€์ฆ๋˜์ง€ ์•Š๋˜ "CI-dead" ๊ฐญ์„ ๋‹ซ์Œ. ์„ธ ๋ชจ๋“ˆ์˜ ์ข…๋‹จ - ์ƒํƒœ(`TOKEN_EXPIRY` / `REFRESH_FAIL_RETRY` / `OFFLINE`)๋ฅผ live self_test + grep - fallback ์œผ๋กœ skeleton-validate โ†’ login_state / token_refresh / chat_presence - ์ƒํƒœ๊ธฐ๊ณ„๊ฐ€ CI ์—์„œ ์‹ค์ œ ๊ฒ€์ฆ๋œ๋‹ค. ๊ฐ ๋ชจ๋“ˆ self_test ์˜ ๋ฌธ์„œํ™”๋œ ์ƒํƒœ(login 5, - token 5, chat 4)๋Š” ์ด๋ฏธ ์ „๋ถ€ exercise ๋˜์–ด ์žˆ์–ด(self_test ์ถ• ๊ณ ๊ฐˆ) ๋ชจ๋“ˆ ์ž์ฒด๋Š” - ๋ฌด๋ณ€๊ฒฝ โ€” ๊ฐญ์€ CI-๊ฒ€์ฆ ๋ถ€์žฌ์˜€๋‹ค. own1: ์‹ค OAuth endpoint 0 / ์‹ค XMPP 0 / socket 0 / - network 0. cond.3 status ๋Š” partial ์œ ์ง€(network-gated = blk.1, ์ •์ง). - -### Added - -- feat(F-NSWINDOW-E5): i386 **์ธํ„ฐํ”„๋ฆฌํ„ฐ** ์ตœ์ดˆ ๋„์ž… โ€” ๋””์ฝ”๋“œ๋งŒ ํ•˜๋˜ E2 ๋ฅผ ๋„˜์–ด - ์‹ค์ œ Win32 ๊ฒŒ์ž„ ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ”์ดํŠธ๋ฅผ **์‹คํ–‰**(์ƒํƒœ ๋ณ€์ด)ํ•œ๋‹ค. `native/i386_cpu.{c,h}` - = ๋ ˆ์ง€์Šคํ„ฐ ํŒŒ์ผ(`gpr[8]`/eip/eflags, esp=gpr[4]) + ํ”Œ๋žซ VAโ†’host ๋ฉ”๋ชจ๋ฆฌ ๋ชจ๋ธ - (`mem_read32`/`mem_write32`, ๊ฒฝ๊ณ„๊ฒ€์‚ฌ) + fetchโ†’decodeโ†’**execute**โ†’advance ๋ฃจํ”„. - ์‹คํ–‰ op: PUSH_R / POP_R / PUSH_IMM / PUSH_RM([reg+disp]) / MOV_R_RM(8B) / - MOV_RM_R(89) / CALL_REL(E8) / JMP_REL(E9ยทEB) / RET(C3ยทC2). ๋ฏธ์ปค๋ฒ„ opcode ๋Š” - `I386_OP_UNKNOWN` ์œผ๋กœ **์ •์งํ•˜๊ฒŒ halt**(wall VA ๊ธฐ๋ก). ๋ถ„๊ธฐ ํƒ€๊นƒ์€ ๋””์Šค์–ด์…ˆ๋ธ”๋Ÿฌ์™€ - ๋™์ผํ•œ `eip+len+imm` ๊ณต์‹ ์žฌ์‚ฌ์šฉ. own1: ํ”„๋กœ๊ทธ๋žจ ์ž๊ธฐ ๋ฐ”์ดํŠธ + Intel SDM ์˜๋ฏธ๋ก ๋งŒ, - Wine/CrossOver/Box86/QEMU/ReactOS ์†Œ์Šค 0. -- test(F-NSWINDOW-E5): `native/i386_cpu_test.c` โ€” Battle.net-Setup.exe ์˜ ์‹ค์ œ - 9-insn ์—”ํŠธ๋ฆฌ ๋ธ”๋ก(entry_va 0x5388A6) ์„ hermetic ํ”Œ๋žซ ์ด๋ฏธ์ง€์— ๋ฐ•์•„ CI ์—์„œ - ๋ฐ”์ด๋„ˆ๋ฆฌ ์—†์ด ์‹คํ–‰(ํŒŒ์ผ ์ธ์ž ์ฃผ๋ฉด ์‹ค PE ๋„ ๋กœ๋“œยท์‹คํ–‰). ์‹ค์ธก(๋กœ์ปฌ clang ๋นŒ๋“œ, - 19/19 [ok], `__SHIM_TEST__ PASS`): Run A(์—”ํŠธ๋ฆฌ์—์„œ ์‹คํ–‰) โ†’ CALL_REL 1๊ฐœ ์‹คํ–‰, - ๋ฆฌํ„ด์ฃผ์†Œ 0x5388AB push, eip=์‹คํƒ€๊นƒ 0x539259 ๋กœ ๋ถ„๊ธฐ ํ›„ ๋””์ฝ”๋” ์ปค๋ฒ„๋ฆฌ์ง€ wall ์—์„œ - halt โ†’ `__SHIM__ PARTIAL phase=entry_block_executed insns=1 halted=unknown halt_va=0x539259`. - Run B(push/mov/push-rm), Run C(pop/pop/ret), Run D(jmp) ๊ฐ€ PUSH_RยทMOV_R_RMยท - PUSH_RMยทPOP_RยทRETยทJMP_REL ์˜๋ฏธ๋ก ์„ ์‹ค ๋ฐ”์ดํŠธ๋กœ ๊ฒ€์ฆ. `native/build.sh` ์— - `i386_cpu_test` ํƒ€๊นƒ ๋“ฑ๋ก(clang arm64 + ad-hoc codesign, ๊ธฐ์กด ๋นŒ๋“œ ์žฌ์‚ฌ์šฉ). - โ†’ **๊ฒŒ์ž„ ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ”์ดํŠธ ์ตœ์ดˆ ์‹ค EXECUTION ๋งˆ์ผ์Šคํ†ค**. ๋‹ค์Œ wall(r3): VA 0x539259 - (`__scrt_common_main` ํ”„๋กค๋กœ๊ทธ)์˜ ์ฒซ ๋ฏธ์ปค๋ฒ„ opcode โ€” group-1 imm arith(0x83/0x81/ - 0x80)ยทmov r/m imm(0xC7/0xC6)ยทbyte mov(0x88/0x8A)ยทtest(0x84)ยทand/or(0x09/0x0B/ - 0x21/0x23) ๋””์ฝ”๋” ์ปค๋ฒ„๋ฆฌ์ง€ ํ™•์žฅ ๋Œ€์ƒ. -- feat(F-NSWINDOW-E5 r3): r2 ์˜ **1-instruction wall(0x539259) ๋ŒํŒŒ** โ€” ๋””์ฝ”๋”+ - ์ธํ„ฐํ”„๋ฆฌํ„ฐ๋ฅผ `__scrt_common_main` ํ”„๋กค๋กœ๊ทธ opcode ์ง‘ํ•ฉ์œผ๋กœ ํ™•์žฅ. `native/i386_decode.{c,h}` - ์— group-1 r/m,imm(0x80/0x81/0x83 โ€” add/or/adc/sbb/and/sub/xor/cmp by ModR/M.reg)ยท - mov r/m,imm(0xC7 /0 id, 0xC6 /0 ib)ยทbyte mov+test(0x88/0x8A/0x84)ยทand/or(0x09/0x0B/ - 0x21/0x23) ๋””์ฝ”๋“œ(op enum 32..49 ๋ง๋ฏธ ์ถ”๊ฐ€ โ€” ๊ธฐ์กด 0..31 ordinal ๋ถˆ๋ณ€). `native/i386_cpu.{c,h}` - ์— **EFLAGS ๋ชจ๋ธ**(CF/PF/AF/ZF/SF/OF โ€” SDM ADD/SUB/CMP/logic ์ •ํ™•) + `alu_add`/ - `alu_sub`/`alu_logic` + r/m32 read/write ํ—ฌํผ ์ถ”๊ฐ€, ์‹คํ–‰ op ํ™•์žฅ: MOV_R_IMM(B8+)ยท - MOV_RM_IMM(C7)ยทLEA(8D)ยทINC/DEC r(40+/48+, CF ๋ณด์กด)ยทALU r/m,r+r,r/m(ADD/SUB/CMP/ - XOR/OR/AND/TEST)ยทgroup-1 imm(81/83). byte-width ํ˜•(80/C6/88/8A/84)์€ ๋””์ฝ”๋“œ๋˜๋˜ - ํญ ๋ฏธ๋ชจ๋ธ โ†’ **์ •์ง UNSUPPORTED**. ๊ฐ„์ ‘ IAT CALL(FF /2 [disp32])์€ ๋””์ฝ”๋“œ(CALL_RM) - ๋˜๋˜ **์˜๋„์ ์œผ๋กœ ๋ฏธ์‹คํ–‰** = E4 kernel32 ๊ฒฝ๊ณ„(own1: IAT ํ•ด์„/DRM ์ƒํ˜ธ์ž‘์šฉ 0). -- test(F-NSWINDOW-E5 r3): `native/i386_cpu_test.c` Run A ๊ฐ€ ์ด์ œ ์—”ํŠธ๋ฆฌ CALL ํ›„ - 0x539259 ์˜ `__scrt_common_main` ํ”„๋กค๋กœ๊ทธ(own1: named-family ๋กœ ์ง  ๋ฌธ์„œํ™”๋œ SHAPE โ€” - ์‹ค ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ถ€์žฌ ํ˜ธ์ŠคํŠธ, SDM-์ •ํ™• ์ž๊ธฐ ๋ฐ”์ดํŠธ)๋ฅผ **8๊ฐœ ์ถ”๊ฐ€ ์‹คํ–‰**ํ•˜๊ณ  ์ฒซ ๊ฐ„์ ‘ - IAT CALL ์—์„œ ๋ฉˆ์ถ˜๋‹ค. **์‹ค์ธก(๋กœ์ปฌ clang, 20/20 [ok], `__SHIM_TEST__ PASS`)**: - `__SHIM__ PARTIAL phase=scrt_common_main_prologue insns=9 halted=unsupported halt_va=0x539274 halt_op=call` - โ€” r2 `insns=1 halt@0x539259` โ†’ r3 `insns=9 halt@0x539274`(reason=UNSUPPORTED=CALL_RM, - E4 ๊ฒฝ๊ณ„). hermetic sentinel(0x538BABยท0x53872A)์€ ์•„์ง-๋ฏธ์ปค๋ฒ„ 0xC1(shift group-2, - ๋‹ค์Œ r4 ๋””์ฝ”๋” ๊ฐญ)์œผ๋กœ ๊ต์ฒด โ†’ Run B/D ๋Š” ๊ณ„์† UNKNOWN wall ์—์„œ ์ •์ง halt. .hexa - ํŠธ์œˆ(`native/i386_decode.hexa`) ๋™์ผ ๋ฏธ๋Ÿฌ โ†’ **RUNEQ M4 1042/1042 + M3 byte-equal - (๋กœ์ปฌ ์‹ค์ธก green)**, hexa self_test PASS. own1: ์ž๊ธฐ ๋ฐ”์ดํŠธ + Intel SDM ์˜๋ฏธ๋ก ๋งŒ, - Wine/QEMU/Box86/ReactOS 0, IAT/DRM/Warden ์ƒํ˜ธ์ž‘์šฉ 0. `validated_manjeom` ์€ ์—ฌ์ „ํžˆ - **0**(์‹ค ๊ฒŒ์ž„ ํ”„๋ ˆ์ž„ ์•„๋‹˜ โ€” E3 ์ธํ„ฐํ”„๋ฆฌํ„ฐ ์ „์ง„์ด์ง€ ํ”„๋ ˆ์ž„ ์ฆ๊ฑฐ ์•„๋‹˜). ๋‹ค์Œ wall(r4): - shift group-2(0xC1/0xD1/0xD3)ยทgroup-3(0xF7 test/neg/mul/div) ๋””์ฝ”๋” ํ™•์žฅ, ๋˜๋Š” - ์ฒซ ์กฐ๊ฑด๋ถ„๊ธฐ(Jcc) EFLAGS ์†Œ๋น„, ๋˜๋Š” E4 = ๊ฐ„์ ‘ IAT CALL ์‹คํ–‰(kernel32 stub ๋ฐ”์ธ๋”ฉ) ๊ฒฝ๊ณ„. -- feat(battlenet cond.3): `pe_battle_net_oauth_token` self_test ๊ฐ€ op_kind 6 - `device_code_grant`(`/oauth/device` RFC8628) ์„ ๋น„๋กœ์†Œ exercise โ€” ํ—ค๋”์— - ๋ฌธ์„œํ™”๋์œผ๋‚˜ self_test ๋ฏธ์ปค๋ฒ„์˜€๋˜ ๊ฐญ์„ ๋‹ซ์Œ(6 op_kind ์ „๋ถ€ round-trip). ํ•ฉ์„ฑ - ๋ฐ์ดํ„ฐยทtoken ์‹ค๊ฐ’ 0ยทlength-onlyยท์‹ค ๋„คํŠธ์›Œํฌ 0(own1 ์ค€์ˆ˜). ์–ด์„œ์…˜ ์ •ํ•ฉ: - op_count 6โ†’7, total_token_lifetime_sec 345600โ†’432000, total_token_size_bytes - 5120โ†’6144, count_by_op_kind(6) 0โ†’1, stats `[7,432000,6144,2]`, emit โ‰ฅ8. - cond.3 status ๋Š” partial ์œ ์ง€(์‹ค OAuth ์—”๋“œํฌ์ธํŠธ network smoke ๊ฒŒ์ดํŠธ = blk.1). - -- docs(CLAUDE.md): CI(Blacksmith) ๊ทœ์œจ ๋ฐ•์ œ โ€” `## CI โ€” builds run on Blacksmith, - NOT locally` ์„น์…˜ ์ถ”๊ฐ€(์›Œํฌํ”Œ๋กœ/๋Ÿฌ๋„ˆ/ํˆด์ฒด์ธ/์‹คํ–‰ ๋‚ด์šฉ + "๋กœ์ปฌ ๋นŒ๋“œ ๋ง๊ณ  push - ํ•˜๋ผ" ๊ทœ์น™) + Structure ํŠธ๋ฆฌ์— `.github/workflows/` ํ•ญ๋ชฉ. ๊ฐ™์€ ๊ฒฐํ•จ(๋กœ์ปฌ ๋นŒ๋“œ๋กœ - Mac ์ฃฝ์Œ) ์žฌ๋ฐœ ๋ฐฉ์ง€๋ฅผ ์œ„ํ•ด ๊ฑฐ๋ฒ„๋„Œ์Šค SSOT ์— ๋ช…์‹œ. - - -- ci(blacksmith): `.github/workflows/ci.yml` โ€” gamebox ๋นŒ๋“œ+ํ…Œ์ŠคํŠธ๋ฅผ - Blacksmith ํด๋ผ์šฐ๋“œ Apple-Silicon ๋Ÿฌ๋„ˆ(`blacksmith-6vcpu-macos-15`)์—์„œ ์‹คํ–‰. - gamebox ๋Š” Apple-native(Win32 PE + D3DMetal)๋ผ ์ปดํŒŒ์ผ+apple-only ํ…Œ์ŠคํŠธ์— - macOS ํ˜ธ์ŠคํŠธ๊ฐ€ ํ•„์š”ํ•œ๋ฐ, ๊ทธ๊ฑธ ๋กœ์ปฌ dev Mac ์—์„œ ๋Œ๋ฆฌ๋ฉด 242+ perf ๋ชจ๋“ˆ + - 8 ํ…Œ์ŠคํŠธ๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ŠคํŒŒ์ดํฌํ•ด ๋จธ์‹ ์ด ์ฃฝ์—ˆ๋‹ค. ์ด์ œ push ๋งˆ๋‹ค ํด๋ผ์šฐ๋“œ Mac ์ด - ๋นŒ๋“œ/ํ…Œ์ŠคํŠธ๋ฅผ ๋งก๊ณ  ๋กœ์ปฌ ๋ฐ•์Šค๋Š” `git push` ๋งŒ ํ•œ๋‹ค. ๋Ÿฌ๋„ˆ๋Š” macos-15 ํ•€ - (hexa-lang `release.yml` ์™€ ๋™์ผ ๊ทผ๊ฑฐ โ€” SDK min-OS ๋ฒ ์ด์Šค๋ผ์ธ ์•ˆ์ •). hexa - ํˆด์ฒด์ธ์€ ๋ฆด๋ฆฌ์Šค ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ canonical ์„ค์น˜ ํ•œ ์ค„(`install.sh`)๋กœ ๊น๋‹ค. D3DMetal - SDK ๋ถ€์žฌ๋Š” warn-only(skeleton-tier ๋กœ๋”๋Š” importable). same-org ๋ผ - Blacksmith ํ™œ์„ฑํ™” ๋ณ„๋„ ์ž‘์—… ๋ถˆํ•„์š”(hexa-lang ์ด ์ด๋ฏธ ์‚ฌ์šฉ). - -### Changed - -- docs(architecture): restructure `ARCHITECTURE.json` into a deeper `children` - tree per harness governance rule c4 โ€” a LOSSLESS re-shape (restructure only, - no content change). Decomposed 10 over-long dump cells (root `summary` 527c + - root `note` 731c + 8 node `summary` fields 263โ€“531c) that piled multiple - distinct facts / ` ยท `-joined lists into one field. Each piled fact is now its - own child node (short role line stays on the parent `summary`; each remaining - sentence/list becomes a `{name, summary}` `โ„น๏ธ` info child). Node count - 26 โ†’ 47. The two C-PORT milestones >250c are single coherent done-records - (`milestones[]` is already the per-item list) and stay intact โ€” not dumps. - Losslessness verified by non-whitespace char-multiset before vs after = - identical (0 lost / 0 added; only scaffolding node-name labels added). - `ARCHITECTURE.html` viewer + `python3 serve.py` stay renderable (generic over - the `children` tree; new nodes use only `name`+`summary`). - -- chore(architecture): retire `DOMAINS.tape` + `domains/` (22 domain `.md` - snapshots + 22 `.log.md` logs) into a single `ARCHITECTURE.json` tree SSOT - (hexa-codex/anima pattern), with the `ARCHITECTURE.html` viewer + - `python3 serve.py` static server (copied + adapted from `dancinlab/anima`). - Each domain's `@goal` โ†’ node `summary`, its `- [ ]/[x]` milestones โ†’ - `milestones[]`, and the DOMAINS.tape `@link` edges โ†’ per-node `edges[]` - (`--has-->` tree + `--uses-->`/`--targets-->` cross-edges preserved). Tree = - 22 domains (1 meta-root GAMEBOX + 6 ๋ฉ”์ธ๊ตฌ์กฐ LOADER/WIN32/GFX/NET/PERF/NATIVE + - C-PORT nested under NATIVE + 2 ๋Ÿฐ์ฒ˜ BNET/PURPLE + 1 sprint-meta LAUNCHPAD+ + - 11 ๊ฒŒ์ž„), grouped under 4 section headers โ†’ 26 JSON nodes. `ARCHITECTURE.md` - stays as the component-level prose SSOT and now points to the JSON tree. - `native/i386_decode.hexa` C-PORT cross-link repointed from `domains/C-PORT.md` - โ†’ the C-PORT node in `ARCHITECTURE.json` (provenance string left intact). - Full per-domain `.log.md` history is recoverable via git log; the substantive - entries folded below. - - Domain-log digest (folded from `domains/*.log.md`): - - All 22 domains scaffolded 2026-05-31 (domain init, seeded from the gamebox - ์ „์ˆ˜์กฐ์‚ฌ โ€” @goal + milestones from `.roadmap.*` + repo survey of - lib/loader ยท lib/perf ยท native). - - **C-PORT** (2026-06-03): M1 inventory+classify (4 native/*.c, 869 LOC; - Tier-A 437 ยท Tier-B 113 ยท Tier-C 319) โ†’ M2 decode_modrm_disp port - (RUNEQ 768/768, sha256 b4388479) โ†’ M3 decode_prefixes + i386_op_name + - rd_s32/rd_s16 (RUNEQ 1069/1069, sha256 8e6acbb8) โ†’ M4 stateful - i386_decode_one (RUNEQ 1042/1042, sha256 b2853d0a). Both M2 and M4 caught a - real write-before-fail out-param divergence, fixed โ†’ byte-identical. - - **GAMEBOX-D2R**: prerequisite @uses edges wired (LOADER/WIN32/GFX/NET + - BNET); reconciled 3/4 โ€” D3D11/MPQ/D2S code present + offline/online - checkpoints landed; gameplay-tracks (26 c_d2r_*) left open. - - **GAMEBOX-BNET**: reconciled 5/6 โ€” 10 pe_battle(_)net_* + orchestrator - present, D2R offline+online checkpoints prove the path; D2R non-blocking; - D4/CS2 launch extension open. - - **GAMEBOX-PURPLE**: reconciled 4/4 โ€” 7 c_purple_* + Lineage M/W purple play - checkpoints; scope = M/W; Classic depends on PURPLE for download only. - - **GAMEBOX-LINEAGE-CLASSIC**: wired LOADER/WIN32/GFX @uses; reconciled 3/4 - (r28 loader + native first-frame + play checkpoint + drift-resolution track - bv); two corrections recorded โ€” PURPLE is the download channel (runtime - native, "no Purple shell"), and Classic is an ONLINE MMO (not offline); - playable gate = GameGuard (INCA) kernel AC honest-freeze. - - **GAMEBOX-LAUNCHPAD+**: meta-domain init (`+` composition) targeting D2R + - LINEAGE-CLASSIC; @has + @targets edges wired; shared "playable" smoke bar - (bootโ†’titleโ†’charโ†’in-world) defined with online/anti-cheat honest-freeze. - -### Removed - -- `DOMAINS.tape` (domain roster + tree graph) โ€” superseded by - `ARCHITECTURE.json` (`meta` + per-node `edges[]`). -- `domains/` (22 `*.md` domain snapshots + 22 `*.log.md` logs) โ€” `*.md` folded - into `ARCHITECTURE.json` nodes; `*.log.md` digested into the entry above - (full text recoverable via git log). - -- chore(harness): perfect harness setup โ€” engine submodule bumped to latest on - `harness-hardcore`; authored `ARCHITECTURE.md` SSOT (overview + component map + - data flow + governance/verify, English) over the stub; authored harness-standard - `CLAUDE.md` (H1 + blurb + `## Structure` tree + governance + `## Harness` + - quick reference) over the SPECKIT stub; added a `docs` discipline block to - `harness.config.json` (`architecture`/`log`/`scratchDir` + `scopeDirs: [""]` - root-only + `allow` list covering README/CHANGELOG/ARCHITECTURE/CLAUDE/AGENTS - plus `RELEASE_NOTES_v1.0.*` and `TAPE-AUDIT.md`). `harness docs check` now - reports `docs: ok` with 0 CLAUDE-MD violations. `.claude/settings.json` already - carried the full guarded harness hook set (pre bash / pre write / post edit / - prompt / prefs ยท easy ยท recommend inject / SessionStart) โ€” preserved as-is. - -## [1.0.4] โ€” 2026-05-05 - -### Added - -- Track CK โ€” `docs/VAC_HONEST_FREEZE.md` mk1 narrative (Valve Anti-Cheat user-mode AC + Trusted Mode; resolves cs2.cond.3 deferred hook). -- Track CL โ€” `docs/EAC_KERNEL_HONEST_FREEZE.md` mk1 narrative (EAC kernel + anti-tamper class; 3-cross-class delta_force + elden_ring base+DLC + nightreign). -- Track CM โ€” Nightreign lib module fan-out at skeleton-tier: - - `lib/loader/pe_elden_ring_nightreign_specific_track.hexa` (216 LOC) - - `lib/perf/c_nightreign_co_op_session_init.hexa` (133 LOC) - - `lib/perf/c_nightreign_matchmaking_probe.hexa` (129 LOC) - - `lib/perf/c_nightreign_dx12_first_frame_co_op_variant.hexa` (131 LOC) - - Total 609 LOC; retired_intentional posture inherited from blk.1 + blk.2. -- Track CN โ€” `gamebox/doc/gamebox_hexa_interp_closure_perpetual_deferral_ack_track_cn_landed_2026_05_05.ai.md` (formally closes CJ ยง11 hook 4 as perpetually deferred; multi-year horizon). -- 4 NEW `gamebox_*` markers (CK + CL + CM + CN). -- 4 NEW `gamebox/doc/` handoff docs (CK + CL + CM + CN). - -### Changed - -- `hexa.toml` version: `1.0.3` โ†’ `1.0.4`. -- `README.md` Version badge: `version-1.0.3` โ†’ `version-1.0.4`. -- `.roadmap.elden_ring_nightreign`: `loader_count: 0 โ†’ 1`, `perf_count: 0 โ†’ 3`, NEW `loader_pattern` + `perf_pattern` + `ai_native_handoff_track_cm` fields, NEW comment header line 6 documenting Track CM skeleton-tier fan-out (Track BY documentation-only narrative line 5 preserved verbatim). - -### Cumulative deltas (v1.0.3 โ†’ v1.0.4) - -- gamebox-native markers: 15 โ†’ 19 -- Honest freeze docs: 3 โ†’ 5 (Track-E predecessor + CK + CL) -- lib/loader files: 455 โ†’ 456 (+1 nightreign loader) -- lib/perf files: 242 โ†’ 245 (+3 nightreign perf) -- Forensic verdict: UNCHANGED (`SKELETON_TIER_100PCT_WIN32_VALIDATED_MANJEOM_0`) -- validated_manjeom: UNCHANGED (0 โ€” skeleton-tier per Track BL/BM forensic baseline) - -### Posture - -- own1: Wine 0 / hexa-only / no DRM bypass / no AC bypass (5 classes covered: VAC + GameGuard + EAC kernel + EAC anti-tamper + Warden) / no FromSoft matchmaking bypass / no anima clone / `destructive_ops: 0` (maintained). -- own2: 4 CM modules emit RETIRED_INTENTIONAL posture annotation; CN explicit no-fake-PASS / no-fake-real-run-completion declaration; skeleton-tier vs real-tier distinction explicit; spec freeze ONLY scope explicit per CK + CL. - -## [1.0.3] โ€” 2026-05-05 - -### Added - -- Track CE โ€” `gamebox/doc/gamebox_closure_orchestrator_selftest_paper_mode_track_ce_landed_2026_05_05.ai.md` (S1-S11 paper-mode trace; BZ ยง11 hook partial resolution). -- Track CF โ€” `gamebox/doc/gamebox_hexa_toml_modules_audit_track_cf_landed_2026_05_05.ai.md` (40 entries audit; 1 drift item flagged for CG). -- Track CG โ€” `gamebox/doc/gamebox_c_d2r_archive_round_trip_drift_fix_track_cg_landed_2026_05_05.ai.md` (orphan reference option-b removal). -- Track CH โ€” `gamebox/doc/gamebox_session_aggregate_v3_track_ch_landed_2026_05_05.ai.md` (first standalone-repo session aggregate covering BT-CG). -- hexa.toml `gamebox_perf_top_families` explanatory comment block (CG). -- 4 NEW `gamebox_*` markers (CE / CF / CG / CH). -- `.gitignore` pattern: `resource_op_[0-9]*.marker` (CE post-mortem). - -### Changed - -- `hexa.toml` version: `1.0.2` โ†’ `1.0.3`. -- `hexa.toml` `gamebox_perf_top_families`: orphan `c_d2r_archive_round_trip` entry removed (CG). -- `README.md` Version badge: `version-1.0.2` โ†’ `version-1.0.3`. -- `README.md` perf families table: `c_d2r_archive_round_trip` row removed (CG). - -### Cumulative deltas (v1.0.2 โ†’ v1.0.3) - -- gamebox-native markers: 9 โ†’ 15 (BT-CH) -- RFC 016 audit cumulative null floor: 28 โ†’ 34 cycles -- hexa.toml audit drift items: 1 โ†’ 0 -- Forensic verdict: UNCHANGED (`SKELETON_TIER_100PCT_WIN32_VALIDATED_MANJEOM_0`) -- validated_manjeom: UNCHANGED (0) - -### Posture - -- own1: Wine 0 / hexa-only / no DRM / no AC / no anima clone / `destructive_ops: 0` (CG was reference-removal not file-deletion). -- own2: paper-mode vs real-run distinction explicit; drift fix option chosen documented; v3 vs v1/v2 distinction explicit. - -## [1.0.2] โ€” 2026-05-05 - -### Added - -- **Layout migration** (`1d28b4c refactor(layout 2026-05-05)`): canonical `/doc/` layout โ€” `airgenome/doc/` (75 predecessor handoffs) + `gamebox/doc/` (9 native handoffs incl. CB-CC). -- Track BX โ€” per_game README ยง9 sections for 6 offline-relevant files (lineage_classic_r28 + d2r + battlenet + lineage_w + lineage_m + purple_launcher). -- Track BY โ€” README Game Coverage refresh: wow row removed (historical preserve), elden_ring DLC scope clarified (Shadow of the Erdtree 2024-06-21), elden_ring_nightreign added (2025-05-30 standalone multiplayer co-op spinoff, documentation-only fan-out). -- NEW `.roadmap.elden_ring_nightreign` (documentation-only, 0 lib modules at land-time). -- NEW `docs/per_game/elden_ring_nightreign_README.ai.md` T1 baseline. -- `dlc_scope` + `spinoff_cross_link` + `ai_native_handoff_track_by` fields on `.roadmap.elden_ring`. -- Track BZ โ€” `gamebox/doc/gamebox_closure_orchestrator_paper_invocation_track_bz_landed_2026_05_05.ai.md` (real-invocation attempt + paper-mode derivation; hexa interp blocker). -- Track CA โ€” `gamebox/doc/gamebox_hexa_upstream_rfc_016_reassessment_track_ca_landed_2026_05_05.ai.md` + `docs/HEXA_UPSTREAM_RFC_016_REASSESSMENT_TRACK_CA_2026_05_05.md` (28-cycle null floor reaffirmed). -- Track CB โ€” README "Native markers" + "Resolver telemetry markers (gitignored)" subsections. -- Track CC โ€” per_game README ยง9 sections for 4 retired_intentional files (cs2 + delta_force + diablo4 + elden_ring); elden_ring ยง9 surfaces DLC scope narrative. -- `.gitignore` patterns for hexa-resolver runtime telemetry markers. -- 8 NEW `gamebox_*` markers post-v1.0.0 (BT through CC). - -### Changed - -- README.md TL;DR header: `.roadmap` 14 โ†’ 15 (14 active + 1 historical), `.checkpoint` met 1 โ†’ 3. -- README.md architecture caption: terse 7-figure โ†’ detailed inventory (455 .hexa files, 9 tests, 88 markers across 3 classes). -- README.md Loaders heading: `(35 modules)` โ†’ `(59 named groups across 455 .hexa files)`. -- `.roadmap.elden_ring` goal: scope = base game + Shadow of the Erdtree DLC. -- `docs/airgenome_*.ai.md` (75) โ†’ `airgenome/doc/` per layout migration. -- `docs/gamebox_*.ai.md` (7) โ†’ `gamebox/doc/` per layout migration. -- `state/markers/*.marker` cross-references updated (193 files / 621 lines via sed sweep in `1d28b4c`). -- `hexa.toml` version: `1.0.1` โ†’ `1.0.2`. -- README version badge: `version-1.0.1` โ†’ `version-1.0.2`. - -### Posture - -- Forensic verdict UNCHANGED: `SKELETON_TIER_100PCT_WIN32_VALIDATED_MANJEOM_0`. -- `validated_manjeom` UNCHANGED: 0 (no real game frames). -- own1: Wine 0 / hexa-only / no DRM / no AC / no GameGuard / no EAC / no FromSoft matchmaking bypass / no anima clone / `destructive_ops: 0`. -- own2: honest emit; per_game ยง9 sections explicit about retired_intentional stable + cross-cutting impact + validated_manjeom carry. - -## [1.0.1] โ€” 2026-05-05 - -### Added - -- Track BU โ€” README "Game Coverage" section (+40 LOC; 11 .roadmap targets table + per-game index + 7 cross-roadmap checkpoint table + honest scope footer). -- Track BU โ€” `met_iso` / `met_via` / `evidence[]` fields on `.checkpoint.win32_50pct_coverage` + `.checkpoint.win32_full_coverage`. -- Track BV โ€” `met_iso` / `met_via` / `evidence[]` fields on `.checkpoint.lineage_classic_r28_play`. -- Track BV โ€” 9 NEW `status_flipped_*` fields across `.roadmap.lineage_classic_r28` cond.1/cond.2/cond.3. -- 4 NEW handoff docs + markers (BU + BV). - -### Changed - -- `.checkpoint.win32_50pct_coverage` status: `unmet 30.34/50` โ†’ `met 100/50` (BU). -- `.checkpoint.win32_full_coverage` status: `unmet 30.34/100` โ†’ `met 100/100` (BU). -- `.checkpoint.lineage_classic_r28_play` status: `partial 0/3` โ†’ `met 3/3` (BV, sideways-PASS). -- `.roadmap.lineage_classic_r28` cond.1/cond.2/cond.3 actual status: `partial` โ†’ `retired_intentional` (BV cascading flip). -- `hexa.toml` version: `1.0.0` โ†’ `1.0.1`. -- 3 checkpoint `blockers` arrays renamed `blockers_resolved` (verbatim list preserved). - -### Drift resolution - -- Track BO snapshot v2 drift_count: 3 โ†’ 0 (all 3 items resolved across BU + BV). - -### Posture - -- Forensic verdict UNCHANGED: `SKELETON_TIER_100PCT_WIN32_VALIDATED_MANJEOM_0`. -- `validated_manjeom` UNCHANGED: 0 (no real game frames evidenced). -- own1: Wine 0 / hexa-only / DRM bypass 0 / Warden bypass 0 / anti-cheat bypass 0 / GameGuard bypass 0 / anima clone 0. -- own2: PASS/FAIL/PARTIAL/RETIRED_INTENTIONAL emit honest; status flip rationale per checkpoint cited. - -## [1.0.0] โ€” 2026-05-05 - -### Initial extraction - -- **Forensic verdict**: `SKELETON_TIER_100PCT_WIN32_VALIDATED_MANJEOM_0` -- **Source**: `dancinlife/airgenome-gamebox` 67-cycle session (2026-05-03 to 2026-05-05; deleted 2026-05-05 per closure-cycle directive, history not transferred per D3 fresh-start policy) -- **Reference layout**: `dancinlab/sim-universe` v1.0.0 (sibling repo) - -### Inventory - -- 35 loader modules under `lib/loader/` (32 PE *_core + 5 runtime + 5 DX + 9 Battle.net + 6 calling-conv + 2 launchers; some overlap) - - 435/435 Win32 fn skeleton coverage (Track BP, 2026-05-05) -- 242 perf modules under `lib/perf/` across 104 unique families - - 18+ families at 100% manjeom (Track BL/BM forensic) -- 14 `.roadmap.*` files (mk2 SSOT) -- 7 `.checkpoint.*` files (mk2 checkpoint mechanism); 1 met: `win32_50pct_coverage` (Track BR derivation guard) -- 2 tools under `tool/` (`roadmap_op.hexa` 14-subcmd anima parity broken intentional + `closure_orchestrator.hexa` weighted_threshold awareness) -- 8 tests under `tests/` -- 75 predecessor markers under `state/markers/airgenome_gamebox_*.marker` (preserved verbatim per own2 traceability) -- 4 hexa-lang upstream RFCs merged (rfc_012/_013/_014 PR #47 + rfc_015 PR #48) - -### Posture - -- **own1**: Wine 0 / hexa-only / DRM bypass 0 / Warden bypass 0 / anti-cheat bypass 0 / anima clone 0 -- **own2**: PASS/FAIL emit honest, PARTIAL/RETIRED_INTENTIONAL emit explicit -- **L1-L5 online expansion lock-in carry** (EULA / Warden / multi-year / D2R-single / parallel) per `.roadmap.battlenet` -- **License**: Apache-2.0 diff --git a/CLAUDE.md b/CLAUDE.md index e49e9be..928796c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -7,7 +7,7 @@ Warden / anti-cheat bypass, no anima clone). The PEโ†’D3D11โ†’Metal pipeline is proven end-to-end with a self-authored own1 D3D11 PE (`validated_manjeom = first_own1_authored_d3d11_pe_to_metal_frame`, an infrastructure milestone) โ€” but **no commercial game frame is evidenced yet**. Full design lives in -[ARCHITECTURE.md](ARCHITECTURE.md); history in [CHANGELOG.md](CHANGELOG.md). +[ARCHITECTURE.md](ARCHITECTURE.md); history in [CHANGELOG.jsonl](CHANGELOG.jsonl). ## Structure @@ -30,7 +30,7 @@ gamebox/ โ”œโ”€ .checkpoint.* โ€” cross-roadmap forensic checkpoint snapshots โ”œโ”€ hexa.toml โ€” hx manifest (name, version, entry) โ”œโ”€ ARCHITECTURE.md โ€” architecture SSOT (update-in-place) -โ”œโ”€ CHANGELOG.md โ€” append-only history +โ”œโ”€ CHANGELOG.jsonl โ€” append-only history โ”œโ”€ harness.config.json โ€” harness config (lockdown, lint, docs discipline) โ”œโ”€ .github/workflows/ โ€” CI (ci.yml โ€” github-hosted macOS build+test) โ””โ”€ .harness-engine/ โ€” dancinlab harness submodule (governance engine) @@ -43,7 +43,7 @@ gamebox/ - **own2 honesty** โ€” subcommands emit explicit PASS/FAIL/PARTIAL reasons; predecessor markers preserved verbatim. - **Single-doc discipline** โ€” architecture goes to `ARCHITECTURE.md` (overwrite, - SSOT); history to `CHANGELOG.md` (append); transient output to + SSOT); history to `CHANGELOG.jsonl` (append); transient output to `scripts/scratch/`. Don't scatter `*-report.md` / dated notes at the repo root. - **Protected branches** โ€” `main` / `master`. Open a PR from a feature branch. diff --git a/README.md b/README.md index e3edd8b..795b953 100644 --- a/README.md +++ b/README.md @@ -399,7 +399,7 @@ SKELETON_TIER_WIN32 + E5_PIPELINE_PROVEN gamebox/ โ”œโ”€โ”€ README.md โ”œโ”€โ”€ LICENSE Apache-2.0 -โ”œโ”€โ”€ CHANGELOG.md +โ”œโ”€โ”€ CHANGELOG.jsonl โ”œโ”€โ”€ hexa.toml hx manifest (name, version, entry) โ”œโ”€โ”€ install.hexa hx build hook โ”œโ”€โ”€ cli/ diff --git a/harness.config.json b/harness.config.json index 7926db1..e9b8c8d 100644 --- a/harness.config.json +++ b/harness.config.json @@ -24,7 +24,7 @@ "lint": { "freshnessFiles": [], "changelog": { - "file": "CHANGELOG.md", + "file": "CHANGELOG.jsonl", "triggerPattern": "\\.(hexa)$", "ignore": [ "(^|/)(tests?|__tests__|spec)/", @@ -44,14 +44,14 @@ ], "docs": { "architecture": "ARCHITECTURE.md", - "log": "CHANGELOG.md", + "log": "CHANGELOG.jsonl", "scratchDir": "scripts/scratch", "scopeDirs": [ "" ], "allow": [ "README.md", - "CHANGELOG.md", + "CHANGELOG.jsonl", "ARCHITECTURE.md", "CLAUDE.md", "AGENTS.md",