#+#+#+#+ # 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.