Every chapter REPL treated an empty line as a quit command and exited with
status 0 without a word, while the banner only promises "Type q to quit".
Under VS Code's debugger the Python extension's environment-activation line
is often injected into stdin after the program started, so the first thing
the REPL read was a blank line and the chapter vanished right after its
banner.
An empty line is now ignored and the prompt comes back; q and exit still
quit, and EOF/Ctrl-C still end the loop. s17 already behaved this way. A
static test keeps every chapter's quit check free of the empty string.
Fixes#567
- Delete safe_path entirely (following PR #483 approach) — no dead code
- Update all 3 READMEs per module to reflect read_file in Gate 2
- s04: also update permission_hook snippet in READMEs
- s20: remove safe_path (already replaced with inline resolution)
Closes#482
s04_hooks: permission_hook checks path + asks user, but safe_path
still raised hard ValueError — user approval was ineffective, same
root cause as s03 (#482).
s20_comprehensive: permission_hook used safe_path directly inside
try/except, silently denying all writes outside workspace without
ever asking the user. Now uses is_relative_to check + user prompt.
Both files also add read_file to the permission coverage.
s05-s08 intentionally NOT changed: their permission_hook does not
check paths at all — safe_path is their only path-safety defense.