TenantAtlas/specs/191-baseline-compare-operator-mode/plan.md
ahmido f7bbea2623 191-baseline-compare-operator-mode (#223)
## Summary
<!-- Kurz: Was ändert sich und warum? -->

## Spec-Driven Development (SDD)
- [ ] Es gibt eine Spec unter `specs/<NNN>-<feature>/`
- [ ] Enthaltene Dateien: `plan.md`, `tasks.md`, `spec.md`
- [ ] Spec beschreibt Verhalten/Acceptance Criteria (nicht nur Implementation)
- [ ] Wenn sich Anforderungen während der Umsetzung geändert haben: Spec/Plan/Tasks wurden aktualisiert

## Implementation
- [ ] Implementierung entspricht der Spec
- [ ] Edge cases / Fehlerfälle berücksichtigt
- [ ] Keine unbeabsichtigten Änderungen außerhalb des Scopes

## Tests
- [ ] Tests ergänzt/aktualisiert (Pest/PHPUnit)
- [ ] Relevante Tests lokal ausgeführt (`./vendor/bin/sail artisan test` oder `php artisan test`)

## Migration / Config / Ops (falls relevant)
- [ ] Migration(en) enthalten und getestet
- [ ] Rollback bedacht (rückwärts kompatibel, sichere Migration)
- [ ] Neue Env Vars dokumentiert (`.env.example` / Doku)
- [ ] Queue/cron/storage Auswirkungen geprüft

## UI (Filament/Livewire) (falls relevant)
- [ ] UI-Flows geprüft
- [ ] Screenshots/Notizen hinzugefügt

## Notes
<!-- Links, Screenshots, Follow-ups, offene Punkte -->

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #223
2026-04-11 12:51:46 +00:00

13 KiB

Implementation Plan: Baseline Compare Matrix: High-Density Operator Mode

Branch: 191-baseline-compare-operator-mode | Date: 2026-04-11 | Spec: /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/191-baseline-compare-operator-mode/spec.md Input: Feature specification from /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/191-baseline-compare-operator-mode/spec.md

Note: This plan formalizes the existing 191 spec slice and keeps the work strictly inside the already-shipped Spec 190 matrix surface.

Summary

Refactor the existing workspace baseline compare matrix into an adaptive operator-density surface. The route, baseline reference, visible-set-only truth, compare-start behavior, and drilldowns stay unchanged, but the page gains local presentation-mode state, dense multi-tenant scanning, compact single-tenant rendering, staged heavy-filter application, grouped legends, and clearer separation between blocking refresh, passive auto-refresh, and last-updated status.

Technical Context

Language/Version: PHP 8.4.15
Primary Dependencies: Laravel 12, Filament v5, Livewire v4, Pest v4, Tailwind CSS v4, existing BaselineCompareMatrixBuilder, BadgeCatalog, CanonicalNavigationContext, and UiEnforcement patterns
Storage: PostgreSQL via existing baseline, assignment, compare-run, and finding tables; no new persistence planned
Testing: Pest feature tests and browser smoke coverage run through Laravel Sail
Target Platform: Laravel monolith web application under apps/platform
Project Type: web application
Performance Goals: Improve scan throughput without increasing query shape beyond Spec 190, keep heavy filter changes non-chatty, and preserve DB-only render-time matrix surfaces
Constraints: No compare-logic change, no new persistence, no hidden-tenant leakage, no generalized density framework, no provider or panel changes, and no new asset pipeline
Scale/Scope: One existing matrix page, one existing Blade view, one existing builder, one logical contract file, and focused feature plus browser regressions

Constitution Check

GATE: Passed before Phase 0 research. Re-checked after Phase 1 design and still passing.

Principle Pre-Research Post-Design Notes
Inventory-first / snapshots-second PASS PASS The spec changes presentation only and keeps Spec 190 truth sources intact.
Read/write separation PASS PASS Compare assigned tenants remains the only mutation and is unchanged.
Graph contract path N/A N/A No new Graph behavior or contract-registry work is introduced.
Deterministic capabilities PASS PASS Existing capabilities remain canonical and unchanged.
Workspace + tenant isolation PASS PASS Visible-set-only aggregation and drilldown scope remain unchanged.
RBAC-UX authorization semantics PASS PASS Existing 404 vs 403 semantics and server-side enforcement remain unchanged.
Run observability / Ops-UX PASS PASS Compare-run truth is reused exactly as in Spec 190; this spec only clarifies the visual cues around it.
Data minimization PASS PASS No new data copies, exports, or persisted UI artifacts are introduced.
Proportionality / anti-bloat PASS PASS The work stays local to one page and does not add a new abstraction or stored artifact.
Persisted truth / behavioral state PASS PASS Presentation mode and staged filter state remain request-scoped only.
UI semantics / few layers PASS PASS Existing state, trust, freshness, and severity semantics are reused rather than redefined.
Filament v5 / Livewire v4 compliance PASS PASS The work remains inside the existing Filament page and Livewire-backed route.
Provider registration location PASS PASS No provider changes are required; Laravel 11+ registration remains in bootstrap/providers.php.
Global search hard rule PASS PASS No new searchable resource or page is introduced.
Destructive action safety PASS PASS No destructive action is added. Existing confirmation behavior for compare-start remains unchanged.
Asset strategy PASS PASS No new assets are required. Existing deployment behavior for cd apps/platform && php artisan filament:assets remains unchanged.

Filament-Specific Compliance Notes

  • Livewire v4.0+ compliance: This plan remains on Filament v5 + Livewire v4 and does not introduce legacy APIs.
  • Provider registration location: No panel or provider changes are needed; Laravel 11+ provider registration remains in bootstrap/providers.php.
  • Global search: The feature does not add a new globally searchable resource. Existing baseline-resource search behavior is unchanged.
  • Destructive actions: No new destructive action is introduced. Existing compare-start actions remain confirmation-gated where already defined.
  • Asset strategy: No new global or on-demand asset registration is planned. Deployment handling of cd apps/platform && php artisan filament:assets remains unchanged.
  • Testing plan: Extend the existing matrix feature, builder, guard, and browser suites to cover presentation mode, staged filter application, and non-blocking status surfaces.

Phase 0 Research

Research outcomes are captured in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/191-baseline-compare-operator-mode/research.md.

Key decisions:

  • Keep the existing matrix route and truth model and change presentation only.
  • Resolve auto, dense, and compact mode from visible tenant count, with a route-local override only.
  • Make dense mode state-first rather than action-first.
  • Render single-tenant review as a compact compare list rather than a one-column matrix.
  • Convert heavy filters to staged apply/reset semantics.
  • Replace the long policy-type checkbox stack with a more compact operator-first selector.
  • Group legends into compact support context and separate blocking refresh from passive auto-refresh and last-updated cues.
  • Reuse existing drilldown and visible-set semantics unchanged.

Phase 1 Design

Design artifacts are created under /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/191-baseline-compare-operator-mode/:

  • research.md: decisions and rejected alternatives for local operator-density work
  • data-model.md: request-scoped presentation models for mode state, staged filters, dense rows, compact results, and support-surface state
  • contracts/baseline-compare-operator-mode.logical.openapi.yaml: internal logical contract for adaptive rendering and staged filter application
  • quickstart.md: implementation and verification sequence for the follow-up spec

Design decisions:

  • auto remains the default requested mode and resolves to dense for multiple visible tenants and compact for exactly one visible tenant.
  • Manual mode override remains route-local and must never become stored product truth.
  • Dense mode reuses existing compare truth but condenses cell content to state, trust, freshness, and attention.
  • Compact mode reuses the same truth but removes pseudo-matrix structure once only one visible tenant remains.
  • Heavy filter inputs stage locally and apply explicitly; lightweight route-state changes may remain immediate.
  • Grouped legends, passive auto-refresh, and last-updated signals become support context rather than competing top-level content.

Project Structure

Documentation (this feature)

specs/191-baseline-compare-operator-mode/
├── plan.md
├── research.md
├── data-model.md
├── quickstart.md
├── spec.md
├── tasks.md
├── contracts/
│   └── baseline-compare-operator-mode.logical.openapi.yaml
└── checklists/
    └── requirements.md

Source Code (repository root)

apps/platform/
├── app/
│   ├── Filament/
│   │   └── Pages/
│   │       └── BaselineCompareMatrix.php
│   └── Support/
│       └── Baselines/
│           └── BaselineCompareMatrixBuilder.php
├── resources/views/filament/pages/
│   └── baseline-compare-matrix.blade.php
└── tests/
    ├── Browser/
    │   └── Spec190BaselineCompareMatrixSmokeTest.php
    ├── Feature/
    │   ├── Baselines/
    │   │   └── BaselineCompareMatrixBuilderTest.php
    │   ├── Filament/
    │   │   └── BaselineCompareMatrixPageTest.php
    │   └── Guards/
    │       └── ActionSurfaceContractTest.php
    └── Unit/
        └── Badges/

Structure Decision: Keep the work inside the existing Spec 190 matrix implementation surface. This is a presentation refactor of one existing page and its supporting builder/view behavior, not a new domain slice or a new application area.

Complexity Tracking

Violation Why Needed Simpler Alternative Rejected Because
None N/A The follow-up stays within the existing page, builder, and test surfaces and introduces no new structural violation.

Proportionality Review

  • Current operator problem: The matrix already answers the right governance question, but not with enough density or calmness for repeated operator scanning.
  • Existing structure is insufficient because: The current single rendering shape tries to serve both multi-tenant and single-tenant workflows, so supporting context, action repetition, and cell chrome are too heavy in both cases.
  • Narrowest correct implementation: Keep the same route, truth sources, drilldowns, and compare semantics while adding route-local presentation state, denser rendering, and staged filter application.
  • Ownership cost created: Additional view-state logic, a logical contract file, and focused regression coverage for mode resolution, filter workflow, and status visibility.
  • Alternative intentionally rejected: A generalized density framework, a separate dense-report route, or a stored matrix artifact were rejected because the problem is local to the existing matrix surface.
  • Release truth: current-release operator workflow compression

Implementation Strategy

Phase A — Presentation Mode Contract

  • Add route-local auto, dense, and compact mode state.
  • Resolve the active mode from visible tenant count unless manually overridden.
  • Expose lastUpdatedAt, hasStagedFilterChanges, and passive auto-refresh state to the page.

Phase B — Dense Multi-Tenant Surface

  • Keep the subject column sticky during horizontal scroll.
  • Condense dense cells to state, trust, freshness, and attention signals.
  • Move repeated actions into compact secondary affordances without breaking drilldown continuity.

Phase C — Compact Single-Tenant Surface

  • Replace pseudo-matrix rendering with a compact subject-result list when only one visible tenant remains.
  • Remove repeated tenant headers and duplicated secondary metadata.
  • Preserve subject focus and the existing compare/finding/run destinations.

Phase D — Supporting Context Compression

  • Convert heavy matrix filters to staged apply/reset behavior.
  • Replace the current long policy-type control with a more compact selector.
  • Group or collapse legends.
  • Separate blocking refresh from passive auto-refresh and last-updated status.

Phase E — Verification

  • Extend focused feature coverage for mode resolution, staged filter behavior, and support-surface state.
  • Extend browser smoke coverage for one dense-mode path and one compact-mode path.
  • Keep existing Spec 190 matrix truth, drilldown continuity, and RBAC guarantees green.

Risk Assessment

Risk Impact Likelihood Mitigation
Dense mode becomes another framework Medium Low Keep presentation logic local to the matrix page and avoid generalized shared abstractions.
Compact mode hides too much follow-up value Medium Medium Preserve one clear primary drilldown per subject and keep existing follow-up destinations intact.
Staged filtering feels slow or unclear Medium Medium Show explicit staged/applied state and keep reset obvious.
Manual override confuses operators Low Medium Keep auto as the default and surface the resolved mode clearly.
Last-updated and auto-refresh cues drift out of sync Medium Low Derive both cues from the same rendered matrix payload and active-run state.

Test Strategy

  • Extend BaselineCompareMatrixPageTest for requested vs resolved mode, active filter application, compact vs dense rendering, and non-blocking refresh cues.
  • Extend BaselineCompareMatrixBuilderTest for any new derived presentation metadata required by the page.
  • Keep ActionSurfaceContractTest green so calmer actions do not regress the surface contract.
  • Extend Spec190BaselineCompareMatrixSmokeTest to prove one dense-mode and one compact-mode operator path on the Livewire page.
  • Run the focused Sail verification pack from quickstart.md and re-run update-agent-context.sh copilot after the plan is finalized.