M7 head records M6 realities:
- IAuditCentralHealthSnapshot exists; M7 dashboard reads it.
- SiteHealthReport.SiteAuditBacklog ready for per-site tiles.
- IAuditLogRepository.QueryAsync is the page's data source.
- Pre-existing AuditLog.razor rename to ConfigurationAuditLog.razor
needs verification.
- OperationalAudit + AuditExport permission strings need to exist.
- Real gRPC pull client still deferred; doesn't gate M7.
M6 head records M5 realities:
- IOptionsMonitor hot-reload pattern verified; M6 retention config can
reuse.
- AuditRedactionFailure counter site-only in M5; M6 wires central side.
- Filter integration is at 3 writer entry points; purge actor doesn't
emit so no filter integration needed.
- SwitchOutPartitionAsync drop-and-rebuild dance required (M1 reality
+ M6-T4 already documents it).
- M6 should land the real ISiteStreamAuditClient (Option A) so push
telemetry leaves NoOp behind.
M5 head records M4 realities:
- AuditingDbConnection/Command/DataReader decorators need filter plug-in
at WriteAsync emission point.
- CentralAuditWriter + FallbackAuditWriter are both filter integration
points for the direct-write + chained-write paths.
- InboundAPI middleware RequestSummary populated, ResponseSummary=null
pending response-body buffering decision in M5.
- UseWhen(/api/) path-scoped middleware gives natural per-target
redaction hook.
- Error-row cap raised on Status IN (Failed, Parked, Discarded,
Attempted, Skipped) per M1 vocab reconciliation.
M4 head now records M3 realities:
- Vocabulary translation table from pre-M1 spec strings to M1-aligned
enum values (DbWrite vs SyncWrite/SyncRead; NotifyDeliver vs
Notification.Attempt/Terminal; InboundRequest/InboundAuthFailure vs
ApiInbound.Completed; Failed vs PermanentFailure).
- Mapper consolidation: 4 DTO mappers exist; extract single helper
before M4 adds more channels.
- OnCachedTelemetryWithoutDualWriteAsync test-mode fallback may be
deprecated in M4.
- Site SQLite drain for OperationTrackingStore: only dual-write
transaction writes central today; plan drain if M4 needs in-flight
tracking visibility.
- SiteCallAuditActor wired but unused on M3 hot path; M4/M6 natural
first direct caller.
M3 head now records M2 realities:
- enum vocabulary (M1-aligned) drives CachedSubmit/ApiCallCached/etc.
- NoOpSiteStreamAuditClient stays until M6; M3 e2e tests reuse Bundle H's
DirectActorSiteStreamAuditClient (extract to Integration/Infrastructure/).
- Mapper duplication note (gRPC handler inlines DTO->entity decoding;
consider moving AuditEventMapper to Commons in M3).
- AuditIngestAskTimeout=30s hardcoded; M3 may expose via options.
- CachedCallTelemetry message MUST be created from scratch (additive
per Commons REQ-COM-5a; never renamed CachedOperationTelemetry).
- Central dual-write AuditLog + SiteCalls in one tx; reuse Bundle A
duplicate-key swallow pattern for CachedCallId.
- M2 head: honor M1 vocabulary (ApiCall/Delivered), harden InsertIfNotExistsAsync
(race window — first concurrent writer arrives in M2), add keyset-tiebreaker
test (Bundle D reviewer's deferred recommendation), reuse MsSqlMigrationFixture
+ Xunit.SkippableFact pattern.
- M6-T4 (AuditLogPurgeActor): replace M1's NotSupportedException stub with the
drop-and-rebuild dance for the non-aligned UX_AuditLog_EventId unique index;
acknowledge the small outage window during partition SWITCH.
- M6-T5 (partition maintenance): note M1 ships 24 monthly boundaries (Jan 2026 -
Dec 2027); service rolls the function forward via SPLIT RANGE.
Per user request: every milestone now carries bite-sized TDD tasks
(write failing test -> run failing -> implement -> run passing -> commit),
matching M1's density. Each task lists exact file paths, numbered steps,
and a commit message.
Task counts per milestone:
- M1 Foundation: 11
- M2 Site pipeline (sync-only): 12
- M3 Cached operations + dual-write (inlines #22 + cached-call tracking): 18
- M4 Remaining boundary emission: 12
- M5 Payload + redaction policy: 10
- M6 Reconciliation, purge, partition maintenance, metrics: 12
- M7 Central UI: 16
- M8 CLI: 9
Total: ~100 bite-sized tasks.
The roadmap remains the contract; per-milestone execution still goes
through brainstorm -> writing-plans -> subagent-driven-development to
produce a milestone-specific .tasks.json. Tasks in this roadmap will
shift slightly as M1 reveals codebase realities; treat them as the
intended shape rather than immutable IDs.
Roadmap covering Audit Log (#23) code implementation across 8 milestones
(M1 Foundation → M8 CLI). Reflects the actual state of the codebase —
all 22 prior components have source + tests, but Site Call Audit (#22)
and cached-call tracking are design-only despite being on main; their
minimum surface is inlined into M3.
M1 is laid out at full TDD-level task detail (11 bite-sized tasks).
M2–M8 are at milestone-shape detail (goals, files, task headlines,
acceptance criteria, risk callouts). Per-milestone bite-sized plans
will be generated by brainstorm + writing-plans when each milestone is
about to execute — locking 80 task cards now would mostly be stale by
M5 as M1 reveals codebase realities.
Critical path: M1 → M2 → (M3 ∥ M4 ∥ M5) → M6 → (M7 ∥ M8).
Spec: docs/requirements/Component-AuditLog.md + alog.md (commit
fec0bb1).