spec: add inventory specs 039-044

This commit is contained in:
Ahmed Darrazi 2026-01-07 14:58:39 +01:00
parent 3465076a04
commit 6a27609875
18 changed files with 685 additions and 0 deletions

View File

@ -0,0 +1,17 @@
# Implementation Plan: Inventory Program (Meta)
**Branch**: `feat/039-inventory-program` | **Date**: 2026-01-07 | **Spec**: `specs/039-inventory-program/spec.md`
## Summary
Program-level north star and decomposition for the Inventory-first roadmap.
## Deliverables
- A shared vocabulary and boundaries (Inventory vs Snapshot/Backup)
- A roadmap to split delivery into 040044 feature specs
- Program principles aligned with constitution
## Notes
This spec is not tied to code changes.

View File

@ -0,0 +1,55 @@
# Feature Specification: Inventory Program (Meta)
**Feature Branch**: `feat/039-inventory-program`
**Created**: 2026-01-07
**Status**: Draft
## Purpose
This is an epic/program-level specification that anchors vision, scope, principles, and a roadmap for an Inventory-first approach across TenantPilot.
This document is intentionally non-implementation and does not require immediate code changes.
## Program Goals
- Establish Inventory as the primary substrate for analysis, reporting, monitoring, and UI navigation (Inventory is “last observed”, not absolute Intune truth).
- Maintain immutable snapshots/backups as explicit actions (manual/scheduled), separate from inventory sync.
- Provide a config-driven coverage/support matrix across policy types (backup/restore/risk/support).
- Build toward dependency visibility, cross-tenant comparison/promotion, and drift detection.
## Key Definitions
- **Inventory**: TenantPilots last observed catalog of Intune objects (mutable; updated by sync runs).
- **Snapshot/Backup**: Immutable capture of an objects payload for versioning/restore (explicit action).
- **Coverage/Support Matrix**: Derived view describing support level (backup/restore/risk) per policy type.
## Data Domains
- Inventory Items
- Sync Runs (observability)
- Support/Capabilities derived from contracts/config
- Dependencies (links between inventory items and foundation objects)
- Cross-tenant context (explicit and access-checked)
## Principles (Program-level)
- Inventory-first, snapshots-second
- Read/write separation by default (preview + confirmation + audit + tests for writes)
- Single contract path to Graph
- Deterministic capabilities
- Tenant isolation is non-negotiable
- Automation is idempotent & observable (locks, run records, stable error codes)
- Data minimization & safe logging
## Roadmap / Decomposition
- **Spec 040 — Inventory Core**: inventory items + sync runs + deterministic selection + missing semantics
- **Spec 041 — Inventory UI**: inventory lists, coverage matrix, sync runs UI, policy viewer
- **Spec 042 — Dependencies Graph**: inventory_links and dependency views (assignments/scope tags/filters first)
- **Spec 043 — Cross-tenant Compare & Promotion**: read-only compare first; gated promotion later
- **Spec 044 — Drift MVP**: drift findings based on inventory/run metadata and optional hashes
## Non-Goals
- This meta spec does not define concrete schemas or endpoints.
- This meta spec does not introduce new write paths (promotion/remediation) without dedicated feature specs.

View File

@ -0,0 +1,7 @@
# Tasks: Inventory Program (Meta)
**Input**: `specs/039-inventory-program/spec.md`
- [ ] T001 Confirm naming/numbering for 040044
- [ ] T002 Draft skeleton specs for 041044
- [ ] T003 Validate alignment with constitution principles

View File

@ -0,0 +1,32 @@
# Implementation Plan: Inventory Core (040)
**Branch**: `feat/040-inventory-core` | **Date**: 2026-01-07 | **Spec**: `specs/040-inventory-core/spec.md`
## Summary
Implement a tenant-scoped inventory catalog (“last observed”) and an observable sync run system with deterministic selection scoping. Ensure no snapshots/backups are created by sync.
## Constitution Check
- Inventory-first, snapshots-second (sync never creates snapshots)
- Read/write separation (sync is read-only; any future writes require preview/confirmation/audit/tests)
- Single contract path to Graph (Graph access only through existing abstractions/contracts)
- Deterministic capabilities (capabilities resolver output testable)
- Tenant isolation (non-negotiable)
- Automation observable + idempotent (locks, run records, stable error codes, 429/503 handling)
- Data minimization + safe logging
## Deliverables (Phase-friendly)
- Data model for inventory items and sync runs
- Sync engine orchestration and locking strategy
- Deterministic selection hashing
- Capabilities resolver output snapshot tests
- Minimal Filament/CLI surface to trigger and observe sync runs (if required by tasks)
## Out of Scope
- Dependency graph hydration (spec 042)
- Cross-tenant promotion (spec 043)
- Drift reporting (spec 044)
- Lifecycle “deleted” semantics (feature 900)

View File

@ -0,0 +1,176 @@
# Feature Specification: Inventory Core (Sync + Catalog)
**Feature Branch**: `feat/040-inventory-core`
**Created**: 2026-01-07
**Status**: Draft
## Overview
TenantPilot needs a reliable, tenant-scoped inventory catalog that represents what the system last observed in Microsoft Intune. This inventory is used as the primary substrate for analysis, reporting, monitoring, and UI visibility.
**Key intent:** Inventory is a “last observed” catalog (TenantPilots truth), not an absolute truth about Intune completeness.
**Non-goal:** A sync MUST NOT create snapshots or backups automatically.
## User Scenarios & Testing *(mandatory)*
### User Story 1 — Run Inventory Sync for a Tenant (Priority: P1)
A tenant admin (or scheduled automation) runs an inventory sync for a tenant to populate/update the inventory catalog.
**Why this priority**: Everything else depends on having a stable, queryable inventory catalog.
**Independent Test**: Run a sync for a tenant and verify inventory items are upserted, tenant-scoped, and last-observed fields update without producing snapshots/backups.
**Acceptance Scenarios**:
1. **Given** a tenant and a configured selection of policy types/categories, **When** a sync completes, **Then** inventory items are upserted for each observed object with correct `tenant_id`, `policy_type`, `external_id`, and `last_seen_at`.
2. **Given** an existing inventory item, **When** the same object is observed again, **Then** the existing record is updated (not duplicated) and `last_seen_at` and `last_seen_run_id` are updated.
3. **Given** a sync selection that excludes some policy types/categories, **When** the sync completes, **Then** only objects within that selection are observed/updated.
4. **Given** a successful sync, **When** the sync finishes, **Then** no policy snapshots/backups are created as a side effect.
---
### User Story 2 — Observe Completeness/Confidence of a Sync (Priority: P1)
A tenant admin views whether missing items are likely “not seen” due to partial/failed sync vs confidently missing in a clean run.
**Why this priority**: Prevents misleading conclusions (e.g., “deleted”) when Graph errors or permissions issues occur.
**Independent Test**: Mark a run as partial/failed and verify missing items are presented as low confidence (derived at query/UI time) and do not imply deletion.
**Acceptance Scenarios**:
1. **Given** a `latestRun` for a tenant+selection that has `status != success` or `had_errors = true`, **When** inventory is queried for missing items relative to that run, **Then** missing is presented as low confidence (and no stronger claim is made).
2. **Given** a `latestRun` for a tenant+selection that is `status = success` and `had_errors = false`, **When** an item was not observed in that run, **Then** the UI can show it as “not seen in latest run” (higher confidence) without implying deletion.
---
### User Story 3 — Monitor Sync Runs (Priority: P2)
A tenant admin (and platform admin) can see sync run history and quickly diagnose failures using stable error codes and counts.
**Why this priority**: Makes automation observable and supportable at MSP scale.
**Independent Test**: Create sync runs with different statuses and verify run records include counts and stable error codes.
**Acceptance Scenarios**:
1. **Given** multiple sync runs, **When** a user views run history, **Then** each run shows status, started/finished timestamps, and counts (observed/updated/errors).
2. **Given** a throttling event, **When** a sync run records it, **Then** the run captures a stable error code (e.g., “graph_throttled”) and does not fail silently.
---
### Edge Cases
- Sync is triggered twice for the same tenant+selection while the first is still running.
- Sync completes with partial results due to transient Graph errors.
- A tenants permissions change between runs causing objects to be invisible.
- Selection payload is equivalent but arrays are ordered differently.
## Requirements *(mandatory)*
### Functional Requirements
- **FR-001**: System MUST maintain an Inventory Catalog that represents TenantPilots last observed state of Intune objects.
- **FR-002**: System MUST upsert inventory items by a stable identity key that prevents duplicates.
- **FR-003**: System MUST record Sync Runs with status, timestamps, counts, and stable error codes.
- **FR-004**: System MUST ensure tenant isolation for all inventory and run queries.
- **FR-005**: System MUST support deterministic selection scoping via `selection_hash` for sync runs.
- **FR-006**: System MUST NOT create snapshots/backups during inventory sync (sync is not backup).
- **FR-007**: System MUST derive “missing” as a computed state relative to the latest completed run for the same tenant+selection.
- **FR-008**: System MUST enforce `meta_jsonb` key whitelisting by dropping unknown keys without failing the sync.
- **FR-009**: System MUST implement safe automation behavior: locking, idempotency, and observable failures.
### Non-Functional Requirements
- **NFR-001 (Concurrency limits)**: Sync automation MUST enforce two limits: a global concurrency limit (across tenants) and a per-tenant concurrency limit.
- **NFR-002 (Throttling resilience)**: Sync MUST handle throttling/transient failures (e.g., 429/503) using backoff + jitter.
- **NFR-003 (Deterministic behavior)**: Selection hashing and capability derivation MUST be deterministic and testable.
- **NFR-004 (Data minimization)**: Inventory MUST store metadata and whitelisted meta only; payload-heavy content belongs to snapshots/backups.
- **NFR-005 (Safe logging)**: Logs MUST not contain secrets/tokens; monitoring MUST rely on run records + error codes.
### Key Entities *(include if feature involves data)*
- **Inventory Item**: A tenant-scoped record representing a single Intune object as last observed (type, external identity, display name/metadata, last observed fields, whitelisted meta).
- **Sync Run**: A tenant-scoped record representing an inventory sync execution for a specific selection (selection_hash, status, timestamps, counts, stable error codes).
- **Selection Payload**: The normalized representation of the run scope used to compute selection_hash.
## Success Criteria *(mandatory)*
### Measurable Outcomes
- **SC-001**: For a given tenant, inventory sync can be executed repeatedly without creating duplicate inventory items.
- **SC-002**: A sync run always produces a run record with status, timestamps, and counts.
- **SC-003**: Missing is computed relative to latest completed run for the same tenant+selection; runs with different selection hashes do not affect each other.
- **SC-004**: Unknown meta keys never break sync and are not persisted.
- **SC-005**: Operators can distinguish “not seen” from “deleted” (deleted is reserved and not produced in this feature).
## Spec Appendix: Deterministic Selection + Missing Semantics (copy/paste-ready)
### Definition: “completed” and “latestRun”
- **Definition:** `completed` means `status ∈ {success, partial, failed, skipped}` and `finished_at != null` (or the equivalent field used by the run model).
- **Definition:** `latestRun` is the latest completed Sync Run for `(tenant_id, selection_hash)`.
### Selection Hash
- `selection_payload` includes only fields that influence run scope:
- `policy_types[]`, `categories[]`, `include_foundations` (bool), `include_dependencies` (bool)
- `canonical_json(payload)` is a canonical JSON serialization with:
- sorted object keys
- sorted arrays for `policy_types` and `categories`
- no whitespace / pretty formatting
- `selection_hash = sha256(canonical_json(selection_payload))`
- **AC:** Identical selection payload ⇒ identical selection_hash (independent of array ordering).
### Missing is derived (not persisted)
- **Definition:** Missing is a derived state computed at query/UI time relative to `latestRun(tenant_id, selection_hash)`.
- **AC:** Runs with different `selection_hash` do not affect missing computation for other selections.
- If `latestRun.status != success` or `latestRun.had_errors = true`, items not observed in that run are presented as `missing (low confidence)`.
### Deleted is reserved
- `deleted` is reserved and MUST NOT be produced by this feature.
- Only a later lifecycle feature may set `deleted` with strict verification rules.
### Meta Whitelist (Fail-safe)
- `meta_jsonb` has a documented whitelist of allowed keys.
- **AC:** Unknown `meta_jsonb` keys are dropped (not persisted) and MUST NOT cause sync to fail.
### Observed Run
- `inventory_items.last_seen_run_id` and `inventory_items.last_seen_at` are updated when an item is observed.
- `last_seen_run_id` implies the selection via `sync_runs.selection_hash`; no per-item selection hash is required for core.
## Testing Guidance (non-implementation)
These are test cases expressed in behavior terms (not code).
### Test Cases — Sync and Upsert
- **TC-001**: Sync creates or updates inventory items and sets `last_seen_at`.
- **TC-002**: Re-running sync for the same tenant+selection updates existing records and does not create duplicates.
- **TC-003**: Inventory queries scoped to Tenant A never return Tenant Bs items.
### Test Cases — Selection Hash Determinism
- **TC-010**: Same selection payload with arrays in different order yields the same selection_hash.
- **TC-011**: Different selection payload yields a different selection_hash.
### Test Cases — Missing Semantics
- **TC-020**: Missing is derived relative to latest completed run for the same tenant+selection.
- **TC-021**: A run for selection Y does not affect missing computation for selection X.
- **TC-022**: If latestRun is partial/failed or had_errors, missing is shown as low confidence.
### Test Cases — Meta Whitelist
- **TC-030**: Unknown meta keys are not persisted and do not fail sync.
### Test Cases — Automation Safety
- **TC-040**: Concurrent sync triggers for the same tenant+selection do not result in overlapping runs (lock behavior).
- **TC-041**: A throttling event results in a visible, stable error code and a non-silent failure signal.

View File

@ -0,0 +1,33 @@
# Tasks: Inventory Core (040)
**Input**: `specs/040-inventory-core/spec.md`, `specs/040-inventory-core/plan.md`
## P1 — MVP (US1/US2)
- [ ] T001 [US1] Define Inventory Item data model (tenant-scoped identity + last_seen fields)
- [ ] T002 [US1] Define Sync Run data model (tenant_id, selection_hash, status, timestamps, counts, stable error codes)
- [ ] T003 [US1] Implement deterministic selection hashing (canonical json + sha256)
- [ ] T004 [US1] Implement inventory upsert semantics (no duplicates)
- [ ] T005 [US1] Enforce tenant isolation in all inventory/run queries
- [ ] T006 [US2] Implement derived “missing” computation relative to latest completed run (tenant_id + selection_hash)
- [ ] T007 [US2] Ensure low-confidence missing when latestRun is partial/failed or had_errors
- [ ] T008 [US2] Implement meta_jsonb whitelist enforcement (drop unknown keys, never fail sync)
## P2 — Observability & Safety (US3 + NFR)
- [ ] T009 [US3] Ensure run records include stable error codes and counts
- [ ] T010 [NFR] Add idempotency + locks to prevent overlapping runs per tenant+selection
- [ ] T011 [NFR] Add global + per-tenant concurrency limiting strategy
- [ ] T012 [NFR] Implement throttling handling strategy (backoff + jitter for transient Graph failures)
## Tests (Required for runtime behavior)
- [ ] T020 [US1] Tests: upsert does not create duplicates; last_seen updated
- [ ] T021 [US2] Tests: missing derived per latestRun(selection_hash); selection isolation
- [ ] T022 [US2] Tests: partial/failed run => low confidence missing
- [ ] T023 [US2] Tests: meta whitelist drops unknown keys without failing
- [ ] T024 [NFR] Tests: selection_hash determinism (array ordering)
## Notes
- “deleted” is reserved and MUST NOT be produced in this feature.

View File

@ -0,0 +1,24 @@
# Implementation Plan: Inventory UI
**Date**: 2026-01-07
**Spec**: `specs/041-inventory-ui/spec.md`
## Summary
Add admin screens for inventory browsing, item inspection, sync run visibility, and type coverage/capabilities.
## Dependencies
- Inventory core data + sync runs available (Spec 040)
- Capabilities/support matrix derivation available
## Deliverables
- Inventory landing + list + detail
- Sync runs list + detail
- Coverage/capabilities view
## Risks
- UI performance for large tenants
- Data leakage if raw payload rendering is not constrained

View File

@ -0,0 +1,71 @@
# Feature Specification: Inventory UI
**Feature Branch**: `feat/041-inventory-ui`
**Created**: 2026-01-07
**Status**: Draft
## Purpose
Provide a consistent admin UI for browsing Inventory, understanding sync status, and seeing capability/coverage information per policy type.
## Users
- Tenant Admin (primary)
- MSP Operator (if cross-tenant access exists; read-only unless explicitly allowed)
## User Scenarios & Testing
### Scenario 1: Browse inventory
- Given a tenant context
- When the user opens Inventory
- Then they can browse inventory items by type and see core fields (name, platform/type, last observed, status)
### Scenario 2: Inspect a single inventory item
- Given an inventory item exists
- When the user opens the item details
- Then they can see normalized metadata and the latest observed payload (or a safe subset if full payload is not available)
### Scenario 3: See sync run outcomes
- Given sync runs exist
- When the user opens Sync Runs
- Then they can see run status, timing, counts, and error summaries
### Scenario 4: Understand coverage/capabilities
- Given the system has a support matrix
- When the user views the coverage table
- Then they can see which types are supported for backup/restore/preview and any restrictions
## Functional Requirements
- FR1: Provide an Inventory landing view scoped to the current tenant.
- FR2: Provide inventory list views grouped by policy type (or category) with pagination/search.
- FR3: Provide an inventory item detail view showing:
- stable identifiers
- last observed timestamps
- source run reference
- capability/support status for the items type
- FR4: Provide a Sync Runs list/detail view.
- FR5: Provide a Coverage/Capabilities view derived from configuration/contract registry.
- FR6: Enforce tenant isolation in all navigation and data access.
## Non-Functional Requirements
- NFR1: Pages should remain usable for tenants with large inventories (no full-table loads).
- NFR2: UI must not expose secrets or unsafe payload fields.
- NFR3: Errors should be actionable (clear messages + stable error codes where available).
## Success Criteria
- SC1: Admins can find an inventory item and view its details in under 60 seconds.
- SC2: Admins can identify the latest completed sync run for a tenant in under 30 seconds.
- SC3: Coverage view communicates support level clearly enough that admins make the correct decision without trial-and-error.
## Out of Scope
- Writing changes back to Intune from inventory screens (restore/promotion).
- Cross-tenant comparison (covered in Spec 043).
## Related Specs
- Program: `specs/039-inventory-program/spec.md`
- Core: `specs/040-inventory-core/spec.md`

View File

@ -0,0 +1,9 @@
# Tasks: Inventory UI
- [ ] T001 Inventory landing page + navigation
- [ ] T002 Inventory list views per type/category
- [ ] T003 Inventory detail view with capability/support indicator
- [ ] T004 Sync runs list + detail
- [ ] T005 Coverage/capabilities view derived from config/contracts
- [ ] T006 Authorization + tenant isolation tests
- [ ] T007 Performance sanity checks (pagination/search)

View File

@ -0,0 +1,24 @@
# Implementation Plan: Inventory Dependencies Graph
**Date**: 2026-01-07
**Spec**: `specs/042-inventory-dependencies-graph/spec.md`
## Summary
Add dependency edge model, extraction logic, and UI views to explain relationships between inventory items and prerequisite/foundation objects.
## Dependencies
- Inventory items and stable identifiers (Spec 040)
- Inventory UI detail pages (Spec 041) or equivalent navigation
## Deliverables
- Relationship taxonomy
- Persisted dependency edges
- Query and rendering in UI
## Risks
- Heterogeneous reference shapes across policy types
- Edge explosion for large tenants

View File

@ -0,0 +1,54 @@
# Feature Specification: Inventory Dependencies Graph
**Feature Branch**: `feat/042-inventory-dependencies-graph`
**Created**: 2026-01-07
**Status**: Draft
## Purpose
Represent and surface dependency relationships between inventory items and foundational Intune objects so admins can understand blast radius and prerequisites.
## User Scenarios & Testing
### Scenario 1: View dependencies for an item
- Given an inventory item
- When the user opens its dependencies view
- Then they can see inbound and outbound relationships (e.g., “uses”, “assigned to”, “scoped by”)
### Scenario 2: Identify missing prerequisites
- Given an item references a prerequisite object not present in inventory
- When the user views dependencies
- Then missing prerequisites are clearly indicated
### Scenario 3: Filter dependencies by relationship type
- Given multiple relationship types exist
- When the user filters by relationship type
- Then only matching edges are shown
## Functional Requirements
- FR1: Define a normalized set of relationship types.
- FR2: Store dependency edges between inventory items and other objects (including non-inventory foundations when applicable).
- FR3: Allow querying inbound/outbound edges for a given item.
- FR4: Show missing prerequisites without requiring a separate “deleted” state in core inventory.
- FR5: All dependency data is tenant-scoped and access-controlled.
## Non-Functional Requirements
- NFR1: Dependency extraction must be idempotent (re-runnable without duplicating edges).
- NFR2: Dependency extraction must not fail an inventory sync run if an unknown/unsupported reference is encountered; it should record a safe warning.
## Success Criteria
- SC1: Admins can determine prerequisites and blast radius for an item in under 2 minutes.
- SC2: For supported relationship types, dependency edges are consistent across re-runs (deterministic output).
## Out of Scope
- Automatic remediation.
- Cross-tenant dependency graphs.
## Related Specs
- Program: `specs/039-inventory-program/spec.md`
- Core: `specs/040-inventory-core/spec.md`

View File

@ -0,0 +1,7 @@
# Tasks: Inventory Dependencies Graph
- [ ] T001 Define relationship taxonomy
- [ ] T002 Add dependency edge storage and indexes
- [ ] T003 Extraction pipeline (idempotent)
- [ ] T004 Item-level dependencies UI
- [ ] T005 Tests for edge determinism and tenant scoping

View File

@ -0,0 +1,24 @@
# Implementation Plan: Cross-tenant Compare and Promotion
**Date**: 2026-01-07
**Spec**: `specs/043-cross-tenant-compare-and-promotion/spec.md`
## Summary
Introduce read-only cross-tenant comparison views; optionally add promotion with strong safety gates.
## Dependencies
- Inventory core + UI (Specs 040041)
- Strong authorization model for multi-tenant access
## Deliverables
- Tenant selection + comparison view
- Safe diff output and export
- (Optional) gated promotion workflow
## Risks
- Data leakage across tenants
- Over-scoping promotion beyond safe MVP

View File

@ -0,0 +1,59 @@
# Feature Specification: Cross-tenant Compare and Promotion
**Feature Branch**: `feat/043-cross-tenant-compare-and-promotion`
**Created**: 2026-01-07
**Status**: Draft
## Purpose
Enable safe cross-tenant comparison of inventory and, optionally, controlled promotion workflows.
Comparison is read-only by default. Any write/promotion behavior must be explicitly gated, audited, and separately authorized.
## User Scenarios & Testing
### Scenario 1: Compare two tenants (read-only)
- Given the operator has access to Tenant A and Tenant B
- When they select two tenants and a set of policy types
- Then they can see differences in presence and key metadata
### Scenario 2: Compare with a stable reference
- Given a reference selection scope
- When the operator runs comparison
- Then results are stable and reproducible for that scope
### Scenario 3: Promotion is explicitly gated (optional)
- Given promotion is enabled by policy
- When the operator initiates promotion
- Then the system requires explicit confirmation and records an audit event
## Functional Requirements
- FR1: Support selecting two tenants within authorized scope.
- FR2: Provide read-only diff views based on inventory metadata and stable identifiers.
- FR3: Provide exportable comparison results.
- FR4: If promotion is included:
- require explicit enablement
- require explicit confirmation per operation
- record audit logs
- support dry-run/preview
## Non-Functional Requirements
- NFR1: Enforce tenant isolation and least privilege across tenant selection and data access.
- NFR2: Comparison must not expose secrets or unsafe payload fields.
## Success Criteria
- SC1: Operators can identify which tenant differs for a given policy type in under 2 minutes.
- SC2: Read-only comparisons are reproducible when run again with the same scope.
## Out of Scope
- Bulk remediation without preview/confirmation.
## Related Specs
- Program: `specs/039-inventory-program/spec.md`
- Core: `specs/040-inventory-core/spec.md`
- Drift: `specs/044-drift-mvp/spec.md`

View File

@ -0,0 +1,7 @@
# Tasks: Cross-tenant Compare and Promotion
- [ ] T001 Define authorized tenant selection rules
- [ ] T002 Read-only compare UI and diff rules
- [ ] T003 Export capability for comparison results
- [ ] T004 If enabled: promotion workflow with preview + confirm + audit
- [ ] T005 Tests: tenant isolation, authorization, reproducibility

View File

@ -0,0 +1,24 @@
# Implementation Plan: Drift MVP
**Date**: 2026-01-07
**Spec**: `specs/044-drift-mvp/spec.md`
## Summary
Add drift findings generation and UI using inventory and sync run metadata.
## Dependencies
- Inventory core + run tracking (Spec 040)
- Inventory UI patterns (Spec 041)
## Deliverables
- Baseline definition and drift finding generation
- Drift summary + detail UI
- Acknowledge/triage actions
## Risks
- False positives if baseline definition is unclear
- Data volume for large tenants

View File

@ -0,0 +1,55 @@
# Feature Specification: Drift MVP
**Feature Branch**: `feat/044-drift-mvp`
**Created**: 2026-01-07
**Status**: Draft
## Purpose
Detect and report drift between expected and observed states using inventory and run metadata.
This MVP focuses on reporting and triage, not automatic remediation.
## User Scenarios & Testing
### Scenario 1: View drift summary
- Given inventory sync has run at least twice
- When the admin opens Drift
- Then they see a summary of changes since the last baseline
### Scenario 2: Drill into a drift finding
- Given a drift finding exists
- When the admin opens the finding
- Then they see what changed, when, and which run observed it
### Scenario 3: Acknowledge/triage
- Given a drift finding exists
- When the admin marks it acknowledged
- Then it is hidden from “new” lists but remains auditable
## Functional Requirements
- FR1: Define a baseline concept (e.g., last completed run for a selection scope).
- FR2: Produce drift findings for adds/removals/metadata changes based on inventory/run state.
- FR3: Provide drift UI with summary and details.
- FR4: Allow acknowledgement/triage states.
## Non-Functional Requirements
- NFR1: Drift generation must be deterministic for the same baseline and scope.
- NFR2: Drift must remain tenant-scoped and safe to display.
## Success Criteria
- SC1: Admins can identify drift across supported types in under 3 minutes.
- SC2: Drift results are consistent across repeated generation for the same baseline.
## Out of Scope
- Automatic revert/promotion.
## Related Specs
- Program: `specs/039-inventory-program/spec.md`
- Core: `specs/040-inventory-core/spec.md`
- Compare: `specs/043-cross-tenant-compare-and-promotion/spec.md`

View File

@ -0,0 +1,7 @@
# Tasks: Drift MVP
- [ ] T001 Define baseline and scope rules
- [ ] T002 Drift finding generation (deterministic)
- [ ] T003 Drift summary + detail UI
- [ ] T004 Acknowledge/triage state
- [ ] T005 Tests for determinism and tenant scoping