{"kind":"hwanse-status-comment-producer-boundary-review","status":"comment-data-grounded-selector-source-grounded-writer-unproven","source":["out/status_comment_selector_binding_review.json","out/status_menu_ui_expression_review.json","out/status_menu_vm_table_review.json","tools/build_status_comment_producer_boundary_review.py"],"summary":{"surfaceCount":7,"confirmedDataSurfaceCount":3,"selectorArrayCount":9,"selectorArrayAllBlocksMatched":true,"commentGroupCount":9,"actorTableCount":21,"selectorProducerProven":false,"selectorSourceGrounded":true,"selectorProducerProbeStatus":"inline-vm-array-consumer-grounded-producer-pending","statusPayloadConsumerGrounded":true,"statusPayloadPromptCommandCount":2,"postSelectorActorBranchGrounded":true,"backingStoreGrounded":true,"backingStoreExactRefCount":6,"backingOffset0WriterProven":false,"decision":"상태창 짧은 문구의 9개 group, actor table, 0x004e8610 selector array는 확정됐다. 상태창 payload를 실행하는 0x2f consumer, 0x41b66d text/status control interpreter, 40 14 selector source, selector 뒤 actor-slot branch도 확인됐다. 0x004576d8 backing block의 저장/로드 구조도 확인됐다. 하지만 backing selector value offset +0을 쓰는 writer와 게임 내 의미는 아직 증명되지 않았다."},"surfaces":[{"surface":"short comment 40 13 01 text groups","promotion":"confirmed-text-groups","finding":"commentGroupCount=9; actorTableCount=21; commentBlockCount=9.","gap":"텍스트와 pointer group은 확정됐지만 현재 상황/시나리오 값 선택은 아니다."},{"surface":"inline selector array","promotion":"confirmed-inline-array / consumer-pending","finding":"array=0x004e8610; count=9; allBlocksMatched=True; order=['0x77', '0x78', '0x79', '0x7a', '0x7b', '0x7c', '0x7d', '0x7e', '0x7f'].","gap":"No direct x86 pointer reference to 0x004e8610 was found; the array is consumed as inline VM payload data."},{"surface":"producer probe","promotion":"negative-xref / VM-consumer-only","finding":"anchor refs=0; outside entry refs=0; status=inline-vm-array-consumer-grounded-producer-pending.","gap":"The selector payload/header/array has no normal x86 pointer refs. Each grounded status-comment block is referenced through the inline 0x004e8610 + index*4 array slot.  The missing producer is therefore the VM/status-window code that computes the selector index before reading this inline array, not another ordinary pointer table."},{"surface":"status/menu 0x40 VM table context","promotion":"confirmed-control-handlers / backing-byte-writer-pending","finding":"opcode14TableCount=4; opcode13TableCount=16; interpreter=0x0041b66d; handlerTable=0x0047f1d8.","gap":"40 14 selector source는 좁혀졌지만 source byte/word를 쓰는 writer와 게임 내 의미는 아직 별도 추적 대상이다."},{"surface":"status window payload relation","promotion":"status-window-core-and-payload-consumer-confirmed / selector-index-producer-unverified","finding":"status payload 0x004e842e..0x004e85fc; region 6; status status-window-expression-grounded-core; 0x2f payload commands=2.","gap":"상태창 payload 소비는 grounded. 남은 미확정은 payload 내부 0x004e8610 selector array의 index/entry를 고르는 producer다."},{"surface":"post-selector actor branch","promotion":"actor-slot-consumer-grounded / selector-group-producer-unverified","finding":"branch=0x004e8660; slots=[0, 1, 2]; grounded=True.","gap":"actor slot 0/1/2 branch는 보이지만, 9개 selector group 중 현재 group을 고르는 producer는 아직 없다."},{"surface":"0x004576d8 backing status block","promotion":"persistent-block-grounded / offset-0-writer-pending","finding":"block=0x004576d8 size=114; refs=6; actorRows=0x00457750 size=648; globalVars=0x0059db60 size=512.","gap":"block 저장/로드와 몇몇 offset writer는 grounded지만 selector source인 +0의 직접 writer/의미는 아직 미확정이다."}],"selectorBoundary":[{"surface":"status core payload","va":"0x004e842e..0x004e85fc","role":"region #6 상태창 본문 직접 draw payload","evidence":"40 2e actor numeric, 40 30 equipment-name, 40 24 portrait, 40 0e labels are decoded in status_menu_ui_expression_review.","producerMeaning":"short-comment selector producer가 아니라 상태창의 고정/actor-field 렌더 표면이다."},{"surface":"status payload consumers","va":"0x004e842e","role":"active-object command stream consumes region #6 payload","evidence":"refs=3; 0x2f payload commands=2; top stream=0x004ddc6c","producerMeaning":"payload 실행 경계는 확정됐지만, selector index 산출은 이 command의 operand가 아니라 payload 내부 VM 처리에 남는다."},{"surface":"selector inline header","va":"0x004e85fc","role":"40 1b 01 + 40 14 03 00 count record","evidence":"40 1b 01 00 opens the status/menu VM list; 40 14 03 00 09 00 00 00 is the inline 9-entry count before the block pointer array.; 40 14 source=BYTE [object+0xa8 + 0x00]; nearest base=object+0xa8 = 0x004576d8","producerMeaning":"9-entry array를 여는 inline text/status control record다. source는 object+0xa8+0이고 직전 40 1b 01 00이 object+0xa8=0x004576d8로 세팅한다."},{"surface":"selector entry array","va":"0x004e8610","role":"table id 0x77..0x7f block pointer array","evidence":"record=0x004e8608; entryTable=0x004e8610; kinds={'status-comment-block': 9}","producerMeaning":"각 블록 포인터와 index source는 확정됐다. 남은 것은 0x004576d8+0 backing value의 writer/의미다."},{"surface":"backing selector base block","va":"0x004576d8","role":"40 1b 01이 object+0xa8로 지정하는 persistent/global status block","evidence":"0x004576d8 is a 0x72-byte persistent/global status block. It is saved/loaded next to the 3 actor rows at 0x00457750 and the global byte table at 0x0059db60. The status-comment selector source uses object+0xa8+0 with object+0xa8 set to this block, but the exact writer for offset +0 is still not statically proven.","producerMeaning":"selector byte가 들어있는 블록의 정체는 확정 쪽으로 승격. offset +0 writer/게임 내 의미는 미확정."},{"surface":"post-selector local branch list","va":"0x004e8660","role":"selector payload 뒤의 40 1f local branch list","evidence":"pointerCount=3; entries=['0x004e8670', '0x004e867c', '0x004e8688']","producerMeaning":"selector 다음의 VM 흐름 후보지만, selector index나 entry index write/read 증거는 아직 없다."},{"surface":"normal x86 xref probe","va":"0x004e8610","role":"negative proof","evidence":"anchor refs=0; outside entry refs=0","producerMeaning":"ordinary pointer consumer가 아니라 0x40 VM payload interpreter 안에서 처리되는 표면으로 봐야 한다."}],"payloadConsumers":{"statusPayloadVaHex":"0x004e842e","topMenuObjectSequenceVaHex":"0x004ddc6c","refCount":3,"promptPayloadCommandCount":2,"refs":[{"refVaHex":"0x004ddaa8","commandVaHex":"0x004ddaa4","commandRawHex":"10 8e 4e 00 2e 84 4e 00","classification":"non-command-data-ref","modeHex":""},{"refVaHex":"0x004ddc78","commandVaHex":"0x004ddc74","commandRawHex":"2f 02 00 00 2e 84 4e 00","classification":"prompt-text-opcode-0x2f-payload","modeHex":"0x02"},{"refVaHex":"0x004de070","commandVaHex":"0x004de06c","commandRawHex":"2f 02 00 00 2e 84 4e 00","classification":"prompt-text-opcode-0x2f-payload","modeHex":"0x02"}],"decodedTopStreamStatusCommands":[{"vaHex":"0x004ddc74","opcodeHex":"0x2f","rawHex":"2f 02 00 00 2e 84 4e 00","summary":"prompt/text command mode=0x02 payload=0x004e842e; handler advances +0x08; text payload: ^껷 뒆N 텇N"}]},"postSelectorActorBranch":{"branchListVaHex":"0x004e8660","entryCount":3,"actorSlotCandidates":[0,1,2],"actorSlotBranchGrounded":true,"interpretation":"selector array 뒤의 40 1f 3-entry branch list는 각 entry가 40 1b 02 actorSlot으로 시작한다. 따라서 selector group 내부에서 현재 actor slot(0/1/2)별 문구 테이블을 고르는 consumer는 grounded로 볼 수 있다. 아직 미확정인 것은 9개 selector group 중 어떤 group을 고르는 시나리오/상태 producer다.","entries":[{"index":0,"entryVaHex":"0x004e8670","firstRawHex":"40 1b 02 00","classification":"actor-slot-branch-entry","actorSlotCandidate":0,"continuationVaHex":"0x004e868c","continuationRawHex":"40 01 00 00 8c 86 4e 00","continuationKind":"shared-continuation-pointer"},{"index":1,"entryVaHex":"0x004e867c","firstRawHex":"40 1b 02 01","classification":"actor-slot-branch-entry","actorSlotCandidate":1,"continuationVaHex":"0x004e868c","continuationRawHex":"40 01 00 00 8c 86 4e 00","continuationKind":"shared-continuation-pointer"},{"index":2,"entryVaHex":"0x004e8688","firstRawHex":"40 1b 02 02","classification":"actor-slot-branch-entry","actorSlotCandidate":2,"continuationVaHex":"","continuationRawHex":"40 0e 00 00 00 00 00 00","continuationKind":"inline-continuation"}]},"backingStoreEvidence":{"backingBlockVaHex":"0x004576d8","backingBlockSizeBytes":114,"actorRowsVaHex":"0x00457750","actorRowsSizeBytes":648,"actorRowStrideBytes":216,"globalVarTableVaHex":"0x0059db60","globalVarTableSizeBytes":512,"activeActorPointerTableVaHex":"0x0059db30","exactBackingRefCount":6,"exactBackingRefs":["0x004064e4","0x0041d8d7","0x00422262","0x00422272","0x004233fc","0x00423535"],"actorRowRefCount":39,"globalVarRefCount":66,"activeActorPointerRefCount":260,"fixedRefs":[{"refVaHex":"0x004064e4","kind":"active-object-selector-base-setter","evidence":"active-object side writes object+0xa8 = 0x004576d8"},{"refVaHex":"0x0041d8d7","kind":"text-status-selector-base-setter","evidence":"40 1b mode 1 handler writes object+0xa8 = 0x004576d8"},{"refVaHex":"0x00422262","kind":"backing-subrange-pointer","evidence":"chooses 0x004576d8 + 0x20 when function arg is nonzero"},{"refVaHex":"0x00422272","kind":"backing-subrange-pointer","evidence":"chooses 0x004576d8 + 0x14 when function arg is zero"},{"refVaHex":"0x004233fc","kind":"persistent-load","evidence":"reads 0x72 bytes into 0x004576d8, then 0x288 bytes into 0x00457750, then 0x200 bytes into 0x0059db60"},{"refVaHex":"0x00423535","kind":"persistent-save","evidence":"writes 0x72 bytes from 0x004576d8, then 0x288 bytes from 0x00457750, then 0x200 bytes from 0x0059db60"}],"offsetRefs":[{"offsetHex":"0x01","addressHex":"0x004576d9","writerVaHex":"0x004248d5","evidence":"copies BYTE [0x55b2fc + 1] into 0x004576d9 before running a status/text payload","status":"direct-writer-grounded"},{"offsetHex":"0x10","addressHex":"0x004576e8","writerVaHex":"0x0043218f","evidence":"increments active actor count at 0x004576e8 while registering an actor row","status":"direct-writer-grounded"},{"offsetHex":"0x11","addressHex":"0x004576e9","writerVaHex":"0x00432169","evidence":"stores actor slot byte into 0x004576e9 + count during active actor registration","status":"direct-writer-grounded"},{"offsetHex":"0x00","addressHex":"0x004576d8","writerVaHex":"","evidence":"no direct static writer to the exact selector byte was found in the current absolute-ref scan","status":"writer-unproven"}],"interpretation":"0x004576d8 is a 0x72-byte persistent/global status block. It is saved/loaded next to the 3 actor rows at 0x00457750 and the global byte table at 0x0059db60. The status-comment selector source uses object+0xa8+0 with object+0xa8 set to this block, but the exact writer for offset +0 is still not statically proven."},"groupRows":[{"tableIdHex":"0x77","blockVaHex":"0x004f84fc","markerSlotCount":1,"emptySlotCount":2,"parsedTableCount":0,"classifications":[],"sample":""},{"tableIdHex":"0x78","blockVaHex":"0x004b1eb4","markerSlotCount":1,"emptySlotCount":2,"parsedTableCount":0,"classifications":[],"sample":""},{"tableIdHex":"0x79","blockVaHex":"0x0047e9f0","markerSlotCount":2,"emptySlotCount":1,"parsedTableCount":0,"classifications":[],"sample":""},{"tableIdHex":"0x7a","blockVaHex":"0x0043ffc0","markerSlotCount":2,"emptySlotCount":1,"parsedTableCount":0,"classifications":[],"sample":""},{"tableIdHex":"0x7b","blockVaHex":"0x00511af4","markerSlotCount":3,"emptySlotCount":0,"parsedTableCount":0,"classifications":[],"sample":""},{"tableIdHex":"0x7c","blockVaHex":"0x004d7da8","markerSlotCount":3,"emptySlotCount":0,"parsedTableCount":0,"classifications":[],"sample":""},{"tableIdHex":"0x7d","blockVaHex":"0x0048c414","markerSlotCount":3,"emptySlotCount":0,"parsedTableCount":0,"classifications":[],"sample":""},{"tableIdHex":"0x7e","blockVaHex":"0x00454e14","markerSlotCount":3,"emptySlotCount":0,"parsedTableCount":0,"classifications":[],"sample":""},{"tableIdHex":"0x7f","blockVaHex":"0x00534710","markerSlotCount":3,"emptySlotCount":0,"parsedTableCount":0,"classifications":[],"sample":""}],"conclusions":["40 13 01 상태창 짧은 문구 테이블은 EXE에서 9개 그룹으로 재현된다.","40 1b 00 00 40 1f 00 00 블록도 정확히 9개이며, 각 블록은 table id별로 3개 포인터 슬롯을 가진다.","상태창 payload 0x004e85fc 안에서 0x004e8610의 9-entry 블록 포인터 배열이 확인되며, 배열 순서는 table id 0x77..0x7f와 일치한다.","일부 슬롯은 독립 40 13 01 table marker가 아니라 40 0a empty/terminator 슬롯이다. 따라서 actor-table 이름은 consumer 확정 전까지 후보로 둔다.","대부분 테이블은 인접 로컬 포인터가 소유하는 데이터 블록으로 보이며, 일부는 selector-root scene/resource 범위 안에 들어간다.","아직 시나리오 플래그/상태값이 selector array index와 엔트리 index를 고르는 producer는 확정되지 않았다.","selector/header/array 자체에는 일반 x86 포인터 참조가 없고, 각 comment block은 0x004e8610 + index*4 inline array slot에서만 참조된다."],"nextFrontier":["status/menu payload consumer, 40 14 source, actor-slot branch, 0x004576d8 backing block 저장/로드는 grounded. 이제 0x004576d8+0 backing value writer를 찾는다.","scene-root-contained group 7개와 local-pointer-owned group 2개를 분리해, selector index가 scene group 순서인지 상태 flag인지 대조한다.","상태창을 여는 opener가 확정되면 그 call path에서 0x004576d8 주변 write를 함께 추적한다.","정적 상태에서는 0x40 VM interpreter의 남은 handler 중 40 1f/40 2e/40 30 쪽 소비 의미를 더 디코드한다. 런타임 trace는 기본 경로로 두지 않는다."]}