Reads a file as UTF-8 with lossy fallback, enforcing binary detection and max read size limit.
Defense-in-depth: verifies that the canonical path stays within the process’s project root
(if determinable) even though callers SHOULD have already jail-checked the path.