Add attention filtering and SLA tracking to Security section
## Overview
Add status indicators and standardize format for the "Security" subsection.
**Note:** This section currently shows a heatmap. Following the pattern established, we will add a filtered table component that shows only issues requiring attention, while keeping the heatmap available via a dashboard link.
> **Post-implementation note (2026-03-25):** RAG status classification was later removed from all triage report sections in https://gitlab.com/gitlab-org/quality/triage-ops/-/merge_requests/3919. The Security section retains its attention-filtering logic (SLA tracking, missing labels) but no longer displays status emojis or a Status column. `StatusHelper` was deleted; the section's filtering logic is self-contained. See https://gitlab.com/gitlab-org/quality/analytics/team/-/work_items/436+ for the direction change.
## Implementation
Follow the pattern from Test Health section (https://gitlab.com/gitlab-org/quality/triage-ops/-/merge_requests/3848):
1. **Create helper methods** in `lib/` for:
- **Defining status thresholds** (red/amber/green) - what metrics qualify as critical vs needs attention vs healthy
- **Defining filtering logic** - what items show in the detailed table vs deferred to dashboard
- Formatting subsection content
2. **Update template** (`policies/template/group/team-summary.yml.erb`):
- Add section header with status emoji
- Include status indicator in section title
- Add summary table with key metrics (outside collapsible)
- Make detailed content collapsible
3. **Regenerate policies** for all 75 team policy files
4. **Add tests** for helper methods and status calculations
## To be determined
- [x] **Status thresholds:** What counts as red/amber/green for this subsection?
- [x] **Filtering logic:** Which items show in the table vs "View all on dashboard"?
- [x] **Metrics to display:** What information helps teams prioritize?
- [x] **Contextual messages:** What guidance should teams see for each status level?
## Decisions
### 1. Status Thresholds
Hybrid approach combining unlabeled issues with severity-based SLA tracking:
| Status | Criteria |
|--------|----------|
| **Red** | >2 unlabeled issues OR any S1 approaching SLA OR >3 S2 issues OR >10 S3 issues OR >15 S4 issues |
| **Amber** | 1-2 unlabeled issues OR 1-3 S2 issues OR 5-10 S3 issues OR 8-15 S4 issues |
| **Green** | No issues requiring attention |
### 2. Age-Based SLA Tracking
Issues approaching SLA are flagged based on severity-specific thresholds:
| Severity | SLA | Warning Threshold |
|----------|-----|-------------------|
| S1 | 30 days | >16 days old |
| S2 | 30 days | >16 days old |
| S3 | 60 days | >46 days old |
| S4 | 90 days | >76 days old |
### 3. Filtering Logic
- **Show in table:** Issues missing severity/priority labels OR issues approaching/past SLA
- **Show in heatmap:** All issues organized by priority and severity
### 4. Contextual Guidance
Link to [Security prioritization guidelines](https://handbook.gitlab.com/handbook/security/product-security/vulnerability-management/sla/) in the handbook for teams needing guidance on prioritization.
### 5. Always-render behavior
The section should always render, even when a group has 0 ~"bug::vulnerability" issues. Uses an instance variable flag mechanism: the header rule sets a flag when it runs, and the footer rule (which always runs as `type: custom`) checks the flag. If the header never ran, the footer renders a green fallback.
## Target Format
```markdown
### [STATUS_ICON] Security
| Status | Area | Summary |
|--------|------|---------|
| [STATUS_ICON] | [Area] | X total (details) - [Dashboard](URL) |
<details>
<summary><b>View detailed breakdown</b></summary>
#### [STATUS_ICON] [Subsection name]
**Showing X items requiring attention** (details) - [View all Y items](URL)
[Contextual guidance text]
| [Columns] |
|-----------|
| [Filtered data] |
#### Full Security Heatmap
[Full heatmap table showing all items organized by relevant dimensions]
</details>
----
```
**Format notes:**
- **Summary table** at the top shows status and high-level counts (outside collapsible)
- **Everything else** (filtered table, guidance, heatmap) is inside the collapsible <details> section
- **Filtered table** appears first inside details, followed by **full heatmap**
- Status emoji appears in section header, summary table, and subsection headers
## Links to Resources
- Pattern reference: https://gitlab.com/gitlab-org/quality/triage-ops/-/merge_requests/3848
- Security section MR: https://gitlab.com/gitlab-org/quality/triage-ops/-/merge_requests/3908
- Status removal MR: https://gitlab.com/gitlab-org/quality/triage-ops/-/merge_requests/3919
- See `quarantine_helper_context.rb` for status threshold examples
- See `clickhouse_quarantine_helper.rb` for filtering logic examples
## Exit Criteria
- [x] Status thresholds defined and documented for this subsection
- [x] Filtering logic defined (what shows in table vs dashboard)
- [x] Helper methods created and tested
- [x] Subsection added to template with status indicators
- [x] All team policies regenerated
- [x] Contextual guidance provided for each status level
- [x] Tests passing
- [ ] Always-render fallback implemented (green state when 0 issues)
- [ ] Label notation used in message text
Part of: https://gitlab.com/gitlab-org/quality/analytics/team/-/work_items/436
task