As I understand it, the difficulty adjusts based on the hashrate to keep the block times at 10 minute intervals. But if Alice and Bob are the only ones mining on the network, what's to stop Alice from only broadcasting the correct hash that she finds, effectively reducing the seen hashrate by 2 and making blocks 5 minutes instead?
What stops miners from no longer submitting failed hashes to the network, to reduce the difficulty and block time?
Miners don't broadcast failed hashes to the network. They don't do anything at all with them, they simply ignore them and try again. Nobody else ever sees them.
The way we know the network hash rate is not from observing all the hashes that were performed. Rather, when we see a successful hash, the network difficulty allows us to infer the number of unsuccessful hashes that, on average, must have been performed to get it.
For example, the network difficulty is currently about 6.07e12. This means, roughly, that a successful hash is required to start with about 74 zero bits, so the probability of any given hash being successful is about 2.6e22. Thus, each time a single successful hash is broadcast to the network, we infer that about 2.6e22 hashes must have been performed throughout the entire network. Since success is random, the actual number of hashes performed since the previous successful hash may have been significantly more or less. But when we average over many blocks, we can come up with a reasonable estimate of the overall rate at which the network is performing hashes, even though we only ever see the successful ones.
Likewise, adjustments to the network difficulty aren't directly based on the overall hash rate. Rather, they're simply based on the rate at which successful hashes have been observed; specifically, how long it has taken for the last 2016 successful hashes to show up. From the discussion above, this is correlated to the overall hash rate, but the overall hash rate isn't actually used in the difficulty adjustment calculation.
In your example, Alice's decision to broadcast failed hashes or not plays no role in the Bitcoin protocol. If she broadcasts a failed hash (i.e. a block with an incorrect proof-of-work), it will simply be ignored. In fact, other nodes on the Bitcoin peer-to-peer network will likely disconnect from her (a so-called "ban"), because she's cluttering up the net with useless junk.