v0.6.0
Closes the findings from a full security and code review (#8 to #14).
The public-repository control now sits at whichever layer owns it. At repository scope it is RunPool's, because GitHub has no per-repository equivalent: registration refuses by default, refuses again when visibility cannot be resolved rather than assuming safe, and takes an explicit --allow-public override. At organisation scope it is GitHub's: RunPool reads allows_public_repositories from the default runner group and warns only when it has been turned on, rather than duplicating a control that already defaults correctly.
Also fixed: pool names are validated at register, closing a malformed-JSON path, a directory-traversal path and a word-splitting bug together. The config is created 0600 because it may hold a webhook secret. The runner download fails on HTTP errors, lands atomically and verifies its published SHA256. The scheduler tick takes a lock so a slow poll cannot overlap the next run.
New: SECURITY.md states the threat model plainly and owns the two deliberate differences from GitHub's hardening guidance.