95b16a5047
Diagnosed from session 508c8d58 (frontend freestyle run, WorkflowFailed): three independent weak-model-hostile gates, none a model-capability problem. - shell: split a collapsed single-string command line (["npm create vite …"]) into tokens instead of rejecting it as a "collapsed array". The model reliably re-emits this shape; rejecting looped bootstrap_frontend until stage_loop_break. JSON-escape mangles (quotes/commas in argv[0]) stay rejected. - recovery: a stage_loop_break route now gets a "Stuck-loop ticket", not the "Contract arbitration ticket". The arbitration prompt told the model to read and reconcile "the files named below" — but a tool-syntax loop names zero files, sending the recovery agent grepping the repo for 40+ turns until the repair ladder exhausted. - plan lint: H3 (unreferenced_prompt_artifact) demoted from hard failure to soft finding, and seeds excluded from it. It word-matches artifact IDs in free prose and cannot tell a forgotten dep from a descriptive mention, so as a hard gate it burned architect retries on words it couldn't reword away (analysis/dod). Hard tier is now deterministic graph facts only (H1/H2). Tests: ShellToolTest, PlanLinterTest, RecoveryRoutingTest green; detekt clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015Ly2mMnt9TCZbvhcC1JfuV