You might want to append a ?per_page=50 to the end of your GET statements like this. That will cut the number of API calls by a factor of 5 since the default is 10.
I do use the list course assignment submissions on our mandatory orientation (which has had several thousand students at a time in it, currently with only 1585 since we just reset the version for summer/fall enrollment). However, my approach is a little different. Once they've completed the assignment I'm checking, I delete them from the course. Since we run the process every 20 minutes and quiz submissions don't show up until they've completed the quiz or had a grade assigned, there's rarely a more than a handful of students who are returned with the call. Still, everytime that someone has called to complain that they're still in the orientation and not able to get into their courses, it's been something other than the programming.
I also know that you could get 1000 people who say it's never happened to them, but that's not a proof. All it takes is one time where it doesn't work. You might be the counter-example that proves it broken.
So, let's talk debugging steps. You've probably already checked all these things, but just in case one of them makes you go ahah!, I thought I'd ask.
When you pull up Adam's score by specifying his ID on the API call, is there anything out of the ordinary when compared with other students who do show up in the big list?
Are you sure the code to pull all the assignments is really pulling all of the assignments? Are you using the links header to get the next page or are you manually trying to generate the links? Are you processing the information as it comes in or gathering it all into one body for processing at the end?
Have you tried dumping the URIs that are called to look for a missing or out-of-sequence call? If there is one, that might indicate where the problem is and even if it's on your end or Canvases?
Is it possible that new students are getting added to the course while you're fetching the assignment list? Yes, I'm grasping, but I'm wondering if another student got inserted, if it might skip over someone. I don't program in Ruby, but I know a guy who does who said he's had issues assigning unique id's when two people hit it at the same time but on multiple threads. I think the logic just needs fixed, but I'm trying to eliminate all possibilities, no matter how far fetched they may be.
Is there a regular pattern to the ones that are missing? Does changing the ?per_page parameter affect which ones are missing?
Are you looking for Adam in the raw dump from the API calls or are you doing some processing first and then looking for him? Can you identify where Adam should fall in the progression and then see if there is something in the previous entry that is causing an issue (I honestly have no idea what that would be - again, grasping, throwing out things and hoping something sticks)?
Is Adam a super-hacker? Does he have a role other than student? Does he have a role other than student somewhere else in Canvas?
I'm afraid this isn't much help. This is one of those things where nothing obvious jumps out at me and I use the same API calls.
I have had issues with the API not returning information, but that was with the quiz submissions, not the assignment submissions. That was an issue of it only returning one submission while the documentation indicated it should return all of them. I think that's a different issue than what you're facing.