16-bit address-size is not usable in 64-bit code.  Pointers are 64-bit.  You could have tried assembling movw %ax, (%bx), although the resulting error message, foo.s:1: Error: `(%bx)' is not a valid base/index expression is not super-helpful.  (I used gcc -c foo.s to run GAS on it, on my x86-64 Linux desktop.)
Address-size and operand-size are separate things.
mov %ax, (%rbx) is a 16-bit store to the memory pointed-to by RBX.  %ax is a 16-bit register so it implies 16-bit operand size.  (And yes, movw with the operand-size override suffix on the mnemonic is also a valid way of writing it.)
Fun fact:
mov %ax, (%ebx) is encodable in 64-bit mode, but it will only use the low 32 bits of RBX as the address for the memory operand.  You basically never want to use 32-bit address-size in 64-bit mode, not even in an LEA instruction.
Your lab partner is correct, it's exactly analogous to C:
  uint16_t *p;
  sizeof(p) == 8        // With a normal x86-64 C compiler
  sizeof(*p) == 2
You always have to use the full size of the register in addressing modes.  Using the low 16 bits of a pointer as the addressing mode wouldn't be useful.
there's not a ton of explicit information on this!
Intel's manuals are very explicit, but also quite long.  https://software.intel.com/en-us/articles/intel-sdm#three-volume
HTML extract of the main part of the vol.2 manual (without the how-to-read-it part): https://www.felixcloutier.com/x86/index.html, with the entry for mov being https://www.felixcloutier.com/x86/mov
See also other links at https://stackoverflow.com/tags/x86/info.
Related: