Summary
OEE reads 0.0 on every work center in a fresh instance, for every role. Two independent breaks make Performance a constant zero, so the composite is always zero. A metric that is always zero is worse than one that is absent: it looks like data.
The two breaks
- Production runs never carry a work-center id.
forge.data/Services/OeeService.cs (~L37-41) filters production runs on r.WorkCenterId, but CreateProductionRun never sets it, so the performance query matches nothing.
idealCycleTimeSeconds is silently dropped on create. It is not a member of CreateWorkCenterRequest (WorkCentersController.cs ~L68), so a caller who supplies it gets 201 and a work center with no ideal cycle time. Even with a run attributed, performance has no denominator.
Also role-gated: all four OEE routes exclude the Engineer role, so a shop-floor engineer cannot read OEE for their own cell.
Suggested fix
- Set
WorkCenterId on ProductionRun at creation (from the operation's work center, or accept it in the request).
- Add
idealCycleTimeSeconds to CreateWorkCenterRequest (it is already on the update path/entity) or reject it with 400 instead of dropping it.
- Decide whether OEE ships: if not yet, return
null/404 rather than 0.0.
- Revisit the role list on the OEE routes.
Found by the 2026-08-30 arsenal-as-client gap audit; reproduced live, adversarially verified.
Summary
OEE reads
0.0on every work center in a fresh instance, for every role. Two independent breaks makePerformancea constant zero, so the composite is always zero. A metric that is always zero is worse than one that is absent: it looks like data.The two breaks
forge.data/Services/OeeService.cs(~L37-41) filters production runs onr.WorkCenterId, butCreateProductionRunnever sets it, so the performance query matches nothing.idealCycleTimeSecondsis silently dropped on create. It is not a member ofCreateWorkCenterRequest(WorkCentersController.cs~L68), so a caller who supplies it gets201and a work center with no ideal cycle time. Even with a run attributed, performance has no denominator.Also role-gated: all four OEE routes exclude the Engineer role, so a shop-floor engineer cannot read OEE for their own cell.
Suggested fix
WorkCenterIdonProductionRunat creation (from the operation's work center, or accept it in the request).idealCycleTimeSecondstoCreateWorkCenterRequest(it is already on the update path/entity) or reject it with400instead of dropping it.null/404rather than0.0.Found by the 2026-08-30 arsenal-as-client gap audit; reproduced live, adversarially verified.