TenantAtlas/specs/101-golden-master-baseline-governance-v1/tasks.md

210 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
description: "Task breakdown for implementing Feature 101"
---
# Tasks: Golden Master / Baseline Governance v1
**Input**: Design documents from `specs/101-golden-master-baseline-governance-v1/`
**Key constraints (from spec/plan)**
- Filament v5 + Livewire v4.0+ only.
- UI surfaces are DB-only at render time (no outbound HTTP).
- Capture/compare start surfaces are enqueue-only (no remote work inline).
- Precondition failures return **HTTP 422** with stable `reason_code` and **must not** create an `OperationRun`.
- RBAC semantics: non-member → **404** (deny-as-not-found); member but missing capability → **403**.
- Findings use sha256 64-char fingerprints (reuse `App\Services\Drift\DriftHasher`).
---
## Phase 1: Setup (Shared Infrastructure)
**Purpose**: Ensure the repo is ready for implementation + verification.
- [X] T001 Verify feature docs are in place in specs/101-golden-master-baseline-governance-v1/
- [X] T002 Verify local dev prerequisites via quickstart in specs/101-golden-master-baseline-governance-v1/quickstart.md
---
## Phase 2: Foundational (Blocking Prerequisites)
**Purpose**: Core primitives used across all user stories (schema, capabilities, operation UX).
**Checkpoint**: After this phase, US1/US2/US3 work can proceed.
- [X] T003 Add baseline capabilities to app/Support/Auth/Capabilities.php (`workspace_baselines.view`, `workspace_baselines.manage`)
- [X] T004 Add baseline capabilities to app/Services/Auth/WorkspaceRoleCapabilityMap.php (Owner/Manager = manage; Operator/Readonly = view)
- [X] T005 [P] Add operation labels for baseline_capture + baseline_compare in app/Support/OperationCatalog.php
- [X] T006 [P] Extend summary keys to include severity breakdown keys in app/Support/OpsUx/OperationSummaryKeys.php (add `high`, `medium`, `low`)
- [X] T007 Create baseline schema migrations in database/migrations/*_create_baseline_profiles_table.php (workspace-owned)
- [X] T008 Create baseline schema migrations in database/migrations/*_create_baseline_snapshots_table.php (workspace-owned)
- [X] T009 Create baseline schema migrations in database/migrations/*_create_baseline_snapshot_items_table.php (workspace-owned)
- [X] T010 Create baseline schema migrations in database/migrations/*_create_baseline_tenant_assignments_table.php (tenant-owned)
- [X] T011 Create findings source migration in database/migrations/*_add_source_to_findings_table.php
- [X] T012 [P] Add BaselineProfile model in app/Models/BaselineProfile.php (casts for scope_jsonb; status constants/enum)
- [X] T013 [P] Add BaselineSnapshot model in app/Models/BaselineSnapshot.php (casts for summary_jsonb)
- [X] T014 [P] Add BaselineSnapshotItem model in app/Models/BaselineSnapshotItem.php (casts for meta_jsonb)
- [X] T015 [P] Add BaselineTenantAssignment model in app/Models/BaselineTenantAssignment.php (casts for override_scope_jsonb)
- [X] T016 [P] Update Finding model for new column in app/Models/Finding.php (fillable/casts for `source` as needed by existing conventions)
- [X] T017 [P] Add baseline scope value object / helpers in app/Support/Baselines/BaselineScope.php (normalize + intersect profile/override)
- [X] T018 [P] Add baseline reason codes in app/Support/Baselines/BaselineReasonCodes.php (constants for 422 responses)
- [X] T018a [P] Add BadgeDomain::BaselineProfileStatus case to app/Support/Badges/BadgeDomain.php + create domain mapper class in app/Support/Badges/Domains/BaselineProfileStatusBadges.php + register in BadgeCatalog (BADGE-001 compliance for draft/active/archived)
- [X] T018b [P] Add model factories: database/factories/BaselineProfileFactory.php, BaselineSnapshotFactory.php, BaselineSnapshotItemFactory.php, BaselineTenantAssignmentFactory.php (required for Pest tests in Phase 35)
---
## Phase 3: User Story 1 — Baseline Profile CRUD (Priority: P1) 🎯 MVP
**Goal**: Workspace managers define baseline profiles (scope + lifecycle) with correct RBAC and action surfaces.
**Independent Test**:
- As a member with `workspace_baselines.manage`, create/edit/archive a profile.
- As a member with `workspace_baselines.view`, list/view but cannot mutate.
- As a non-member, baseline pages/actions deny-as-not-found (404).
### Tests (required in this repo)
- [X] T019 [P] [US1] Add feature test scaffolding in tests/Feature/Baselines/BaselineProfileAuthorizationTest.php
- [X] T020 [P] [US1] Add 404 vs 403 semantics tests in tests/Feature/Baselines/BaselineProfileAuthorizationTest.php
- [X] T021 [P] [US1] Add Action Surface contract coverage for the new resource in tests/Feature/Guards/ActionSurfaceValidatorTest.php (resource discovered or explicitly whitelisted per existing test conventions)
### Implementation
- [X] T022 [US1] Create Baseline Profile Filament resource in app/Filament/Resources/BaselineProfileResource.php (navigation group = Governance)
- [X] T023 [P] [US1] Add resource pages in app/Filament/Resources/BaselineProfileResource/Pages/ListBaselineProfiles.php
- [X] T024 [P] [US1] Add resource pages in app/Filament/Resources/BaselineProfileResource/Pages/CreateBaselineProfile.php
- [X] T025 [P] [US1] Add resource pages in app/Filament/Resources/BaselineProfileResource/Pages/ViewBaselineProfile.php
- [X] T026 [P] [US1] Add resource pages in app/Filament/Resources/BaselineProfileResource/Pages/EditBaselineProfile.php
- [X] T027 [US1] Implement form/table schema in app/Filament/Resources/BaselineProfileResource.php (scope editor backed by App\Support\Inventory\InventoryPolicyTypeMeta)
- [X] T028 [US1] Implement RBAC (404 vs 403) and UI enforcement in app/Filament/Resources/BaselineProfileResource.php using App\Services\Auth\WorkspaceCapabilityResolver + App\Support\Rbac\WorkspaceUiEnforcement
- [X] T029 [US1] Implement audit logging for baseline profile mutations in app/Filament/Resources/BaselineProfileResource.php using App\Services\Audit\WorkspaceAuditLogger
- [X] T030 [US1] Ensure the resource is safe for global search (either keep View/Edit pages enabled OR disable global search explicitly) in app/Filament/Resources/BaselineProfileResource.php
**Checkpoint**: Baseline profiles CRUD works and is independently testable.
---
## Phase 4: User Story 2 — Capture Immutable Baseline Snapshot (Priority: P2)
**Goal**: Managers can enqueue capture from a tenant to create (or reuse) an immutable, workspace-owned snapshot.
**Independent Test**:
- Trigger capture twice for unchanged effective content → the same `snapshot_identity_hash` is reused (no duplicates).
- If profile is active, capture success updates `active_snapshot_id`.
### Tests (required in this repo)
- [X] T031 [P] [US2] Add capture enqueue + precondition tests in tests/Feature/Baselines/BaselineCaptureTest.php (include: empty-scope capture produces empty snapshot without errors [EC-005])
- [X] T032 [P] [US2] Add snapshot dedupe test in tests/Feature/Baselines/BaselineCaptureTest.php (include: concurrent capture request for same scope reuses active run [EC-004])
### Implementation
- [X] T033 [P] [US2] Add capture action UI to app/Filament/Resources/BaselineProfileResource/Pages/ViewBaselineProfile.php (Action::make()->action()->requiresConfirmation(); select source tenant; gated by `workspace_baselines.manage` via WorkspaceUiEnforcement — disabled with tooltip for view-only members, server-side 403 on execution)
- [X] T034 [US2] Add capture start service in app/Services/Baselines/BaselineCaptureService.php (precondition validation before OperationRun creation; enqueue via OperationRunService)
- [X] T035 [P] [US2] Add snapshot identity helper in app/Services/Baselines/BaselineSnapshotIdentity.php (sha256 over normalized items; reuse DriftHasher::hashNormalized where appropriate)
- [X] T036 [P] [US2] Add capture job in app/Jobs/CaptureBaselineSnapshotJob.php (DB-only reads; creates snapshot + items; updates profile active snapshot when applicable)
- [X] T037 [US2] Add audit logging for capture started/completed/failed in app/Jobs/CaptureBaselineSnapshotJob.php using App\Services\Intune\AuditLogger
- [X] T038 [US2] Persist run context + summary_counts for capture in app/Jobs/CaptureBaselineSnapshotJob.php (use only allowed summary keys)
**Checkpoint**: Capture creates immutable snapshots and dedupes repeated capture.
---
## Phase 5: User Story 3 — Assign + Compare (“Soll vs Ist”) (Priority: P3)
**Goal**: Operators can assign a baseline to a tenant (v1: exactly one), then enqueue compare-now to generate drift findings + summary.
**Independent Test**:
- With assignment + active snapshot: compare enqueues an operation and produces findings + summary.
- Re-running compare updates existing findings (same fingerprint) rather than duplicating.
### Tests (required in this repo)
- [X] T039 [P] [US3] Add assignment CRUD tests (RBAC + uniqueness) in tests/Feature/Baselines/BaselineAssignmentTest.php
- [X] T040 [P] [US3] Add compare precondition 422 tests (no OperationRun created) in tests/Feature/Baselines/BaselineComparePreconditionsTest.php (include: concurrent compare reuses active run [EC-004]; draft/archived profile blocks compare [EC-001])
- [X] T041 [P] [US3] Add compare idempotent finding fingerprint tests in tests/Feature/Baselines/BaselineCompareFindingsTest.php
- [X] T042 [P] [US3] Add compare summary_counts severity breakdown tests in tests/Feature/Baselines/BaselineCompareFindingsTest.php
### Implementation — Assignment (v1)
- [X] T043 [P] [US3] Add BaselineTenantAssignments relation manager in app/Filament/Resources/BaselineProfileResource/RelationManagers/BaselineTenantAssignmentsRelationManager.php
- [X] T044 [US3] Enforce assignment RBAC (404 vs 403) and audits in app/Filament/Resources/BaselineProfileResource/RelationManagers/BaselineTenantAssignmentsRelationManager.php (manage-gated mutations; view-gated visibility)
- [X] T045 [US3] Implement effective scope validation (override narrows only) in app/Services/Baselines/BaselineScope.php
### Implementation — Tenant landing + dashboard card
- [X] T046 [P] [US3] Add tenant landing page in app/Filament/Pages/BaselineCompareLanding.php (navigation label “Soll vs Ist”; DB-only)
- [X] T047 [P] [US3] Add landing view in resources/views/filament/pages/baseline-compare-landing.blade.php (shows assignment state, last run link, findings link)
- [X] T048 [P] [US3] Add tenant dashboard card widget in app/Filament/Widgets/Dashboard/BaselineCompareNow.php
- [X] T049 [US3] Wire the widget into app/Filament/Pages/TenantDashboard.php (add widget class to getWidgets())
### Implementation — Compare engine + job
- [X] T050 [US3] Add compare start service in app/Services/Baselines/BaselineCompareService.php (preconditions; enqueue OperationRun; freeze snapshot_id in run context)
- [X] T051 [P] [US3] Add compare job in app/Jobs/CompareBaselineToTenantJob.php (DB-only; compute drift items; upsert findings with `source='baseline.compare'`)
- [X] T052 [US3] Implement fingerprinting + idempotent upsert in app/Jobs/CompareBaselineToTenantJob.php (use App\Services\Drift\DriftHasher::fingerprint)
- [X] T053 [US3] Implement severity mapping (missing=high, different=medium, unexpected=low) in app/Jobs/CompareBaselineToTenantJob.php
- [X] T054 [US3] Persist run summary_counts with totals + severity breakdown in app/Jobs/CompareBaselineToTenantJob.php (requires T006)
- [X] T055 [US3] Add audit logging for compare started/completed/failed in app/Jobs/CompareBaselineToTenantJob.php using App\Services\Intune\AuditLogger
**Checkpoint**: Tenant “Soll vs Ist” UI works end-to-end and compare generates deduped findings.
---
## Phase 6: Polish & Cross-Cutting Concerns
- [X] T056 [P] Add operation duration hinting for new operation types in app/Support/OperationCatalog.php (expectedDurationSeconds for baseline_capture/baseline_compare)
- [X] T057 Ensure all destructive actions have confirmation in app/Filament/Resources/BaselineProfileResource.php and app/Filament/Resources/BaselineProfileResource/RelationManagers/BaselineTenantAssignmentsRelationManager.php
- [X] T058 Run formatting on touched files via `vendor/bin/sail bin pint --dirty`
- [X] T059 Run focused test suite via `vendor/bin/sail artisan test --compact tests/Feature/Baselines`
- [X] T060 Run the quickstart walkthrough in specs/101-golden-master-baseline-governance-v1/quickstart.md and adjust any mismatches; spot-check SC-001 (create+capture < 5 min) and SC-002 (compare < 2 min for 500 policies)
---
## Dependencies & Execution Order
### Phase Dependencies
- Phase 1 (Setup) Phase 2 (Foundational) US phases
- Phase 2 blocks US1/US2/US3.
### User Story Dependencies
- **US1 (P1)** is the MVP and enables profile CRUD.
- **US2 (P2)** depends on US1 (needs profiles) and Phase 2 schema/services.
- **US3 (P3)** depends on US1 (needs profiles) and Phase 2 schema; compare also depends on US2 having produced an active snapshot.
---
## Parallel Execution Examples
### US1 parallelizable work
- T023, T024, T025, T026 (resource pages) can be implemented in parallel.
- T019 and T020 (authorization tests) can be implemented in parallel with the resource skeleton.
### US2 parallelizable work
- T035 (snapshot identity helper) and T036 (capture job) can be implemented in parallel once the schema exists.
- T031T032 tests can be written before the job/service implementation.
### US3 parallelizable work
- T046T048 (landing page + view + widget) can be done in parallel with T050T054 (compare service/job).
- T039T042 tests can be written before implementation.
---
## Implementation Strategy
### MVP First (US1 only)
1. Complete Phase 1 + Phase 2
2. Deliver Phase 3 (US1)
3. Run: `vendor/bin/sail artisan test --compact tests/Feature/Baselines/BaselineProfileAuthorizationTest.php`
### Incremental delivery
- Add US2 (capture) validate dedupe + active snapshot updates
- Add US3 (assign + compare) validate 422 contract + idempotent findings + summary output