Index
2026-09-21 — Plan

실험 3 — Oracle-plan Online Control Eval 설계

SceneMem | GT 계획 + 시드 제거로 execute-state memory를 유일한 변수로 만든다

TL;DR

1,490
측정 칸
298
질의 (5 arm)
$210
API 견적
600h
GPU 견적
$0
이번 세션 지출

1 배경 / 목적

이 벤치마크는 메모리를 두 종류로 나눠 잰다 — retrospective memory(과거에 본 것을 회상)와 execute-state memory(실행 중 바뀐 상태를 기록하고 꺼내 씀). 이를 위해 실험을 셋으로 쪼갰다.

축실험 1 (읽기)실험 2 (계획형 온라인)실험 3 (이 설계)
retrospective memory측정 대상계획 출처로 사용제거
계획 품질—전략이 만든 계획 (틀릴 수 있음)GT 고정 (항상 정답)
execute-state memory없음6 arm 중 4개 채널 꺼짐 → 측정 불가유일한 변수

실험 2가 남긴 세 미결이 실험 3의 존재 이유다.

(a) 실행 계수 .58이 편향돼 있다: 실험 2는 "그 전략의 읽기 답이 맞은 칸"만 돌았다(scores.place_set == 1). LOO 난이도 보정이 그 칸들이 쉬운 칸임을 이미 보였다 — frames-uniform 자기 셀 .634는 같은 칸에서 다른 전략도 .649. 따라서 "종단 SR = 읽기 × .58"의 .58은 상향 편향 추정치다.
(b) execute-state 채널이 대부분 꺼진 채로 쟀다: textlog은 프롬프트가 note: null을 강제해 원천 차단 · frames-uniform의 온라인 기여는 현재 뷰 중복이라 순증 0 · vis-pure는 89% 칸에서 KEEP 0장 · rf-v3는 계획 줄을 100% 삭제. 6 arm 중 tagmem 하나만 작동했다.
(c) vis-pure의 KEEP 미사용은 능력이 아니라 축출 비용 문제: 짝지은 16칸에서 A팔은 103턴 동안 KEEP 0회(seed_left 정확히 8.00), 정상화 문장 한 줄을 넣은 B팔은 18회. 원인은 읽기 단계가 8슬롯을 다 써서 메모리가 꽉 찬 채 시작하는 것이다.

2 작업 내용 — 확정 조건과 그 근거

하네스를 코드로 전수 확인하고(서브에이전트 2대 병렬), 사용자 결정 9건을 받아 설계를 확정했다. 실행한 측정은 없다.

항목확정값대안을 버린 이유
arm5개 — blind · frames-uniform · rf-v3 · vis-pure · tagmem-r3textlog은 시드를 빼면 blind와 완전 동일(둘 다 notes=none · images=none)
frames-uniform 포함포함유일한 비-에이전트 이미지 대조군. 없으면 vis-pure의 이득을 "사진을 갖는 것" vs "고르는 것"으로 분리 못 한다
계획 위치과제 지시 블록에 고정노트에 두면 rf-v3가 지운다(실험 2에서 100%) → 정답 계획에서는 arm 고유 핸디캡
시드 메모리전 arm 제거축이 execute-state 하나로 정리되고 KEEP 축출비용이 0이 된다
표본 k하위유형당 30k=50은 GPU 925h(1주+). k=30이면 580h이고 짝비교 n=298로 Δ.05 검정력 충분
find 버전v1.2 fd856246하위유형 50씩이 정확히 나오고 논문 읽기 본표와 일치
restore 버전v1.1 6511da78아래 §3 데이터셋 감사

표본 구성 (실측 분포)

D1D2D3S1S2k=30 표본
find v1.2 (722)22022950123100150
restore v1.1 (575)215196287957148

사용자가 제안한 "50개씩 → 472개 정도"는 find를 v1.2로 잡았을 때 정확히 250+228=478이었다(v1.0은 S1 34 · S2 20뿐이라 250이 안 나온다). k만 30으로 낮춰 확정 — 298질의 × 5 arm = 1,490칸.

하네스 변경 4건 (기본값은 실험 2와 바이트 동일)

1. --plan gt GT를 손으로 조립하지 않는다 — 읽기 트랙 정본 빌더 facts.gt_selections / gt_selections_restore 출력을 gt_plan_answer()로 감싸 기존 plan_texts()에 흘린다 2. --seed none 전 arm 빈 메모리. 축출 정상화 문장도 함께 끈다 (빈 메모리에선 "starts full"이 거짓 진술) 3. --plan-slot instruction 계획을 노트 밖으로. 전 arm plan_mode="fixed", rewrite 거부 4. frames-uniform 시드 off면 온라인 타임라인만 표집. 예산보다 짧은 초반의 중복 적재 방지 = min(cap, total)
검증됨: 서브에이전트가 보관 merged.json 전 행으로 확인 — {"selections": gt, "abstain": false} 형태면 find 4000/4000 · restore 4000/4000 행에서 오류 0으로 계획 문장이 나온다.
find "pick up the mug — on the desk in the bedroom"
restore "put the ladle back — it is now on the dining table in the kitchen; return it to the sink in the bathroom"

3 결과

사전등록 지표 — SR을 주지표에서 내렸다

실험 2 restore 353행 실측:

계획 항목 수nSR턴단가
1 (D1/D2/D3)306.20323.2$0.184
2 (S1/S2)34.00036.9$0.250
313.00047.1$0.312

이 칸들은 읽기 정답 칸이었으므로 GT 계획을 줘도 안 오른다 — 실행 문제다. 그러나 multi야말로 execute-state가 물리는 구간("1번은 끝냈다"를 기억해야 함)이므로 지표를 바꿔 측정한다.

주지표정의실험 2 기준선
M1 held_repick_rate든 채로 같은 물체를 다시 집은 턴 / 총 턴find 1341회 중 257회(19%)가 낙하 유발
M2 false_done목표 미달인데 done 선언.25 (전략 무관)
M3 wasted_turn_share목표 달성 후 쓴 턴 / 총 턴.304
M4 gc (multi)충족된 답 / 전체 답 = 단계 전이미측정
반증선(사전등록): 5 arm 중 어느 것도 M1~M3에서 |Δ| ≥ 0.05 & 2·SE 밖을 못 내면 "execute-state 메모리는 이 과제에서 실행을 바꾸지 않는다"로 확정 보고한다. 전 arm이 같은 칸을 돌므로 McNemar 짝비교가 된다 — 실험 2의 LOO 보정보다 강하다.

데이터셋 감사 — "restore도 v1.2로 통일"은 하면 안 된다

사용자 질문("restore가 1.2랑 1.1이랑 다른 게 뭐지? 왜 본표가 v1.2가 아니야?")으로 대조했다.

편e987b40f609076c0
train_1299__276,466,03480,778,387
train_1847__163,580,41266,399,832
train_2224__0103,732,181108,527,344
결론: restore GT(to.xyz · settled frame)는 609076c0 판 궤적에서 계산됐다 → 루트를 섞으면 조용히 틀린다. v1.2는 find 전용 릴리즈(589→722, 신규 133 중 132가 이종 물체 다중 cross_multi)이고, "restore v1.2 측정"이라는 게 존재하지 않아 본표가 v1.1인 것이지 업데이트 누락이 아니다. find v1.2는 v1.0과 같은 100편을 쓴다(새 편 0).

spec 자체 검토에서 잡은 결함 3건

③ §3.1 "바닥 답에 방 이름을 넣는다"가 데이터와 어긋났다: 원천 답의 room이 바닥 답에서 64/64 null이라 채울 값이 없다. 게다가 채우면 GT 계획이 어떤 읽기 답도 도달 못 하는 수준이 되어 "종단 SR = 읽기 × 실행" 분해가 깨진다. → 그대로 두고 plan_floor_answers로 기록만. 영향 범위 실측: find 722질의 중 25(3.5%, k=30 표본에서 ~5질의), restore는 0.
② "M1~M4가 전부 행 필드로 계산된다" — 틀림: M1(재-pick)은 행에 없고 plan_log.json 턴 시퀀스에서 나온다. ① 오타 1건.

막힌 지점

h5py 부재: PYTHONPATH=src python -c "from sbench_eval.dataset_v1 import paper_cell" → ModuleNotFoundError: h5py. 시스템 python에 없다. paper_cell을 인라인 재구현해 분포를 셌고, 계획에는 "셀 생성은 h5py 있는 python으로"를 명시했다.
cross_multi를 kind로 찾으려다 0건: v1.2의 kind는 find_target/find_distractor뿐이고, 이종 다중은 steps=multi + 답의 카테고리가 서로 다른 것으로 구별된다(name이 "cup+remote control+pen").

4 Takeaway

의미

1. 실험 3은 실험 2의 "전략 차 없음"을 뒤집으러 가는 게 아니라, 그 결론이 성립할 조건을 처음으로 만드는 것이다. 시드를 빼면 KEEP 축출 비용이 0이 되고 frames-uniform의 순증 0 문제가 해소되어, 6 arm 중 4개가 꺼져 있던 채널이 전부 켜진다.

2. SR을 주지표에서 내린 것이 이 설계의 핵심 결정이다. restore multi SR 0/47은 GT 계획으로도 안 오르므로, SR을 고집하면 가장 비싼 구간(전체 예산의 45%)에서 아무 신호도 못 얻는다.

3. 병목은 돈이 아니라 GPU 시간이다(≈$210 vs ≈600 GPU-h). k=50→30 결정이 그래서 나왔다.

4. 데이터셋 버전 혼용은 조용히 틀리는 부류다 — 질의 파일이 같아 보여도 편이 다를 수 있다. 메모리에 기록했다.

5 Next Steps

즉시 ($0)

구현 계획 Task 1~7. 네 스위치의 기본값이 실험 2와 바이트 동일함을 회귀 테스트로 고정한다. spec docs/superpowers/specs/2026-09-21-oracle-plan-online-design.md(216cd2b), 계획 docs/superpowers/plans/2026-09-21-oracle-plan-online.md(fd813a4).

승인 대기 (유료)

P1 스모크 $1.5 — v1.2 cross_multi는 온라인에서 한 번도 안 돌아봤다(턴 상한 53 · 예산 5500). 실패하면 find S1/S2 표본을 v1.0 기존 multi 54질의 중심으로 재구성해야 한다.
본 런 ≈$210 — 일일 캡 $100이라 3일 분할. 실험 2 restore(114칸 남음, ≈$22)가 own 8 GPU를 전부 쓰는 중이라 그게 끝나야 들어간다.

결과를 보고 결정

M1~M3에 신호가 있으면 tagmem의 "온라인 전용 상태 슬롯"(사용자 설계, 미구현)을 추가 arm으로 잴지. 신호가 없으면 논문에서 온라인 트랙 기여를 "전이 계수 + 완료 인지 결함"으로 한정할지.

미해결

resume · routine은 온라인 미배선(V1_FAMILIES = ("find","restore")). 주입물 씬 재구성 통합에 ≈3일 필요.