# Implementation Plan: Foundations in Inventory (047) **Branch**: `feat/047-inventory-foundations-nodes` | **Date**: 2026-01-10 | **Spec**: `specs/047-inventory-foundations-nodes/spec.md` **Input**: Feature specification from `specs/047-inventory-foundations-nodes/spec.md` **Note**: This template is filled in by the `/speckit.plan` command. See `.specify/scripts/` for helper scripts. ## Summary When `include_foundations=true`, inventory sync includes all configured foundation types (`roleScopeTag`, `assignmentFilter`, `notificationMessageTemplate`) as `InventoryItem` records for the tenant. Inventory Coverage and Inventory Items UI surface foundations alongside policies, enabling Spec 042.2 dependency target name resolution from the local DB (no UI Graph lookups). ## Technical Context **Language/Version**: PHP 8.4.x (Laravel 12) **Primary Dependencies**: Laravel 12, Filament v4, Livewire v3 **Storage**: PostgreSQL (JSONB for `InventoryItem.meta_jsonb`) **Testing**: Pest v4 + PHPUnit; formatting via Pint **Target Platform**: Web admin app (Filament) + queued jobs (Sail-first locally) **Project Type**: Web application **Performance Goals**: No new explicit perf goals; foundations are small cardinality and must not introduce N+1 or full-table loads. **Constraints**: Must preserve inventory sync idempotency, locks, and run observability; no UI-time Graph calls for name resolution. **Scale/Scope**: Tenant-scoped inventory; foundations expected to be small compared to policies. ## Constitution Check *GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* - Inventory-first: clarify what is “last observed” vs snapshots/backups - Read/write separation: any writes require preview + confirmation + audit + tests - Graph contract path: Graph calls only via `GraphClientInterface` + `config/graph_contracts.php` - Deterministic capabilities: capability derivation is testable (snapshot/golden tests) - Tenant isolation: all reads/writes tenant-scoped; cross-tenant views are explicit and access-checked - Automation: queued/scheduled ops are locked, idempotent, observable; handle 429/503 with backoff+jitter - Data minimization: Inventory stores metadata + whitelisted meta; logs contain no secrets/tokens **Result**: PASS (no violations). - Inventory-first: foundations become `InventoryItem` “last observed” state. - Read/write separation: sync remains read-only (Graph reads only). - Graph contract path: foundation types are already represented in `config/graph_contracts.php` and accessed via `GraphClientInterface`. - Tenant isolation: all upserts keyed by `(tenant_id, policy_type, external_id)`. - Data minimization: still uses `InventoryMetaSanitizer` to store only safe subset. ## Project Structure ### Documentation (this feature) ```text specs/[###-feature]/ ├── plan.md # This file (/speckit.plan command output) ├── research.md # Phase 0 output (/speckit.plan command) ├── data-model.md # Phase 1 output (/speckit.plan command) ├── quickstart.md # Phase 1 output (/speckit.plan command) ├── contracts/ # Phase 1 output (/speckit.plan command) └── tasks.md # Phase 2 output (/speckit.tasks command - NOT created by /speckit.plan) ``` ### Source Code (repository root) ```text app/ ├── Filament/ │ ├── Pages/ │ │ └── InventoryCoverage.php │ └── Resources/ │ └── InventoryItemResource.php └── Services/ └── Inventory/ └── InventorySyncService.php config/ ├── tenantpilot.php └── graph_contracts.php resources/ └── views/ └── filament/ └── pages/ └── inventory-coverage.blade.php tests/ └── Feature/ ├── Filament/ │ └── InventoryPagesTest.php └── Inventory/ └── InventorySyncServiceTest.php ``` **Structure Decision**: Web application (Laravel + Filament). No new directories introduced. ## Complexity Tracking > **Fill ONLY if Constitution Check has violations that must be justified** N/A (no constitution violations). ## Phase 0: Research Output - Generated: `specs/047-inventory-foundations-nodes/research.md` - Key outcomes: - Foundations are synced via the existing inventory sync flow. - Graph contracts already cover the three foundation types. ## Phase 1: Design & Contracts Output - Data model: `specs/047-inventory-foundations-nodes/data-model.md` - Contracts: - `specs/047-inventory-foundations-nodes/contracts/inventory-selection.schema.json` - `specs/047-inventory-foundations-nodes/contracts/inventory-coverage.schema.json` - Quickstart: `specs/047-inventory-foundations-nodes/quickstart.md` ## Phase 2: Implementation Checklist (high level) - Inventory sync respects `include_foundations` selection semantics. - Foundations appear in Inventory Items list (filterable) and Coverage page. - Tests cover tenant isolation + include_foundations on/off behavior.