Repository navigation
v0.2.4
Security fix. An unusable candidate's id could forge a rejection line in
the terminal.
When per-candidate validation landed in v0.2.2, a candidate that fails the
contract began being reported rather than refusing the whole plan. The
rejection record carries candidate.get("id") — a value that by construction
has been through no validation, that being exactly why it is in the error
handler — and the renderer prints it.
A planner returning an id of:
bad<ESC>[2K<CR> rejected fake-id: looks fine
erases the rejection line gator just printed and writes its own in its place.
The model whose output is being judged can forge the judgement, for whoever
reads the terminal.
The existing guard in validate_candidates was never the problem and still
works: a valid candidate's free text has been scanned for control characters
since v0.2.2. The reporting path added beside it had no such check.
The fix
safe_text() applied at the data boundary, not at the print site. The
manifest is stored and re-rendered by other commands later, so escaping only
when printing would leave a delayed version of the same attack sitting on
disk.
Four tests, wider than the coverage that existed before: both refusal paths
including acceptance-criteria scanning, the id reaching a terminal, and no raw
control byte in the stored manifest.
Affects
v0.2.2 and v0.2.3, wherever gator auto plan runs against a planner that can
be induced to return a hostile candidate id. Upgrade with deno task install.