Summary: - Baseline Compare landing: enterprise UI (stats grid, critical drift banner, better actions), navigation grouping under Governance, and Action Surface Contract declaration. - Baseline Profile view page: switches from disabled form fields to proper Infolist entries for a clean read-only view. - Fixes tenant name column usages (`display_name` → `name`) in baseline assignment flows. - Dashboard: improved baseline governance widget with severity breakdown + last compared. Notes: - Filament v5 / Livewire v4 compatible. - Destructive actions remain confirmed (`->requiresConfirmation()`). Tests: - `vendor/bin/sail artisan test --compact tests/Feature/Baselines` - `vendor/bin/sail artisan test --compact tests/Feature/Guards/ActionSurfaceContractTest.php` Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #123
167 lines
6.2 KiB
Markdown
167 lines
6.2 KiB
Markdown
#+#+#+#+
|
||
# Implementation Plan: Golden Master / Baseline Governance v1 (R1.1–R1.4)
|
||
|
||
**Branch**: `101-golden-master-baseline-governance-v1` | **Date**: 2026-02-19 | **Spec**: [spec.md](spec.md)
|
||
**Input**: Feature specification from [spec.md](spec.md)
|
||
|
||
## Summary
|
||
|
||
Implement a workspace-owned **Golden Master baseline** that can be captured from a tenant into an immutable snapshot, assigned to tenants, and compared (“Soll vs Ist”) to generate drift findings + a compact operational summary.
|
||
|
||
This feature reuses existing patterns:
|
||
- tenant-scoped `OperationRun` for capture/compare observability + idempotency
|
||
- `findings` for drift tracking with sha256 fingerprints
|
||
|
||
## Technical Context
|
||
|
||
**Language/Version**: PHP 8.4.x
|
||
**Framework**: Laravel 12
|
||
**Admin UI**: Filament v5 (requires Livewire v4.0+)
|
||
**Storage**: PostgreSQL (Sail locally); SQLite is used in some tests
|
||
**Testing**: Pest v4 (`vendor/bin/sail artisan test`)
|
||
**Target Platform**: Docker via Laravel Sail (macOS dev)
|
||
**Project Type**: Laravel monolith (server-rendered Filament + Livewire)
|
||
**Performance Goals**:
|
||
- Compare completes within ~2 minutes for typical tenants (≤ 500 in-scope policies)
|
||
**Constraints**:
|
||
- Baseline/monitoring pages must be DB-only at render time (no outbound HTTP)
|
||
- Operation start surfaces enqueue-only (no remote work inline)
|
||
**Scale/Scope**:
|
||
- Multi-tenant, workspace isolation is an authorization boundary
|
||
|
||
## Constitution Check
|
||
|
||
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
|
||
|
||
- Inventory-first: compare operates on “last observed” inventory/policy versions; baseline snapshot is an explicit immutable capture.
|
||
- Read/write separation: capture/compare are operational jobs; any mutations are confirmed, audited, and tested.
|
||
- Graph contract path: no Graph calls on UI surfaces; any Graph usage (if introduced) must go through `GraphClientInterface` and `config/graph_contracts.php`.
|
||
- Deterministic capabilities: new baseline capabilities are added to the canonical registry and role maps.
|
||
- RBAC-UX semantics: non-member is 404; member but missing capability is 403.
|
||
- Run observability: capture/compare are always `OperationRun`-tracked; start surfaces only create/reuse runs and enqueue work.
|
||
- Data minimization: workspace-owned baseline snapshots are minimized and must not store tenant secrets.
|
||
- Badge semantics (BADGE-001): finding severity/status uses existing `BadgeCatalog` mapping.
|
||
- Filament Action Surface Contract: resources/pages created or modified must define Header/Row/Bulk/Empty-State + inspect affordance.
|
||
|
||
✅ Phase 0 and Phase 1 design choices satisfy the constitution. No violations are required.
|
||
|
||
## Project Structure
|
||
|
||
### Documentation (this feature)
|
||
|
||
```text
|
||
specs/101-golden-master-baseline-governance-v1/
|
||
├── plan.md
|
||
├── spec.md
|
||
├── research.md
|
||
├── data-model.md
|
||
├── quickstart.md
|
||
└── contracts/
|
||
└── baseline-governance.openapi.yaml
|
||
```
|
||
|
||
### Source Code (repository root)
|
||
|
||
```text
|
||
app/
|
||
├── Filament/
|
||
├── Jobs/
|
||
├── Models/
|
||
├── Policies/
|
||
├── Services/
|
||
└── Support/
|
||
|
||
database/
|
||
└── migrations/
|
||
|
||
resources/
|
||
└── views/
|
||
|
||
tests/
|
||
├── Feature/
|
||
└── Unit/
|
||
```
|
||
|
||
**Structure Decision**: Implement baseline governance as standard Laravel models, migrations, services, jobs, and Filament resources/pages under the existing `app/` conventions.
|
||
|
||
## Phase 0 — Research (completed)
|
||
|
||
Outputs:
|
||
- [research.md](research.md)
|
||
|
||
Key decisions captured:
|
||
- Workspace-owned, data-minimized baseline snapshots (reusable across tenants)
|
||
- `OperationRun` types `baseline_capture` and `baseline_compare` using `ensureRunWithIdentity()` for idempotent starts
|
||
- Precondition failures return 422 with stable `reason_code` and do not create runs
|
||
- Findings reuse `findings` with sha256 fingerprints; Phase 2 adds `findings.source` to satisfy `source = baseline.compare`
|
||
|
||
## Phase 1 — Design & Contracts (completed)
|
||
|
||
Outputs:
|
||
- [data-model.md](data-model.md)
|
||
- [contracts/baseline-governance.openapi.yaml](contracts/baseline-governance.openapi.yaml)
|
||
- [quickstart.md](quickstart.md)
|
||
|
||
### UI Surfaces (Filament v5)
|
||
|
||
- Workspace-context: Governance → Baselines
|
||
- Resource for baseline profile CRUD
|
||
- Capture action (manage capability)
|
||
- Tenant assignment management (manage capability)
|
||
- Tenant-context: “Soll vs Ist” landing page
|
||
- Compare-now action (view capability)
|
||
- Links to latest compare run + findings
|
||
|
||
### Authorization & capabilities
|
||
|
||
- Add new workspace capabilities:
|
||
- `workspace_baselines.view`
|
||
- `workspace_baselines.manage`
|
||
- Enforce membership as 404; capability denial as 403.
|
||
|
||
### Operation types
|
||
|
||
- `baseline_capture` (tenant = source tenant)
|
||
- `baseline_compare` (tenant = target/current tenant)
|
||
|
||
### Agent context update (completed)
|
||
|
||
The agent context update script was run during planning. It should be re-run after this plan update if the automation depends on parsed plan values.
|
||
|
||
## Phase 2 — Execution Plan (to be translated into tasks.md)
|
||
|
||
1) **Migrations + models**
|
||
- Add baseline tables (`baseline_profiles`, `baseline_snapshots`, `baseline_snapshot_items`, `baseline_tenant_assignments`)
|
||
- Add `findings.source` column + index to meet FR-015
|
||
|
||
2) **Services**
|
||
- Baseline scope resolution (profile scope ∩ assignment override)
|
||
- Snapshot identity calculation and dedupe strategy
|
||
- Compare engine to produce drift items and severity mapping (FR-009)
|
||
|
||
3) **Jobs (queued)**
|
||
- `CaptureBaselineSnapshotJob` (creates snapshot, items, updates active snapshot when applicable)
|
||
- `CompareBaselineToTenantJob` (creates/updates findings + writes run summary_counts)
|
||
|
||
4) **Filament UI**
|
||
- Baseline profiles resource (list/view/edit) with action surfaces per spec matrix
|
||
- Tenant assignment UI surface (v1: single baseline per tenant)
|
||
- “Soll vs Ist” tenant landing page and dashboard card action
|
||
|
||
5) **RBAC + policies**
|
||
- Capability registry + role maps + UI enforcement
|
||
- Regression tests for 404 vs 403 semantics
|
||
|
||
6) **Tests (Pest)**
|
||
- CRUD authorization + action surface expectations
|
||
- Capture snapshot dedupe
|
||
- Compare finding fingerprint idempotency
|
||
- Precondition failures return 422 and create no `OperationRun`
|
||
|
||
7) **Formatting**
|
||
- Run `vendor/bin/sail bin pint --dirty`
|
||
|
||
## Complexity Tracking
|
||
|
||
None.
|