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
2.7 KiB
2.7 KiB
Tasks: Inventory Core (040)
Input: specs/040-inventory-core/spec.md, specs/040-inventory-core/plan.md
P1 — MVP (US1/US2)
- T001 [US1] Add migrations:
inventory_items(unique: tenant_id+policy_type+external_id; indexes; last_seen fields) - T002 [US1] Add migrations:
inventory_sync_runs(tenant_id, selection_hash, status, started/finished, counts, stable error codes) - T003 [US1] Implement deterministic
selection_hash(canonical JSON: sorted keys + sorted arrays; sha256) - T004 [US1] Implement inventory upsert semantics (idempotent, no duplicates)
- T005 [US1] Enforce tenant isolation for all inventory + run read/write paths
- T006 [US2] Implement derived “missing” query semantics vs latest completed run for same (tenant_id, selection_hash)
- T007 [US2] Missing confidence rule: partial/failed or had_errors => low confidence
- T008 [US2] Enforce
meta_jsonbwhitelist (drop unknown keys; never fail sync) - T009 [US1] Guardrail: inventory sync must not create snapshots/backups (no writes to
policy_versions/backup_*)
P2 — Observability & Safety (US3 + NFR)
- T010 [US3] Run lifecycle: ensure run records include counts + stable error codes (visible and actionable)
- T011 [NFR] Locking/idempotency: prevent overlapping runs per (tenant_id, selection_hash)
- T012 [NFR] Concurrency: enforce global + per-tenant limits (queue/semaphore strategy)
- T013 [NFR] Throttling resilience: backoff + jitter for transient Graph failures (429/503)
- 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)
- T020 [US1] Pest: upsert prevents duplicates;
last_seen_atandlast_seen_run_idupdate - T021 [US2] Pest: missing derived per latest completed run for same (tenant_id, selection_hash)
- T022 [US2] Pest: selection isolation (run for selection Y does not affect selection X)
- T023 [US2] Pest: partial/failed/had_errors => missing is low confidence
- T024 [US2] Pest: meta whitelist drops unknown keys (no exception; no persistence)
- T025 [NFR] Pest: selection_hash determinism (array ordering invariant)
- T026 [NFR] Pest: lock prevents overlapping runs for same (tenant_id, selection_hash)
- T027 [NFR] Pest: run error persistence contains no secrets/tokens (assert error context is bounded; no “Bearer ” / access token patterns; prefer error_codes)
- T028 [US1] Pest: inventory sync creates no rows in
policy_versionsandbackup_*tables (assert counts unchanged)
Notes
- “deleted” is reserved and MUST NOT be produced in this feature.