Reproduction steps:
- Install a workflow whose engine_spec declares:
{"engine_spec": {"capabilities": {"max_spend_cents": 50000}, "nodes": []}}
(this is the path workflow_engine.py::run_workflow() actually enforces at
runtime — it reads wf.get("capabilities") where wf IS engine_spec.)
- Call routes/team.py::job_runner(workflow_id=..., max_spend_cents=50000, ...)
— i.e. requester authorizes exactly the workflow's own declared ceiling.
Expected: caps match (50000 == 50000) -> proceeds to run.
Actual: {'ok': False, 'denied': "cap mismatch: job authorizes 50000c but the
installed workflow's ceiling is None — never run above the requester's cap"}
Root cause: workbench/routes/team.py:395 —
wf_cap = ((rec.get("engine_spec") or {}).get("max_spend_cents"))
reads engine_spec.max_spend_cents directly, but the actual runtime-enforced
key (workflow_engine.py run_workflow(), caps = wf.get("capabilities");
max_spend = caps.get("max_spend_cents")) lives one level deeper, at
engine_spec.capabilities.max_spend_cents. Since the top-level key never
exists on a real workflow record, wf_cap is always None, and line 396'swf_cap is None or ... unconditionally rejects — every spend-capped
workflow offloaded through the Team job path is refused, regardless of the
requester's authorized ceiling.
Suggested fix:
caps = (rec.get("engine_spec") or {}).get("capabilities") or {}
wf_cap = caps.get("max_spend_cents")
Station version (railcall version): station-v0.69
Module slug + version: Not module-specific; Team remote job execution
(routes/team.py::job_runner)