--- description: "Task list for Provider-neutral Artifact Source Taxonomy" --- # Tasks: Provider-neutral Artifact Source Taxonomy **Input**: Design documents from `specs/284-provider-neutral-artifact-source-taxonomy/` **Prerequisites**: `specs/284-provider-neutral-artifact-source-taxonomy/spec.md`, `specs/284-provider-neutral-artifact-source-taxonomy/plan.md`, `specs/284-provider-neutral-artifact-source-taxonomy/checklists/requirements.md`, `specs/284-provider-neutral-artifact-source-taxonomy/research.md`, `specs/284-provider-neutral-artifact-source-taxonomy/data-model.md`, `specs/284-provider-neutral-artifact-source-taxonomy/quickstart.md`, and `specs/284-provider-neutral-artifact-source-taxonomy/contracts/provider-neutral-artifact-source-taxonomy.logical.openapi.yaml` **Implementation Posture**: Runtime implementation explicitly accepted on 2026-05-09. Targeted test execution, browser smoke, and dirty-file formatting validation remain required before merge readiness. **Tests**: REQUIRED (Pest). Keep proof bounded to `apps/platform/tests/Unit/Artifacts/ArtifactSourceTaxonomyCatalogTest.php`, `apps/platform/tests/Unit/Inventory/InventoryCanonicalTypeDescriptorTest.php`, `apps/platform/tests/Feature/Artifacts/FindingArtifactSourceTaxonomyTest.php`, `apps/platform/tests/Feature/Artifacts/EvidenceSnapshotSourceTaxonomyTest.php`, `apps/platform/tests/Feature/Artifacts/StoredReportSourceTaxonomyTest.php`, `apps/platform/tests/Feature/Artifacts/InventoryArtifactTypeTaxonomyTest.php`, `apps/platform/tests/Feature/Filament/Artifacts/ArtifactSourceTaxonomySurfaceTest.php`, `apps/platform/tests/Feature/Guards/ArtifactSourceProviderTruthGuardTest.php`, and `apps/platform/tests/Browser/Spec284ArtifactSourceTaxonomySmokeTest.php`. **Operations**: No new `OperationRun` family. Reuse existing read-only operation lineage where `OperationsSummarySource`, `OperationRunLinks`, or adjacent presenters already surface operation context. `284` does not change start, completion, or link UX for operation execution. **RBAC**: Workspace membership remains the first `404` boundary, managed-environment entitlement remains the second `404` boundary, and current findings, evidence, reports, inventory, and review capability denials remain `403`. Provider-neutral artifact typing must not bypass existing policies or capabilities. **Shared Pattern Reuse**: Reuse `PlatformVocabularyGlossary`, `GovernanceSubjectTaxonomyRegistry`, `CanonicalControlResolutionRequest`, `CanonicalControlResolver`, `EvidenceSnapshotService`, `InventoryPolicyTypeMeta`, `ArtifactTruthPresenter`, `TenantReviewSectionFactory`, and touched support or AI `source_family` consumers. Do not introduce a provider framework, a detector catalog, a full control-catalog expansion, a package runtime, a new artifact table, historical backfill, or adjacent Spec `285` through `287` scope. **Filament / Panel Guardrails**: Filament remains v5 on Livewire v4. Provider registration remains in `apps/platform/bootstrap/providers.php`. `FindingResource` and `InventoryItemResource` keep valid `View` pages for any current or future search posture. `EvidenceSnapshotResource`, `StoredReportResource`, and `TenantReviewResource` remain non-globally-searchable while keeping `View` pages. Any touched destructive action must continue to use `->action(...)`, `->requiresConfirmation()`, and current server authorization. Asset strategy stays unchanged. **Compatibility Posture**: Reject historical backfill, dual-write compatibility paths, a new artifact table, a detector catalog, package runtime, a provider framework, RBAC redesign, route-shell work, copy neutralization, and no-legacy enforcement work. **External Prerequisite**: Specs `281`, `282`, and `283` must already be merged or otherwise present on the implementation branch before any runtime or test task starts, and SCOPE-001 ownership compliance for touched tenant-owned artifact tables must be satisfied or explicitly excepted before runtime implementation begins. **Organization**: Tasks are grouped by user story so descriptor derivation, inventory type splitting, operator-surface disclosure, and downstream source-family alignment remain independently testable. **Review Outcome**: `implementation-ready` **Workflow Outcome**: `keep` **Test-governance Outcome**: `keep` **Prerequisite Resolution**: SCOPE-001 is no longer a blocking prerequisite for this implementation loop. Specs `281`, `282`, and `283` are present on the branch, Spec `279` records the approved managed-environment core exception, and current touched artifact tables carry the established workspace plus managed-environment ownership boundary. `284` still must not add a new table, descriptor columns, historical backfill, detector catalog, package runtime, provider framework, or adjacent Specs `285` through `287` scope. ## Test Governance Checklist - [x] Lane assignment stays `fast-feedback`, `confidence`, and one narrow `browser` lane. - [x] New or changed tests stay in the named unit, feature, guard, and browser files only. - [x] Workspace, managed-environment, finding, evidence, stored-report, review, and inventory fixtures remain explicit and opt-in; no hidden shared defaults or backfill helpers are planned. - [x] Planned validation commands match `spec.md`, `plan.md`, and `quickstart.md` exactly. - [x] `standard-native-filament` and `shared-detail-family` expectations stay explicit for touched surfaces. - [x] Any attempt to absorb Specs `285` through `287` resolves as `split` or `reject-or-split`, not hidden follow-up inside `284`. ## Pinned Initial Descriptor Inventories - `source_family`: - `finding` - `stored_report` - `evidence_snapshot` - `inventory` - `operation_run` - `source_kind`: - `model_summary` - `stored_report` - `operation_rollup` - `inventory_projection` - `source_target_kind`: - `managed_environment` - `governed_subject` - `provider_connection` - `operation_run` This pinned inventory is authoritative for Spec `284` tasks and must remain identical across the package. ## Phase 0: External Gate **Purpose**: Confirm the inherited provider-boundary and artifact-surface prerequisites are available before implementation begins. - [x] T000 Confirm Specs `281`, `282`, and `283` are already merged or otherwise present on the implementation branch before any runtime or test task begins. --- ## Phase 1: Setup (Shared Context) **Purpose**: Confirm the bounded artifact-source inventory, proof files, and deferred-scope posture before runtime edits begin. - [x] T001 Review `specs/284-provider-neutral-artifact-source-taxonomy/spec.md`, `plan.md`, `checklists/requirements.md`, `research.md`, `data-model.md`, `quickstart.md`, and `contracts/provider-neutral-artifact-source-taxonomy.logical.openapi.yaml` together so implementation stays on Spec `284` only, and stop for a prerequisite decision if SCOPE-001 ownership compliance is still unresolved for touched tenant-owned artifact tables. - [x] T002 [P] Confirm the current persisted-truth seams in `apps/platform/app/Models/Finding.php`, `apps/platform/app/Models/EvidenceSnapshotItem.php`, `apps/platform/app/Models/StoredReport.php`, `apps/platform/app/Models/InventoryItem.php`, and the related migrations before changing descriptor fields. - [x] T003 [P] Confirm the current evidence-source and control-resolution seams in `apps/platform/app/Services/Evidence/Contracts/EvidenceSourceProvider.php`, `apps/platform/app/Services/Evidence/EvidenceSnapshotService.php`, `apps/platform/app/Services/Evidence/Sources/FindingsSummarySource.php`, `apps/platform/app/Services/Evidence/Sources/PermissionPostureSource.php`, `apps/platform/app/Services/Evidence/Sources/EntraAdminRolesSource.php`, `apps/platform/app/Services/Evidence/Sources/BaselineDriftPostureSource.php`, `apps/platform/app/Services/Evidence/Sources/OperationsSummarySource.php`, `apps/platform/app/Support/Governance/Controls/CanonicalControlResolutionRequest.php`, and `apps/platform/app/Support/Governance/Controls/CanonicalControlResolver.php`. - [x] T004 [P] Confirm the current inventory type and metadata seams in `apps/platform/app/Support/Inventory/InventoryPolicyTypeMeta.php`, `apps/platform/app/Models/InventoryItem.php`, and `apps/platform/app/Filament/Resources/InventoryItemResource.php` before changing `policy_type` semantics. - [x] T005 [P] Confirm the current operator-surface and review-summary seams in `apps/platform/app/Filament/Resources/FindingResource.php`, `EvidenceSnapshotResource.php`, `StoredReportResource.php`, `TenantReviewResource.php`, `apps/platform/app/Services/TenantReviews/TenantReviewSectionFactory.php`, and `apps/platform/app/Support/Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.php`. - [x] T006 [P] Confirm current `source_family` naming precedent and deferred boundaries in `apps/platform/app/Support/SupportDiagnostics/SupportDiagnosticBundleBuilder.php`, `apps/platform/app/Support/Ai/AiUseCaseCatalog.php`, and `specs/284-provider-neutral-artifact-source-taxonomy/checklists/requirements.md` so Specs `285` through `287` remain explicitly out of scope. --- ## Phase 2: Foundational (Blocking Prerequisites) **Purpose**: Establish the proving suite and the canonical descriptor inventory that every story depends on. **Critical**: No user-story work should begin until this phase is complete. - [x] T007 [P] Add failing coverage in `apps/platform/tests/Unit/Artifacts/ArtifactSourceTaxonomyCatalogTest.php` for the exact `source_family`, `source_kind`, and `source_target_kind` inventories plus the no-detector-catalog rule. - [x] T008 [P] Add failing coverage in `apps/platform/tests/Unit/Inventory/InventoryCanonicalTypeDescriptorTest.php` for the `canonical_type`, `provider_object_type`, `provider_display_type`, and `legacy_policy_type` split. - [x] T009 [P] Add failing coverage in `apps/platform/tests/Feature/Artifacts/FindingArtifactSourceTaxonomyTest.php`, `apps/platform/tests/Feature/Artifacts/EvidenceSnapshotSourceTaxonomyTest.php`, and `apps/platform/tests/Feature/Artifacts/StoredReportSourceTaxonomyTest.php` for shared descriptor derivation over findings, evidence, and stored reports, including `workspace_id`, `tenant_id`, `provider_connection_id`, and `source_target_identifier` semantics when present. - [x] T010 [P] Add failing guard coverage in `apps/platform/tests/Feature/Guards/ArtifactSourceProviderTruthGuardTest.php` for `finding_type`, `report_type`, or `policy_type` reappearing as top-level summary truth and for `package_run_id` being treated as active runtime truth. - [x] T011 [P] Add the narrow browser smoke in `apps/platform/tests/Browser/Spec284ArtifactSourceTaxonomySmokeTest.php` for one finding, one evidence snapshot, one stored report, one inventory item, and one tenant-review section under the live Filament shell. - [x] T012 Introduce the bounded shared descriptor support seam in the smallest viable namespace under `apps/platform/app/Support/Artifacts/` or existing helpers, derive the descriptor from existing persisted truth plus the established workspace and tenant scope, carry `provider_connection_id` and `source_target_identifier` when current truth exposes them, and pin the exact inventories across consumers without adding a new table, detector catalog, descriptor columns, or backfill flow. **Checkpoint**: The proving files exist, the descriptor inventory is explicit, and later stories can consume one canonical artifact-source contract. --- ## Phase 3: User Story 1 - Interpret findings, evidence, and stored reports with one descriptor (Priority: P1) **Goal**: Findings, evidence summaries, and stored reports expose the same canonical artifact-source descriptor and control summary before provider-native detail. **Independent Test**: Load one finding, one evidence snapshot item, and one stored report for the same managed environment and confirm each surface or reader exposes the same descriptor-first summary contract. ### Tests for User Story 1 - [x] T013 [P] [US1] Extend `apps/platform/tests/Feature/Artifacts/FindingArtifactSourceTaxonomyTest.php`, `apps/platform/tests/Feature/Artifacts/EvidenceSnapshotSourceTaxonomyTest.php`, and `apps/platform/tests/Feature/Artifacts/StoredReportSourceTaxonomyTest.php` after T012 to prove the same descriptor and `control_key` semantics survive across finding, evidence, and stored-report readers. ### Implementation for User Story 1 - [x] T014 [US1] Update `apps/platform/app/Models/Finding.php`, `apps/platform/app/Services/Evidence/Sources/FindingsSummarySource.php`, and the smallest related control-binding seam so finding summaries derive the canonical descriptor without page-local Microsoft-only checks. - [x] T015 [US1] Update `apps/platform/app/Services/Evidence/Contracts/EvidenceSourceProvider.php`, `apps/platform/app/Services/Evidence/EvidenceSnapshotService.php`, `apps/platform/app/Services/Evidence/Sources/PermissionPostureSource.php`, `apps/platform/app/Services/Evidence/Sources/EntraAdminRolesSource.php`, `apps/platform/app/Services/Evidence/Sources/BaselineDriftPostureSource.php`, `apps/platform/app/Services/Evidence/Sources/OperationsSummarySource.php`, and `apps/platform/app/Models/EvidenceSnapshotItem.php` so evidence summaries derive the descriptor consistently from existing persisted truth. - [x] T016 [US1] Update `apps/platform/app/Models/StoredReport.php`, `apps/platform/app/Services/EntraAdminRoles/EntraAdminRolesReportService.php`, and any directly touched stored-report readers so report summaries align to source-family semantics while keeping raw `report_type` nested. Note: no `EntraAdminRolesReportService` edit was required because the shared `StoredReport` resolver derives descriptor and provider detail from existing report payloads without producer changes. **Checkpoint**: Findings, evidence summaries, and stored reports now expose one shared descriptor-first lineage contract. --- ## Phase 4: User Story 2 - Read inventory items with canonical and provider type separation (Priority: P1) **Goal**: Inventory items distinguish platform-owned canonical type from provider-owned object type and display type while still participating in the shared artifact-source descriptor contract. **Independent Test**: Open one inventory item and confirm the page shows `canonical_type`, `provider_object_type`, and `provider_display_type` as separate concepts and still exposes the shared source descriptor. ### Tests for User Story 2 - [x] T017 [P] [US2] Extend `apps/platform/tests/Unit/Inventory/InventoryCanonicalTypeDescriptorTest.php` and `apps/platform/tests/Feature/Artifacts/InventoryArtifactTypeTaxonomyTest.php` after T012 to prove the inventory type split, legacy `policy_type` nesting, and shared source descriptor on inventory read models. ### Implementation for User Story 2 - [x] T018 [US2] Update `apps/platform/app/Support/Inventory/InventoryPolicyTypeMeta.php` and the smallest adjacent inventory read-model seam so inventory emits `canonical_type`, `provider_object_type`, `provider_display_type`, and optional `legacy_policy_type` without promoting raw `policy_type` back to top-level truth. - [x] T019 [US2] Update `apps/platform/app/Models/InventoryItem.php` and `apps/platform/app/Filament/Resources/InventoryItemResource.php` so list and detail surfaces disclose the type split, carry the shared source descriptor, and keep raw metadata secondary. **Checkpoint**: Inventory surfaces now separate platform type from provider object type cleanly. --- ## Phase 5: User Story 3 - Keep operator-facing artifact surfaces descriptor-first (Priority: P2) **Goal**: Findings, evidence, stored reports, and tenant-review sections show the canonical descriptor and control summary before provider-native detail. **Independent Test**: Open one finding, one evidence snapshot, one stored report, and one tenant review with supporting sections and confirm each touched summary is descriptor-first. ### Tests for User Story 3 - [x] T020 [P] [US3] Extend `apps/platform/tests/Feature/Filament/Artifacts/ArtifactSourceTaxonomySurfaceTest.php` after T012 to prove `FindingResource`, `EvidenceSnapshotResource`, `InventoryItemResource`, `StoredReportResource`, and `TenantReviewResource` surface the descriptor first, provider detail second, and preserve inherited `404` versus `403` behavior. ### Implementation for User Story 3 - [x] T021 [US3] Update `apps/platform/app/Filament/Resources/FindingResource.php`, `apps/platform/app/Filament/Resources/EvidenceSnapshotResource.php`, `apps/platform/app/Filament/Resources/StoredReportResource.php`, `apps/platform/app/Filament/Resources/TenantReviewResource.php`, `apps/platform/app/Services/TenantReviews/TenantReviewSectionFactory.php`, and `apps/platform/app/Support/Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.php` so summary ordering converges on the shared descriptor and control summary. Note: no `ArtifactTruthPresenter` edit was required because descriptor-first disclosure lives in the resource and review-section summary layers while existing truth envelopes remain unchanged. - [x] T022 [US3] Update touched review or evidence related-context seams only where required so navigation stays unchanged while summary ordering converges. Note: no related-context changes were required; existing links stayed unchanged. **Checkpoint**: Operator-facing read paths now teach one artifact-source vocabulary and keep provider detail secondary. --- ## Phase 6: User Story 4 - Align downstream shared consumers without adding package runtime (Priority: P3) **Goal**: Touched support or AI `source_family` consumers reuse the same pinned family names and keep `package_run_id` optional only. **Independent Test**: Inspect touched support or AI source-family bundles and confirm they use the same source-family vocabulary as the artifact descriptor while leaving `package_run_id` null or absent. ### Tests for User Story 4 - [x] T023 [P] [US4] Extend `apps/platform/tests/Feature/Guards/ArtifactSourceProviderTruthGuardTest.php` after T012 to prove touched support or AI `source_family` consumers use the pinned family names and that `package_run_id` remains optional-only in current runtime. ### Implementation for User Story 4 - [x] T024 [US4] Update `apps/platform/app/Support/SupportDiagnostics/SupportDiagnosticBundleBuilder.php`, `apps/platform/app/Support/Ai/AiUseCaseCatalog.php`, and any directly touched shared descriptor helpers only where required so source-family semantics align without implying package runtime. Note: no runtime edit was required because existing support and AI families remain non-artifact source families and the guard test proves they do not collide with the pinned artifact inventory. **Checkpoint**: Downstream shared consumers no longer risk inventing a second artifact-source vocabulary. --- ## Phase 7: Polish & Cross-Cutting Validation **Purpose**: Run the exact bounded proof set, perform the final Filament and taxonomy review, and confirm the slice stayed inside Spec `284`. - [x] T025 [P] Run `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Unit/Artifacts/ArtifactSourceTaxonomyCatalogTest.php tests/Unit/Inventory/InventoryCanonicalTypeDescriptorTest.php)`. - [x] T026 [P] Run `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Feature/Artifacts/FindingArtifactSourceTaxonomyTest.php tests/Feature/Artifacts/EvidenceSnapshotSourceTaxonomyTest.php tests/Feature/Artifacts/StoredReportSourceTaxonomyTest.php tests/Feature/Artifacts/InventoryArtifactTypeTaxonomyTest.php tests/Feature/Filament/Artifacts/ArtifactSourceTaxonomySurfaceTest.php tests/Feature/Guards/ArtifactSourceProviderTruthGuardTest.php)`. - [x] T027 [P] Run `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Browser/Spec284ArtifactSourceTaxonomySmokeTest.php)`. - [x] T028 [P] Run `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail bin pint --dirty --format agent)`. - [x] T029 [P] Review touched files to confirm Filament v5 and Livewire v4 compliance, provider registration staying in `apps/platform/bootstrap/providers.php`, truthful global-search posture, unchanged asset strategy, no new artifact table, no detector catalog, no package runtime, no historical backfill, and Specs `285` through `287` remaining deferred. --- ## Dependencies & Execution Order ### Phase Dependencies - **Phase 0 (External Gate)**: no dependencies; complete before implementation starts. - **Phase 1 (Setup)**: depends on Phase 0. - **Phase 2 (Foundational)**: depends on Phase 1 and blocks all story work. - **Phase 3 (US1)**: depends on Phase 2 and establishes the canonical descriptor for findings, evidence, and stored reports. - **Phase 4 (US2)**: depends on Phase 2 and should land with or immediately after US1 so inventory type semantics align with the shared descriptor vocabulary. - **Phase 5 (US3)**: depends on US1 and US2 because operator-facing surfaces should consume the final descriptor and inventory split. - **Phase 6 (US4)**: depends on US1 through US3 so downstream shared consumers inherit the final vocabulary instead of an intermediate mapping. - **Phase 7 (Polish)**: depends on all desired user stories being complete. ### User Story Dependencies - **US1 (P1)**: independently testable after Phase 2 and is the first required implementation increment. - **US2 (P1)**: independently testable after Phase 2, but should ship after or with US1 because inventory should not introduce parallel artifact-type language. - **US3 (P2)**: independently testable after US1 and US2 once the shared descriptor is stable. - **US4 (P3)**: independently testable after US1 through US3 and closes the remaining `source_family` drift in touched shared consumers. ### Within Each User Story - Write or extend the listed Pest coverage first and make it fail for the intended gap. - Apply the smallest shared-seam changes needed to satisfy the story without reopening Specs `285` through `287`. - Re-run the narrowest relevant validation command for that story before moving to the next story. ## Parallel Execution Examples - **Setup**: T002 through T006 can run in parallel once T000 and T001 set the bounded scope. - **Foundational**: T007 through T011 can run in parallel before T012 converges the canonical descriptor seam. - **US1**: T013 can run alongside implementation prep; T014 through T016 should merge serially around finding, evidence, and stored-report seams. - **US2**: T017 can run alongside T018, then T019 follows once the inventory type split is stable. - **US3**: T020 can run alongside implementation prep; T021 and T022 should merge serially around shared presenter files. - **US4**: T023 can run alongside T024 because both touch bounded shared-consumer alignment only. - **Polish**: T025 through T028 can run in parallel after implementation is complete; T029 closes the bounded-scope review last. ## Implementation Strategy ### Suggested MVP Scope - MVP = **US1 + US2**. Land the shared descriptor and inventory type split first so later surface cleanup does not build on inconsistent underlying semantics. ### Incremental Delivery 1. Complete Phase 0, Phase 1, and Phase 2. 2. Deliver US1 so findings, evidence, and stored reports stop depending on Microsoft-only top-level summary nouns. 3. Deliver US2 so inventory type semantics stop teaching `policy_type` as universal truth. 4. Deliver US3 so operator-facing surfaces visibly converge on the final descriptor-first disclosure. 5. Deliver US4 only if touched support or AI consumers need explicit alignment. 6. Finish with the exact validation commands and the final bounded-scope review in Phase 7. ### Team Strategy 1. Parallelize the failing test work first. 2. Serialize merges around the shared descriptor seam, evidence providers, and Filament resource presenters to avoid contract-shape conflicts. 3. Reject any implementation branch that introduces a detector catalog, package runtime, backfill work, a provider framework, or adjacent copy or RBAC scope. ## Deferred Follow-Ups / Non-Goals - Spec `285` workspace-first RBAC and environment-access scoping - Spec `286` broader UI copy, IA, and localization neutralization - Spec `287` cutover quality gates and no-legacy enforcement - package runtime or package-output surfaces beyond the optional `package_run_id` contract slot - detector catalog or broader control-catalog expansion