Filed by the SaaS launch review. Priority P0.17 — severity high, category unfinished.
Problem
Settings → Agent renders a Max cost per task (USD) control that PUTs to /api/v2/settings and persists config.max_cost_usd, but a full-repo grep finds the field only in config.py, ui/models.py, settings_v2.py and the frontend — no runtime, react_agent, conductor or adapter reads it. A user who sets a $5 cap gets zero cost limiting, and the sibling max_turns field IS wired, making the inert control indistinguishable from a working one. For a paid product a spend cap that silently does nothing is worse than no cap.
Evidence
web-ui/src/app/settings/page.tsx:319
codeframe/ui/routers/settings_v2.py:160
codeframe/core/config.py:167
Acceptance criteria
Atomic by construction: one developer, one focused session.
Problem
Settings → Agent renders a Max cost per task (USD) control that PUTs to /api/v2/settings and persists config.max_cost_usd, but a full-repo grep finds the field only in config.py, ui/models.py, settings_v2.py and the frontend — no runtime, react_agent, conductor or adapter reads it. A user who sets a $5 cap gets zero cost limiting, and the sibling max_turns field IS wired, making the inert control indistinguishable from a working one. For a paid product a spend cap that silently does nothing is worse than no cap.
Evidence
web-ui/src/app/settings/page.tsx:319codeframe/ui/routers/settings_v2.py:160codeframe/core/config.py:167Acceptance criteria
Atomic by construction: one developer, one focused session.