fix: honest risk-tier labels for Project Teams cards

Groups > Project Teams renders 20 cards that all show "Moderate risk" and "Weakest: Security (0%)". The bucketing is faithful math, not a bug: ComputeTeamRisk (internal/analyzer/momentum.go:73-120) computes 0.4*decliningPct + 0.3*zeroHeavyPct + 0.3*(1-avgInfluence), where decliningPct counts members whose momentum falls below the -0.2 AtRiskThreshold (internal/analyzer/methodology.go:402). On this dataset no member crosses that threshold, so the 0.4 term is identically zero and the "High" tier (>= 0.6) would need zeroHeavy=1.0 and avgInfluence=0 at the same time, effectively unreachable. The bare tier label hid that ceiling, so 20 teams whose scores actually range 0.348-0.429 all read as an identical, undifferentiated "Moderate risk" with no way to tell how close any of them sat to the boundary. Weakest domain is a genuine per-team minimum over avg_scores; security happens to be the unique zero domain for every team in this dataset, which reads like a team-specific finding when it is really an instance-wide gap.

Renderer-only fix, no analyzer changes (09-trends.js renderProjectTree):

  1. Render the numeric score next to the tier, e.g. "Moderate risk (0.42)".
  2. Add a title tooltip on the risk span explaining the formula and the unreachable-tier mechanism.
  3. When every team's weakest domain sits at 0%, label it "Weakest: Security (0%, instance-wide)" instead of the bare per-team line.

Added TestRender_TeamRiskTierHonestLabels in render_test.go, following the structural-assertion pattern from !66 (merged)'s honest-empty-state fix (!66 (merged)): asserts the new score-plus-tooltip and instance-wide copy are present in the embedded bundle, and that the old bare tier-only form is gone. Rebuilt assets/app.src.js via make js-bundle. make check passes (vet plus full suite).

Merge request reports

Loading