# Implementation Plan: Tag Badge Catalog (Neutral, Suite-wide) v1

**Branch**: `060-tag-badge-catalog` | **Date**: 2026-01-23 | **Spec**: `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/060-tag-badge-catalog/spec.md`  
**Input**: Feature specification from `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/060-tag-badge-catalog/spec.md`

**Note**: This template is filled in by the `/speckit.plan` command. See `.specify/scripts/` for helper scripts.

## Summary

- Introduce a centralized, suite-wide tag badge catalog for non-status metadata (type/category/platform/environment/visibility/snapshot type).
- Enforce a neutral, explicit palette allowlist (`gray|primary|info`) and domain-based color assignment (domain → color), so tags don’t read as health signals.
- Migrate the minimum targeted surfaces plus any additional tag-like badges found during the discovery sweep.
- Add automated guardrails to prevent ad-hoc tag badge styling from reappearing.

## Technical Context

**Language/Version**: PHP 8.4.15 (Laravel 12)  
**Primary Dependencies**: Filament v5 + Livewire v4  
**Storage**: PostgreSQL  
**Testing**: Pest v4 (PHPUnit v12 runtime via `php artisan test`)  
**Target Platform**: Web application (Filament admin panel)  
**Project Type**: Web (Laravel monolith)  
**Performance Goals**: Tag badge mapping is constant-time; no added queries; no N+1; typical list pages render <2s for normal tenant sizes.  
**Constraints**: Tenant-scoped; tag badge rendering must be DB-only and must not trigger outbound HTTP or job dispatch during render/polling/hydration.  
**Scale/Scope**: Suite-wide migration for tag-like (metadata) badges across tables, detail views, and dashboard lists.

## Constitution Check

*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*

- Inventory-first / Snapshots-second: no changes to inventory or snapshot semantics (UI-only rendering changes).
- Read/write separation: no write behavior introduced.
- Graph contract path: no Graph calls introduced.
- Deterministic capabilities: no capability derivation changes.
- Tenant isolation: all surfaces remain tenant-scoped; catalog mapping is pure.
- Run observability: no new operations/jobs/queues introduced; render remains DB-only.
- Automation: N/A (no queued/scheduled work introduced by this feature).
- Data minimization: no new data storage.
- Badge semantics (BADGE-001): status-like badges remain governed by `BadgeCatalog` / `BadgeRenderer`; this feature applies to tag-like badges only.

Status: ✅ No constitution violations (UI-only semantics; no new Graph calls; no new write behavior; tag badge mapping is pure and tenant-safe).

## Project Structure

### Documentation (this feature)

```text
/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/060-tag-badge-catalog/
├── plan.md              # This file (/speckit.plan command output)
├── research.md          # Phase 0 output (/speckit.plan command)
├── data-model.md        # Phase 1 output (/speckit.plan command)
├── quickstart.md        # Phase 1 output (/speckit.plan command)
├── contracts/           # Phase 1 output (/speckit.plan command)
└── tasks.md             # Phase 2 output (/speckit.tasks command - NOT created by /speckit.plan)
```

### Source Code (repository root)

```text
/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/
├── Filament/
│   ├── Pages/                                    # Update: replace tag badge usage where present
│   ├── Resources/                                # Update: migrate tag-like badges to the tag catalog
│   └── Widgets/                                  # Update: migrate dashboard tag chips
└── Support/
    └── Badges/                                   # New/Update: introduce tag badge catalog (separate from status-like catalog)

/Users/ahmeddarrazi/Documents/projects/TenantAtlas/resources/views/
└── filament/                                     # Update: migrate any tag badge Blade usage

/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/
├── Feature/Guards/                               # New/Update: lightweight “no forbidden tag colors” guard
└── Unit/                                         # New: tag badge mapping tests per domain
```

**Structure Decision**: Laravel monolith + Filament v5 conventions. Keep status-like badge semantics in `app/Support/Badges/*` (Feature 059). Add a separate, neutral tag badge catalog under the same namespace (but not mixed with status domains) and consume it from Filament resources/pages/widgets + Blade views.

## Complexity Tracking

> **Fill ONLY if Constitution Check has violations that must be justified**

None.

## Phase 0 — Outline & Research (complete)

- Output: `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/060-tag-badge-catalog/research.md`
- Key decisions captured:
  - Neutral palette allowlist: `gray|primary|info`.
  - Domain-based colors (domain → color), not per-tag-value colors.
  - Unknown/unmapped fallback: “Other: <value>” (normalized).
  - v1 coverage: minimum targeted surfaces plus any additional tag-like badges found in discovery.

## Phase 1 — Design & Contracts (complete)

### Data model
- Output: `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/060-tag-badge-catalog/data-model.md`
- No schema changes required; tag badge semantics derive from existing metadata fields.

### Contracts
- Output: `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/060-tag-badge-catalog/contracts/tag-badge-semantics.md`
- Output: `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/060-tag-badge-catalog/contracts/guardrails.md`

### Quickstart
- Output: `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/060-tag-badge-catalog/quickstart.md`

### Agent context update
- Output: `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/Agents.md`

### Provider registration (Laravel 11+)
- Panel providers remain registered in `bootstrap/providers.php` (no changes required for this feature unless adding a new provider).

### Livewire / Filament version safety
- Livewire v4.0+ (required by Filament v5) is in use.

### Asset strategy
- No new assets expected. If new panel assets are introduced during implementation, ensure deployment runs `php artisan filament:assets`.

### Destructive actions
- None introduced in this feature.

### Constitution re-check (post-design)
- ✅ Inventory-first / Snapshots-second: unaffected (UI-only semantics).
- ✅ Read/write separation: this feature is read-only.
- ✅ Graph contract path: no Graph calls added.
- ✅ Tenant isolation: tag badge mapping is pure and uses already-available tenant-scoped data.
- ✅ Run observability: no new long-running work introduced.
- ✅ Data minimization: no new payload storage.
- ✅ BADGE-001: status-like badge semantics remain centralized; tag badge semantics are handled separately and remain neutral.

**Gate status (post-design)**: PASS

## Phase 2 — Implementation Plan (next)

### Story 1 (P1): Consistent, neutral tags on core inventory surfaces
- Add a centralized tag badge catalog covering at least: policy type, policy category, platform, tenant environment, visibility/lifecycle, snapshot type.
- Migrate Policies / Policy Versions / Inventory / Tenants to the tag badge catalog.
- Enforce: domain-based colors and neutral palette allowlist.

### Story 2 (P2): Suite-wide consistency via discovery-driven migration
- Produce a discovery report of existing tag badge surfaces and values.
- Migrate additional tag-like badges found during discovery (dashboards, detail views, backup/snapshot metadata) while keeping status-like badges on the status catalog.

### Story 3 (P3): Guardrails keep consistency over time
- Add mapping tests per tag domain, plus an invariant test enforcing the allowed palette.
- Add a lightweight guard test that flags forbidden tag colors (`success|warning|danger`) on tag-like badge surfaces.
