diff --git a/app/Filament/Pages/InventoryCoverage.php b/app/Filament/Pages/InventoryCoverage.php
index b7214c5..39c8b34 100644
--- a/app/Filament/Pages/InventoryCoverage.php
+++ b/app/Filament/Pages/InventoryCoverage.php
@@ -2,6 +2,7 @@
namespace App\Filament\Pages;
+use App\Services\Inventory\CoverageCapabilitiesResolver;
use BackedEnum;
use Filament\Pages\Page;
use UnitEnum;
@@ -31,7 +32,24 @@ public function mount(): void
$policyTypes = config('tenantpilot.supported_policy_types', []);
$foundationTypes = config('tenantpilot.foundation_types', []);
- $this->supportedPolicyTypes = is_array($policyTypes) ? $policyTypes : [];
- $this->foundationTypes = is_array($foundationTypes) ? $foundationTypes : [];
+ $resolver = app(CoverageCapabilitiesResolver::class);
+
+ $this->supportedPolicyTypes = collect(is_array($policyTypes) ? $policyTypes : [])
+ ->map(function (array $row) use ($resolver): array {
+ $type = (string) ($row['type'] ?? '');
+
+ return array_merge($row, [
+ 'dependencies' => $type !== '' && $resolver->supportsDependencies($type),
+ ]);
+ })
+ ->all();
+
+ $this->foundationTypes = collect(is_array($foundationTypes) ? $foundationTypes : [])
+ ->map(function (array $row): array {
+ return array_merge($row, [
+ 'dependencies' => false,
+ ]);
+ })
+ ->all();
}
}
diff --git a/app/Services/Inventory/CoverageCapabilitiesResolver.php b/app/Services/Inventory/CoverageCapabilitiesResolver.php
new file mode 100644
index 0000000..217549e
--- /dev/null
+++ b/app/Services/Inventory/CoverageCapabilitiesResolver.php
@@ -0,0 +1,25 @@
+Type
Label |
Category |
+ Dependencies |
Restore |
Risk |
@@ -18,6 +19,7 @@
{{ $row['type'] ?? '' }} |
{{ $row['label'] ?? '' }} |
{{ $row['category'] ?? '' }} |
+ {{ ($row['dependencies'] ?? false) ? '✅' : '—' }} |
{{ $row['restore'] ?? 'enabled' }} |
{{ $row['risk'] ?? 'normal' }} |
@@ -36,6 +38,7 @@
Type |
Label |
Category |
+ Dependencies |
Restore |
Risk |
@@ -46,6 +49,7 @@
{{ $row['type'] ?? '' }} |
{{ $row['label'] ?? '' }} |
{{ $row['category'] ?? '' }} |
+ {{ ($row['dependencies'] ?? false) ? '✅' : '—' }} |
{{ $row['restore'] ?? 'enabled' }} |
{{ $row['risk'] ?? 'normal' }} |
diff --git a/specs/047-inventory-foundations-nodes/checklists/requirements.md b/specs/047-inventory-foundations-nodes/checklists/requirements.md
index 41259c9..408fb41 100644
--- a/specs/047-inventory-foundations-nodes/checklists/requirements.md
+++ b/specs/047-inventory-foundations-nodes/checklists/requirements.md
@@ -17,6 +17,7 @@ ## Feature 047 Functional Coverage
- [x] FR-002 include_foundations=false produces no foundation node sync side effects.
- [x] FR-003 Foundation nodes stored as InventoryItems with stable identity (tenant_id + policy_type + external_id).
- [x] FR-004 Inventory Coverage UI shows Policies + Foundations.
+- [x] FR-COV-DEP: Coverage shows deterministic Dependencies support column (✅/—) derived from existing capabilities (no Graph calls).
- [x] FR-005 Inventory Items UI can filter/browse foundations.
## Test Gates
diff --git a/specs/047-inventory-foundations-nodes/spec.md b/specs/047-inventory-foundations-nodes/spec.md
index 8313383..79f2356 100644
--- a/specs/047-inventory-foundations-nodes/spec.md
+++ b/specs/047-inventory-foundations-nodes/spec.md
@@ -98,6 +98,27 @@ ### FR-004 Inventory Coverage UI
- “Policies” table (existing behavior)
- “Foundations” table (new; derived from `tenantpilot.foundation_types`)
+#### FR-COV-DEP-001 Dependencies column
+Coverage MUST display an additional column:
+- Header: `Dependencies`
+- Value: `✅` or `—`
+
+#### FR-COV-DEP-002 Deterministic derivation
+The `Dependencies` value MUST be derived deterministically from existing capabilities (config/contracts) only:
+
+`✅` if at least one holds:
+- the type supports Assignments extraction, or
+- the type supports Scope Tags, or
+- the type can reference Assignment Filters, or
+- the type has dependency extraction rules in Spec 042 (relationship taxonomy / extractor mapping)
+
+Otherwise: `—`.
+
+This is **feature support**, not “Graph supports $expand”.
+
+MVP decision:
+- For foundation types, default to `—`.
+
### FR-005 Inventory Items UI
Inventory Items list MUST allow:
- filtering to Foundations (e.g., Category = Foundations)
diff --git a/specs/047-inventory-foundations-nodes/tasks.md b/specs/047-inventory-foundations-nodes/tasks.md
index 1be837c..88eb6ba 100644
--- a/specs/047-inventory-foundations-nodes/tasks.md
+++ b/specs/047-inventory-foundations-nodes/tasks.md
@@ -70,6 +70,12 @@ ## Phase 5: User Story 3 — Coverage communication (Priority: P2)
- [ ] T015 [US3] Update Coverage Blade view to render two tables in resources/views/filament/pages/inventory-coverage.blade.php
- [ ] T016 [P] [US3] Add/adjust Pest test assertions for both headings in tests/Feature/Filament/InventoryPagesTest.php
+### Coverage Dependencies Support (UI-only)
+
+- [x] T026 [US3] Add Coverage table column `Dependencies` (✅/—) in resources/views/filament/pages/inventory-coverage.blade.php
+- [x] T027 [US3] Add deterministic resolver CoverageCapabilitiesResolver::supportsDependencies($type) (contracts/config derived) + unit test in tests/Unit/CoverageCapabilitiesResolverTest.php
+- [x] T028 [P] [US3] Update Pest UI/feature test to assert Coverage renders `Dependencies` column and at least one ✅ in tests/Feature/Filament/InventoryPagesTest.php
+
---
## Phase 6: User Story 4 — Resolve dependency names (Priority: P3)
diff --git a/tests/Feature/Filament/InventoryPagesTest.php b/tests/Feature/Filament/InventoryPagesTest.php
index 21f0ab8..2ec5039 100644
--- a/tests/Feature/Filament/InventoryPagesTest.php
+++ b/tests/Feature/Filament/InventoryPagesTest.php
@@ -25,5 +25,7 @@
->assertOk()
->assertSee('Coverage')
->assertSee('Policies')
- ->assertSee('Foundations');
+ ->assertSee('Foundations')
+ ->assertSee('Dependencies')
+ ->assertSee('✅');
});
diff --git a/tests/Unit/CoverageCapabilitiesResolverTest.php b/tests/Unit/CoverageCapabilitiesResolverTest.php
new file mode 100644
index 0000000..de5e818
--- /dev/null
+++ b/tests/Unit/CoverageCapabilitiesResolverTest.php
@@ -0,0 +1,14 @@
+supportsDependencies($type))->toBe($expected);
+})->with([
+ 'settingsCatalogPolicy' => ['settingsCatalogPolicy', true],
+ 'deviceConfiguration' => ['deviceConfiguration', true],
+ 'conditionalAccessPolicy' => ['conditionalAccessPolicy', false],
+ 'roleScopeTag (foundation, MVP)' => ['roleScopeTag', false],
+]);