# Audit Dual-Write Reconciliation Report - Generated: 2026-04-22T11:59:51.1886399+03:00 - **Overall status: PASS** - Container: `stellaops-postgres` - Database : `stellaops_platform` - Purpose : substitute for the 30-day wall-clock observation window described in SPRINT_20260408_004 (AUDIT-005) and SPRINT_20260408_005 (DEPRECATE-001). Each per-service audit table is reconciled against `timeline.unified_audit_events` using the discriminator the repository-level dual-write mapper puts into `details_jsonb` (`localAuditId` / `localEntryId`). ## Headline counts | Table | Rows | | --- | ---: | | `authority.audit` | 0 | | `authority.login_attempts` | 0 | | `notify.audit` | 0 | | `policy.audit` | 0 | | `release_orchestrator.audit_entries` | 0 | | `scheduler.audit` | 0 | | `timeline.unified_audit_events` | 567 | ## policy.audit <-> timeline(module=policy, localAuditId) | Metric | Value | | --- | ---: | | Local rows | 0 | | Timeline dual-write rows (`details_jsonb ? 'localAuditId'`) | 0 | | **Missing in Timeline (data loss)** | 0 | | Orphan in Timeline (local cleared post-emission) | 0 | | Status | **PASS** | ## notify.audit <-> timeline(module=notify, localAuditId) | Metric | Value | | --- | ---: | | Local rows | 0 | | Timeline dual-write rows (`details_jsonb ? 'localAuditId'`) | 18 | | **Missing in Timeline (data loss)** | 0 | | Orphan in Timeline (local cleared post-emission) | 18 | | Status | **PASS** | ## scheduler.audit <-> timeline(module=scheduler, localAuditId) | Metric | Value | | --- | ---: | | Local rows | 0 | | Timeline dual-write rows (`details_jsonb ? 'localAuditId'`) | 0 | | **Missing in Timeline (data loss)** | 0 | | Orphan in Timeline (local cleared post-emission) | 0 | | Status | **PASS** | ## release_orchestrator.audit_entries <-> timeline(module IN (release,jobengine), localEntryId) | Metric | Value | | --- | ---: | | Local rows | 0 | | Timeline dual-write rows (`details_jsonb ? 'localEntryId'`) | 0 | | **Missing in Timeline (data loss)** | 0 | | Orphan in Timeline (local cleared post-emission) | 0 | | Status | **PASS** | ## authority.login_attempts <-> timeline(module=authority) [tuple-match] `AuthorityAuditSink` assigns a fresh GUID for the Timeline id, so reconciliation falls back to tuple matching on `(action=event_type, timestamp +/- 5s)`. | Metric | Value | | --- | ---: | | `authority.login_attempts` rows | 0 | | Timeline `authority-*` rows | 0 | | **Local rows with no Timeline twin** | 0 | | Status | **PASS** |