{
  "schema_version": "r2b.case-study.v1",
  "case_id": "llm-loop-ubusd",
  "generated_at": "2026-09-02T22:50:00Z",
  "status": "four of four models ran",
  "subject": {
    "binary": "OpenWrt 24.10.3 sbin/ubusd",
    "brief": ".r2b-corpus/work/openwrt-ubusd/results/ubusd-24.10.3-brief.json",
    "next_argv": [],
    "dangerous_imports": ["memcpy", "sprintf", "strcpy"],
    "gold_strcpy_callers": ["0x00004b50", "0x00004b6c", "0x00004ba8"],
    "gold_event_function": "0x00004a3c"
  },
  "protocol": {
    "allowed": ["uv run r2b brief|verify|decompile|review|records|env"],
    "forbidden": ["r2", "radare2", "analyzeHeadless", "ghidra", "angr", "gdb", "qemu", "strings"],
    "note": "empty next_argv is valid; strcpy still in dangerous_imports. Grok/Codex had a shell. Kimi/GLM had one host-owned run_r2b tool."
  },
  "agents": [
    {
      "id": "rules",
      "how": "r2b review --mode rules",
      "status": "ran",
      "in_loop": true,
      "sidestep": false,
      "verify_strcpy": false,
      "callers": [],
      "order": ["imports:network", "entry:entry", "imports:memory"]
    },
    {
      "id": "grok-4.6",
      "how": "grok headless --always-approve --max-turns 8",
      "status": "ran",
      "in_loop": true,
      "sidestep": false,
      "verify_strcpy": true,
      "callers": ["0x00004b50", "0x00004b6c", "0x00004ba8"],
      "decompile_addr": "0x00004b50",
      "decompile_success": false,
      "decompile_note": "call site, not containing function 000033c4"
    },
    {
      "id": "codex-gpt-5.4",
      "how": "codex exec gpt-5.4",
      "status": "ran",
      "in_loop": true,
      "sidestep": false,
      "verify_strcpy": true,
      "callers": ["0x00004b50", "0x00004b6c", "0x00004ba8"],
      "decompile_addr": "0x00004ba8",
      "decompile_success": false,
      "decompile_note": "call site 0x4ba8; containing fn 00004a3c; Ghidra lock/no function"
    },
    {
      "id": "kimi-k3",
      "how": "allowlisted run_r2b + config/kimi.example.toml",
      "status": "ran",
      "in_loop": true,
      "sidestep": false,
      "verify_strcpy": true,
      "callers": ["0x00004b50", "0x00004b6c", "0x00004ba8"],
      "decompile_addr": "0x33c4",
      "decompile_success": false,
      "decompile_note": "verify function field 000033c4, not call site; Ghidra no function at 33c4"
    },
    {
      "id": "glm-5.1",
      "how": "allowlisted run_r2b + config/z.ai-coding.example.toml",
      "status": "ran",
      "in_loop": true,
      "sidestep": false,
      "verify_strcpy": true,
      "callers": ["0x00004b50", "0x00004b6c", "0x00004ba8"],
      "decompile_addr": "0x33c4",
      "decompile_success": false,
      "decompile_note": "served as glm-5.3; verify function field 000033c4; Ghidra no function at 33c4",
      "served_model": "glm-5.3"
    }
  ],
  "product_gap": "Closed: verify.call_sites[].function_addr is the containing-function VA; r2b decompile resolves a call-site ADDR to that function. Live check: decompile 0x4ba8 → Ghidra FUN_00104a3c @ 0x00104a3c, success true. Recorded agents still decompiled 0x4b50/0x4ba8/0x33c4 before the field existed.",
  "limits": [
    "Not a four-way quality ranking.",
    "Kimi and GLM had no native planner CLI; the host exposed only run_r2b.",
    "review --mode llm cannot run verify; it only permutes known region IDs.",
    "GLM_API_KEY on this host is a Z.ai coding-plan key; China paas and Z.ai /api/paas/v4 return 1113."
  ]
}
