diff --git a/specs/039-inventory-program/plan.md b/specs/039-inventory-program/plan.md new file mode 100644 index 0000000..6dfec13 --- /dev/null +++ b/specs/039-inventory-program/plan.md @@ -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 040–044 feature specs +- Program principles aligned with constitution + +## Notes + +This spec is not tied to code changes. diff --git a/specs/039-inventory-program/spec.md b/specs/039-inventory-program/spec.md new file mode 100644 index 0000000..f4db39b --- /dev/null +++ b/specs/039-inventory-program/spec.md @@ -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**: TenantPilot’s last observed catalog of Intune objects (mutable; updated by sync runs). +- **Snapshot/Backup**: Immutable capture of an object’s 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. diff --git a/specs/039-inventory-program/tasks.md b/specs/039-inventory-program/tasks.md new file mode 100644 index 0000000..6a10239 --- /dev/null +++ b/specs/039-inventory-program/tasks.md @@ -0,0 +1,7 @@ +# Tasks: Inventory Program (Meta) + +**Input**: `specs/039-inventory-program/spec.md` + +- [ ] T001 Confirm naming/numbering for 040–044 +- [ ] T002 Draft skeleton specs for 041–044 +- [ ] T003 Validate alignment with constitution principles diff --git a/specs/040-inventory-core/plan.md b/specs/040-inventory-core/plan.md new file mode 100644 index 0000000..01099f4 --- /dev/null +++ b/specs/040-inventory-core/plan.md @@ -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) diff --git a/specs/040-inventory-core/spec.md b/specs/040-inventory-core/spec.md new file mode 100644 index 0000000..b3de53a --- /dev/null +++ b/specs/040-inventory-core/spec.md @@ -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 (TenantPilot’s 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 tenant’s 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 TenantPilot’s 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 B’s 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. diff --git a/specs/040-inventory-core/tasks.md b/specs/040-inventory-core/tasks.md new file mode 100644 index 0000000..20b4ed3 --- /dev/null +++ b/specs/040-inventory-core/tasks.md @@ -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. diff --git a/specs/041-inventory-ui/plan.md b/specs/041-inventory-ui/plan.md new file mode 100644 index 0000000..8b74871 --- /dev/null +++ b/specs/041-inventory-ui/plan.md @@ -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 diff --git a/specs/041-inventory-ui/spec.md b/specs/041-inventory-ui/spec.md new file mode 100644 index 0000000..902f35e --- /dev/null +++ b/specs/041-inventory-ui/spec.md @@ -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 item’s 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` diff --git a/specs/041-inventory-ui/tasks.md b/specs/041-inventory-ui/tasks.md new file mode 100644 index 0000000..f105ffb --- /dev/null +++ b/specs/041-inventory-ui/tasks.md @@ -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) diff --git a/specs/042-inventory-dependencies-graph/plan.md b/specs/042-inventory-dependencies-graph/plan.md new file mode 100644 index 0000000..bf86ce3 --- /dev/null +++ b/specs/042-inventory-dependencies-graph/plan.md @@ -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 diff --git a/specs/042-inventory-dependencies-graph/spec.md b/specs/042-inventory-dependencies-graph/spec.md new file mode 100644 index 0000000..6abb63f --- /dev/null +++ b/specs/042-inventory-dependencies-graph/spec.md @@ -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` diff --git a/specs/042-inventory-dependencies-graph/tasks.md b/specs/042-inventory-dependencies-graph/tasks.md new file mode 100644 index 0000000..22c952b --- /dev/null +++ b/specs/042-inventory-dependencies-graph/tasks.md @@ -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 diff --git a/specs/043-cross-tenant-compare-and-promotion/plan.md b/specs/043-cross-tenant-compare-and-promotion/plan.md new file mode 100644 index 0000000..0ff77ae --- /dev/null +++ b/specs/043-cross-tenant-compare-and-promotion/plan.md @@ -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 040–041) +- 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 diff --git a/specs/043-cross-tenant-compare-and-promotion/spec.md b/specs/043-cross-tenant-compare-and-promotion/spec.md new file mode 100644 index 0000000..f7e416a --- /dev/null +++ b/specs/043-cross-tenant-compare-and-promotion/spec.md @@ -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` diff --git a/specs/043-cross-tenant-compare-and-promotion/tasks.md b/specs/043-cross-tenant-compare-and-promotion/tasks.md new file mode 100644 index 0000000..bed5012 --- /dev/null +++ b/specs/043-cross-tenant-compare-and-promotion/tasks.md @@ -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 diff --git a/specs/044-drift-mvp/plan.md b/specs/044-drift-mvp/plan.md new file mode 100644 index 0000000..6bffb81 --- /dev/null +++ b/specs/044-drift-mvp/plan.md @@ -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 diff --git a/specs/044-drift-mvp/spec.md b/specs/044-drift-mvp/spec.md new file mode 100644 index 0000000..b367de3 --- /dev/null +++ b/specs/044-drift-mvp/spec.md @@ -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` diff --git a/specs/044-drift-mvp/tasks.md b/specs/044-drift-mvp/tasks.md new file mode 100644 index 0000000..7ccfb97 --- /dev/null +++ b/specs/044-drift-mvp/tasks.md @@ -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