Found during plan 0067 review (see plans/0067-durable-action-log.md, Design → File layout).
LLMAgentPolicy builds side-car paths from the raw scene id in two places:
on_trial_start passes f"{scene_id}-e{epoch}" raw to _capture.begin_trial (wire capture path)
on_trial_end writes transcripts/<run_id>/{scene_id}-e{epoch}.jsonl with the raw id
Scene.id is unvalidated task-author input, so a hostile or merely unusual id (path separators, ..) lands directly in a filesystem path. Core's FrameStore already solves this with _safe (unsafe-run substitution + crc32 suffix so distinct ids can't collide), and plan 0067's actions/ side-car reuses it — the plugin's two paths should too.
Low urgency: every in-tree task uses tame ids today. But it's two call sites and the helper already exists.
Found during plan 0067 review (see plans/0067-durable-action-log.md, Design → File layout).
LLMAgentPolicybuilds side-car paths from the raw scene id in two places:on_trial_startpassesf"{scene_id}-e{epoch}"raw to_capture.begin_trial(wire capture path)on_trial_endwritestranscripts/<run_id>/{scene_id}-e{epoch}.jsonlwith the raw idScene.idis unvalidated task-author input, so a hostile or merely unusual id (path separators,..) lands directly in a filesystem path. Core'sFrameStorealready solves this with_safe(unsafe-run substitution + crc32 suffix so distinct ids can't collide), and plan 0067'sactions/side-car reuses it — the plugin's two paths should too.Low urgency: every in-tree task uses tame ids today. But it's two call sites and the helper already exists.