Problem
The fleet cockpit primitive token resolvers use the MAP[key] || fallback idiom, which is not a closed set: a prototype-shaped key (toString, constructor, hasOwnProperty, __proto__) resolves to the inherited Object.prototype member (truthy) instead of the intended fallback, leaking a broken value (a function) into the rendered --fm-* custom property.
@neo-fable reproduced this on familyToken in the #14722 pre-review; it is systemic across the sibling resolvers:
kindToken / kindLabel — apps/agentos/view/fleet/kindRegistry.mjs (from #14701)
stateLabel — apps/agentos/view/fleet/HealthSwatch.mjs (from #14637)
stateToken — apps/agentos/view/fleet/StateDot.mjs (merged, #14593)
familyToken (#14722, FamilyRail.mjs) is already fixed — it delegates to the hasOwn-guarded isKnownFamily.
The fix
Each resolver: return Object.hasOwn(MAP, key) ? MAP[key] : fallback (or delegate to a hasOwn-guarded isKnown* predicate), so the closed set stays closed by construction.
Acceptance criteria
Out of scope
familyToken (#14722, already hardened) · any new resolver (the pattern is the guard, not the map).
Notes
Low real-world likelihood (the maps are fed by the DTO's known vocabulary, not arbitrary input) — this is correctness-by-construction robustness, not a live exploit. Durable lesson: a MAP[key] || fallback lookup is not a closed set.
Problem
The fleet cockpit primitive token resolvers use the
MAP[key] || fallbackidiom, which is not a closed set: a prototype-shaped key (toString,constructor,hasOwnProperty,__proto__) resolves to the inheritedObject.prototypemember (truthy) instead of the intended fallback, leaking a broken value (a function) into the rendered--fm-*custom property.@neo-fable reproduced this on
familyTokenin the #14722 pre-review; it is systemic across the sibling resolvers:kindToken/kindLabel—apps/agentos/view/fleet/kindRegistry.mjs(from #14701)stateLabel—apps/agentos/view/fleet/HealthSwatch.mjs(from #14637)stateToken—apps/agentos/view/fleet/StateDot.mjs(merged, #14593)familyToken(#14722,FamilyRail.mjs) is already fixed — it delegates to the hasOwn-guardedisKnownFamily.The fix
Each resolver:
return Object.hasOwn(MAP, key) ? MAP[key] : fallback(or delegate to a hasOwn-guardedisKnown*predicate), so the closed set stays closed by construction.Acceptance criteria
kindToken,kindLabel,stateLabel,stateTokenguard the map lookup withObject.hasOwn(noMAP[k] ||map-membership).toString/constructor/__proto__resolve to the neutral/fallback (token) or literal (label), never an inherited member.Out of scope
familyToken(#14722, already hardened) · any new resolver (the pattern is the guard, not the map).Notes
Low real-world likelihood (the maps are fed by the DTO's known vocabulary, not arbitrary input) — this is correctness-by-construction robustness, not a live exploit. Durable lesson: a
MAP[key] || fallbacklookup is not a closed set.