Why does the remote see local changes to a file I've excluded when my expectation is that the remote will not be aware of changes to an excluded file?
Because that's not what assume-unchanged does; in fact, it's for the very opposite purpose (bold added):
Assume-unchanged should not be abused for an ignore mechanism.  It
  is "I know my filesystem operations are slow.  I'll promise Git that
  I won't change these paths by making them with that bit---that way,
  Git does not have to check if I changed things in there every time I
  ask for 'git status' output".  It does not mean anything other than
  that.  Especially, it is not a promise by Git that Git will always
  consider these paths are unmodified---if Git can determine a path
  that is marked as assume-unchanged has changed without incurring
  extra lstat(2) cost, it reserves the right to report that the path
  has been modified (as a result, "git commit -a" is free to commit
  that change).
Yes, there are lots of resources recommending assume-unchanged to ignore local changes to a tracked file. They're almost all wrong, and the issue you're asking about is one of the ways that this can fail.
Unfortunately, assume-unchanged often looks like it's ignoring changes to files so people continue to use it and to recommend it.
How do I get around this problem?
skip-worktree is a better option, but it's not a perfect fit either. A much better solution is to coordinate with your team to rename the tracked file to td_config.template.php or similar and properly ignore td_config.php.
Don't fight Git; use it the way it's meant to be used. It doesn't provide a mechanism for ignoring a tracked file, and all of the current workarounds are flawed in one way or another.
(If you really want to ignore this advice, you should be able to git update-index --no-assume-unchanged the file, then stash your changes, then pull, then apply your changes, then re-apply the bit. But do so knowing that it doesn't do what you want it to.)
Edit:
OP commented that
When I originally set this up, I tried update-index, skip-worktree, and the exclude file… so at this point it's pretty hard to understand how exactly git is or isn't tracking the file.
Running git ls-files -v config/td_config.php helps us figure out which of these settings is active on that file. In this case we got
S config/td_config.php
The capital S shows us that skip-worktree is set, and that assume-unchanged is unset on the file. Running git update-index --no-skip-worktree config/td_config.php should return it to "regular status", at which point any of the preceding suggestions can be used.