This work focused on reducing ambiguity in the operating model. Monthly reporting has clearer run and regeneration paths, legacy surfaces are explicitly marked and measurable, and SNS push alerts can enter the same canonical ingest path as polled alerts when enabled.
Monthly reporting is operational
The monthly reporting work moved from backend capability to operator workflow.
The backend can finalise completed monthly reporting periods, expose public report downloads, and regenerate completed periods from an admin reporting page. The public report outputs are friendly to direct download tools, so downstream automation can fetch generated JSON or markdown without needing an authenticated admin session.
The reporting closeout also improved parity between structured JSON and markdown presentation. That matters because monthly reports are not just data exports; they are also human-facing summaries that need to remain consistent as the schema evolves.
Scheduled work has a home
A general housekeeping service was added as the place for recurring maintenance tasks. The first practical use is monthly report auto-finalisation; future maintenance work can use the same pattern if it fits.
This keeps scheduled jobs from being scattered throughout unrelated services. Future operators and maintainers have one obvious place to look for periodic background work.
Legacy cleanup is now evidence based
The legacy cleanup work continued carefully.
The old /api/system/health queueDepth field is now omitted by default, but can be restored with a temporary compatibility flag. The legacy /api/alerts/notify endpoint remains enabled by default, but it is now clearly marked as a compatibility endpoint and can be disabled by configuration.
Both paths now emit explicit usage markers and metrics. This gives the project a concrete observation window instead of relying on guesswork about whether old callers still exist.
The result is a safer removal path: first mark, observe, and measure; then remove only when there is evidence that the compatibility surface is unused.
SNS push alerts use canonical ingest
The SNS callback endpoint no longer logs full notification bodies or CAP XML payloads. It now logs structured metadata and records classified outcomes for received messages.
SNS notification ingest is available behind a default-off flag. When enabled, a configured SNS topic ARN maps to an existing AlertSource.code. Inline CAP XML from the SNS Message field is evaluated with the existing raw CAP candidate evaluator and then persisted through canonical alert ingestion.
That keeps pushed alerts and polled alerts on the same durable path. The current implementation avoids adding a parallel alert model, a parallel persistence path, or a separate source taxonomy.
The implementation also added a distinct SNS_PUSH ingest origin so projection behavior can distinguish pushed live data from feed polling, peer sync, replay, and rebuild work.
Verification
The full alert-hub-v2-node test suite passed after the SNS ingest change:
266 tests, 266 passed
Focused tests also cover the important SNS cases:
- ingest disabled by default
- valid mapped notification persists through canonical ingestion
- duplicate notification remains idempotent
- malformed CAP is rejected without persistence
- unknown topic mapping is rejected without persistence
- missing and unknown SNS message types are classified without breaking the callback
Backlog state
Several backlog items are now clearer:
- monthly reporting workspace work is closed
AH-00021is closedAH-00004remains open, but has explicit observation gates for remaining legacy compatibility paths
The active backlog is smaller and more accurate. More importantly, the remaining cleanup work can be guided by runtime evidence instead of assumptions.