Summary Implements Inventory Core (Spec 040): a tenant-scoped, mutable “last observed” inventory catalog + sync run logging, with deterministic selection hashing and safe derived “missing” semantics. This establishes the foundation for Inventory UI (041), Dependencies Graph (042), Compare/Promotion (043), and Drift (044). What’s included • DB schema • inventory_items (unique: tenant_id + policy_type + external_id; indexes; last_seen_at, last_seen_run_id) • inventory_sync_runs (tenant_id, selection_hash/payload, status, started/finished, counts, error_codes, correlation_id) • Selection hashing • Deterministic selection_hash via canonical JSON (sorted keys + sorted arrays) + sha256 • Sync semantics • Idempotent upsert (no duplicates) • Updates last_seen_* when observed • Enforces tenant scoping for all reads/writes • Guardrail: inventory sync does not create snapshots/backups • Missing semantics (derived) • “missing” computed relative to latest completed run for same (tenant_id, selection_hash) • Low confidence when latest run is partial/failed or had_errors=true • Selection isolation (runs for other selections don’t affect missing) • deleted is reserved (not produced here) • Safety • meta_jsonb whitelist enforced (unknown keys dropped; never fail sync) • Safe error persistence (no bearer tokens / secrets) • Locking to prevent overlapping runs for same tenant+selection • Concurrency limiter (global + per-tenant) and throttling resilience (429/503 backoff + jitter) Tests Added Pest coverage for: • selection_hash determinism (array order invariant) • upsert idempotency + last_seen updates • missing derived semantics + selection isolation • low confidence missing on partial/had_errors • meta whitelist drop (no exception) • lock prevents overlapping runs • no snapshots/backups side effects • safe error persistence (no bearer tokens) Non-goals • Inventory UI pages/resources (Spec 041) • Dependency graph hydration (Spec 042) • Cross-tenant compare/promotion flows (Spec 043) • Drift analysis dashboards (Spec 044) Review focus • Data model correctness + indexes/constraints • Selection hash canonicalization (determinism) • Missing semantics (latest completed run + confidence rule) • Guardrails (no snapshot/backups side effects) • Safety: error_code taxonomy + safe persistence/logging Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local> Reviewed-on: #43
40 lines
2.7 KiB
Markdown
40 lines
2.7 KiB
Markdown
# Tasks: Inventory Core (040)
|
|
|
|
**Input**: `specs/040-inventory-core/spec.md`, `specs/040-inventory-core/plan.md`
|
|
|
|
## P1 — MVP (US1/US2)
|
|
|
|
- [X] T001 [US1] Add migrations: `inventory_items` (unique: tenant_id+policy_type+external_id; indexes; last_seen fields)
|
|
- [X] T002 [US1] Add migrations: `inventory_sync_runs` (tenant_id, selection_hash, status, started/finished, counts, stable error codes)
|
|
- [X] T003 [US1] Implement deterministic `selection_hash` (canonical JSON: sorted keys + sorted arrays; sha256)
|
|
- [X] T004 [US1] Implement inventory upsert semantics (idempotent, no duplicates)
|
|
- [X] T005 [US1] Enforce tenant isolation for all inventory + run read/write paths
|
|
- [X] T006 [US2] Implement derived “missing” query semantics vs latest completed run for same (tenant_id, selection_hash)
|
|
- [X] T007 [US2] Missing confidence rule: partial/failed or had_errors => low confidence
|
|
- [X] T008 [US2] Enforce `meta_jsonb` whitelist (drop unknown keys; never fail sync)
|
|
- [X] T009 [US1] Guardrail: inventory sync must not create snapshots/backups (no writes to `policy_versions`/`backup_*`)
|
|
|
|
## P2 — Observability & Safety (US3 + NFR)
|
|
|
|
- [X] T010 [US3] Run lifecycle: ensure run records include counts + stable error codes (visible and actionable)
|
|
- [X] T011 [NFR] Locking/idempotency: prevent overlapping runs per (tenant_id, selection_hash)
|
|
- [X] T012 [NFR] Concurrency: enforce global + per-tenant limits (queue/semaphore strategy)
|
|
- [X] T013 [NFR] Throttling resilience: backoff + jitter for transient Graph failures (429/503)
|
|
- [X] T014 [NFR] Safe logging & safe persistence: store only stable `error_codes` + bounded safe context in run records (no secrets/tokens; no log parsing required)
|
|
|
|
## Tests (Required for runtime behavior)
|
|
|
|
- [X] T020 [US1] Pest: upsert prevents duplicates; `last_seen_at` and `last_seen_run_id` update
|
|
- [X] T021 [US2] Pest: missing derived per latest completed run for same (tenant_id, selection_hash)
|
|
- [X] T022 [US2] Pest: selection isolation (run for selection Y does not affect selection X)
|
|
- [X] T023 [US2] Pest: partial/failed/had_errors => missing is low confidence
|
|
- [X] T024 [US2] Pest: meta whitelist drops unknown keys (no exception; no persistence)
|
|
- [X] T025 [NFR] Pest: selection_hash determinism (array ordering invariant)
|
|
- [X] T026 [NFR] Pest: lock prevents overlapping runs for same (tenant_id, selection_hash)
|
|
- [X] T027 [NFR] Pest: run error persistence contains no secrets/tokens (assert error context is bounded; no “Bearer ” / access token patterns; prefer error_codes)
|
|
- [X] T028 [US1] Pest: inventory sync creates no rows in `policy_versions` and `backup_*` tables (assert counts unchanged)
|
|
|
|
## Notes
|
|
|
|
- “deleted” is reserved and MUST NOT be produced in this feature.
|