diff --git a/specs/101-golden-master-baseline-governance-v1/tasks.md b/specs/101-golden-master-baseline-governance-v1/tasks.md index 51c6c07..9647c63 100644 --- a/specs/101-golden-master-baseline-governance-v1/tasks.md +++ b/specs/101-golden-master-baseline-governance-v1/tasks.md @@ -21,8 +21,8 @@ ## Phase 1: Setup (Shared Infrastructure) **Purpose**: Ensure the repo is ready for implementation + verification. -- [ ] T001 Verify feature docs are in place in specs/101-golden-master-baseline-governance-v1/ -- [ ] T002 Verify local dev prerequisites via quickstart in specs/101-golden-master-baseline-governance-v1/quickstart.md +- [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 --- @@ -32,24 +32,24 @@ ## Phase 2: Foundational (Blocking Prerequisites) **Checkpoint**: After this phase, US1/US2/US3 work can proceed. -- [ ] T003 Add baseline capabilities to app/Support/Auth/Capabilities.php (`workspace_baselines.view`, `workspace_baselines.manage`) -- [ ] T004 Add baseline capabilities to app/Services/Auth/WorkspaceRoleCapabilityMap.php (Owner/Manager = manage; Operator/Readonly = view) -- [ ] T005 [P] Add operation labels for baseline_capture + baseline_compare in app/Support/OperationCatalog.php -- [ ] T006 [P] Extend summary keys to include severity breakdown keys in app/Support/OpsUx/OperationSummaryKeys.php (add `high`, `medium`, `low`) -- [ ] T007 Create baseline schema migrations in database/migrations/*_create_baseline_profiles_table.php (workspace-owned) -- [ ] T008 Create baseline schema migrations in database/migrations/*_create_baseline_snapshots_table.php (workspace-owned) -- [ ] T009 Create baseline schema migrations in database/migrations/*_create_baseline_snapshot_items_table.php (workspace-owned) -- [ ] T010 Create baseline schema migrations in database/migrations/*_create_baseline_tenant_assignments_table.php (tenant-owned) -- [ ] T011 Create findings source migration in database/migrations/*_add_source_to_findings_table.php -- [ ] T012 [P] Add BaselineProfile model in app/Models/BaselineProfile.php (casts for scope_jsonb; status constants/enum) -- [ ] T013 [P] Add BaselineSnapshot model in app/Models/BaselineSnapshot.php (casts for summary_jsonb) -- [ ] T014 [P] Add BaselineSnapshotItem model in app/Models/BaselineSnapshotItem.php (casts for meta_jsonb) -- [ ] T015 [P] Add BaselineTenantAssignment model in app/Models/BaselineTenantAssignment.php (casts for override_scope_jsonb) -- [ ] T016 [P] Update Finding model for new column in app/Models/Finding.php (fillable/casts for `source` as needed by existing conventions) -- [ ] T017 [P] Add baseline scope value object / helpers in app/Support/Baselines/BaselineScope.php (normalize + intersect profile/override) -- [ ] T018 [P] Add baseline reason codes in app/Support/Baselines/BaselineReasonCodes.php (constants for 422 responses) -- [ ] 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) -- [ ] T018b [P] Add model factories: database/factories/BaselineProfileFactory.php, BaselineSnapshotFactory.php, BaselineSnapshotItemFactory.php, BaselineTenantAssignmentFactory.php (required for Pest tests in Phase 3–5) +- [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 3–5) --- @@ -64,21 +64,21 @@ ## Phase 3: User Story 1 — Baseline Profile CRUD (Priority: P1) 🎯 MVP ### Tests (required in this repo) -- [ ] T019 [P] [US1] Add feature test scaffolding in tests/Feature/Baselines/BaselineProfileAuthorizationTest.php -- [ ] T020 [P] [US1] Add 404 vs 403 semantics tests in tests/Feature/Baselines/BaselineProfileAuthorizationTest.php -- [ ] 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) +- [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 -- [ ] T022 [US1] Create Baseline Profile Filament resource in app/Filament/Resources/BaselineProfileResource.php (navigation group = Governance) -- [ ] T023 [P] [US1] Add resource pages in app/Filament/Resources/BaselineProfileResource/Pages/ListBaselineProfiles.php -- [ ] T024 [P] [US1] Add resource pages in app/Filament/Resources/BaselineProfileResource/Pages/CreateBaselineProfile.php -- [ ] T025 [P] [US1] Add resource pages in app/Filament/Resources/BaselineProfileResource/Pages/ViewBaselineProfile.php -- [ ] T026 [P] [US1] Add resource pages in app/Filament/Resources/BaselineProfileResource/Pages/EditBaselineProfile.php -- [ ] T027 [US1] Implement form/table schema in app/Filament/Resources/BaselineProfileResource.php (scope editor backed by App\Support\Inventory\InventoryPolicyTypeMeta) -- [ ] 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 -- [ ] T029 [US1] Implement audit logging for baseline profile mutations in app/Filament/Resources/BaselineProfileResource.php using App\Services\Audit\WorkspaceAuditLogger -- [ ] 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 +- [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. @@ -94,17 +94,17 @@ ## Phase 4: User Story 2 — Capture Immutable Baseline Snapshot (Priority: P2) ### Tests (required in this repo) -- [ ] 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]) -- [ ] 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]) +- [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 -- [ ] 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) -- [ ] T034 [US2] Add capture start service in app/Services/Baselines/BaselineCaptureService.php (precondition validation before OperationRun creation; enqueue via OperationRunService) -- [ ] T035 [P] [US2] Add snapshot identity helper in app/Services/Baselines/BaselineSnapshotIdentity.php (sha256 over normalized items; reuse DriftHasher::hashNormalized where appropriate) -- [ ] T036 [P] [US2] Add capture job in app/Jobs/CaptureBaselineSnapshotJob.php (DB-only reads; creates snapshot + items; updates profile active snapshot when applicable) -- [ ] T037 [US2] Add audit logging for capture started/completed/failed in app/Jobs/CaptureBaselineSnapshotJob.php using App\Services\Intune\AuditLogger -- [ ] T038 [US2] Persist run context + summary_counts for capture in app/Jobs/CaptureBaselineSnapshotJob.php (use only allowed summary keys) +- [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. @@ -120,32 +120,32 @@ ## Phase 5: User Story 3 — Assign + Compare (“Soll vs Ist”) (Priority: P3) ### Tests (required in this repo) -- [ ] T039 [P] [US3] Add assignment CRUD tests (RBAC + uniqueness) in tests/Feature/Baselines/BaselineAssignmentTest.php -- [ ] 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]) -- [ ] T041 [P] [US3] Add compare idempotent finding fingerprint tests in tests/Feature/Baselines/BaselineCompareFindingsTest.php -- [ ] T042 [P] [US3] Add compare summary_counts severity breakdown tests in tests/Feature/Baselines/BaselineCompareFindingsTest.php +- [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) -- [ ] T043 [P] [US3] Add BaselineTenantAssignments relation manager in app/Filament/Resources/BaselineProfileResource/RelationManagers/BaselineTenantAssignmentsRelationManager.php -- [ ] T044 [US3] Enforce assignment RBAC (404 vs 403) and audits in app/Filament/Resources/BaselineProfileResource/RelationManagers/BaselineTenantAssignmentsRelationManager.php (manage-gated mutations; view-gated visibility) -- [ ] T045 [US3] Implement effective scope validation (override narrows only) in app/Services/Baselines/BaselineScope.php +- [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 -- [ ] T046 [P] [US3] Add tenant landing page in app/Filament/Pages/BaselineCompareLanding.php (navigation label “Soll vs Ist”; DB-only) -- [ ] T047 [P] [US3] Add landing view in resources/views/filament/pages/baseline-compare-landing.blade.php (shows assignment state, last run link, findings link) -- [ ] T048 [P] [US3] Add tenant dashboard card widget in app/Filament/Widgets/Dashboard/BaselineCompareNow.php -- [ ] T049 [US3] Wire the widget into app/Filament/Pages/TenantDashboard.php (add widget class to getWidgets()) +- [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 -- [ ] T050 [US3] Add compare start service in app/Services/Baselines/BaselineCompareService.php (preconditions; enqueue OperationRun; freeze snapshot_id in run context) -- [ ] T051 [P] [US3] Add compare job in app/Jobs/CompareBaselineToTenantJob.php (DB-only; compute drift items; upsert findings with `source='baseline.compare'`) -- [ ] T052 [US3] Implement fingerprinting + idempotent upsert in app/Jobs/CompareBaselineToTenantJob.php (use App\Services\Drift\DriftHasher::fingerprint) -- [ ] T053 [US3] Implement severity mapping (missing=high, different=medium, unexpected=low) in app/Jobs/CompareBaselineToTenantJob.php -- [ ] T054 [US3] Persist run summary_counts with totals + severity breakdown in app/Jobs/CompareBaselineToTenantJob.php (requires T006) -- [ ] T055 [US3] Add audit logging for compare started/completed/failed in app/Jobs/CompareBaselineToTenantJob.php using App\Services\Intune\AuditLogger +- [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. @@ -153,11 +153,11 @@ ### Implementation — Compare engine + job ## Phase 6: Polish & Cross-Cutting Concerns -- [ ] T056 [P] Add operation duration hinting for new operation types in app/Support/OperationCatalog.php (expectedDurationSeconds for baseline_capture/baseline_compare) -- [ ] T057 Ensure all destructive actions have confirmation in app/Filament/Resources/BaselineProfileResource.php and app/Filament/Resources/BaselineProfileResource/RelationManagers/BaselineTenantAssignmentsRelationManager.php -- [ ] T058 Run formatting on touched files via `vendor/bin/sail bin pint --dirty` -- [ ] T059 Run focused test suite via `vendor/bin/sail artisan test --compact tests/Feature/Baselines` -- [ ] 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) +- [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) ---