TenantAtlas/specs/040-inventory-core/tasks.md
ahmido 8ae7a7234e feat/040-inventory-core (#43)
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
2026-01-07 14:54:24 +00:00

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_jsonb whitelist (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_at and last_seen_run_id update
  • 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_versions and backup_* tables (assert counts unchanged)

Notes

  • “deleted” is reserved and MUST NOT be produced in this feature.