Skip to content

feat: resilient violation reporting — DB spool + cron retry (#7) - #25

Merged
cport1 merged 1 commit into
mainfrom
feat/violation-reporting-resilience
Jul 19, 2026
Merged

feat: resilient violation reporting — DB spool + cron retry (#7)#25
cport1 merged 1 commit into
mainfrom
feat/violation-reporting-resilience

Conversation

@cport1

@cport1 cport1 commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Upgrades the minimal shutdown-flush reporter (shipped with #5) into the resilient delivery pipeline #7 asks for — without adding page latency.

What changed

  • Spool table — new webdecoy_violation_queue (activator + DB_VERSION → 2.2.0, dropped on uninstall). Violations are written the moment they occur.
  • Immediate, latency-free delivery — on request shutdown, fastcgi_finish_request() hands the response back to the visitor first, then a blocking batch POST drains the spool. So enforcement stays near-instant (a tripwire hit reaches the deny-list in seconds) while the visitor waits for nothing.
  • Survives outages — a failed batch is retried once, then dropped; the queue is hard-capped at 1000 rows (oldest discarded) so a prolonged ingest outage can't grow the table unbounded. A webdecoy_flush_violations cron (every 15 min) drains whatever the shutdown path couldn't.
  • Clearance preserved — the wd_clearance token survives the spool round-trip, so the tripwire → durable-deny loop still works even after a retry.
  • Cloud-gated — no API key means no spooling and no reporting; rules still enforce locally.

Why a DB spool (not just fire-and-forget)

The P0 reporter used a non-blocking POST — fast, but it couldn't tell whether delivery succeeded, so a momentary ingest blip silently dropped detections. Spooling + a confirmed (blocking, post-response) send + cron retry makes delivery reliable without ever blocking the visitor.

Tests

Verified with a stubbed $wpdb + HTTP harness: enqueue, success clears the queue, clearance preserved through the spool, failure keeps the row and bumps attempts, drop after the retry, delivery on recovery before the drop, and the hard cap trimming overflow. Existing SDK suite still green (35 assertions).

Closes #7. Part of #16.

Upgrades the minimal shutdown-flush reporter from #5 to survive ingest
outages without adding page latency.

- New webdecoy_violation_queue table (activator + DB_VERSION 2.2.0, dropped
  on uninstall). Violations are spooled the moment they occur.
- Delivery: on shutdown, fastcgi_finish_request() hands the response back to
  the client first, then a blocking batch POST drains the spool — so
  enforcement stays near-instant (tripwire hit → deny-list in seconds) with
  zero user-facing latency.
- Resilience: failed batches are retried once then dropped; the queue is
  hard-capped at 1000 rows (oldest discarded) so a prolonged outage can't
  grow the table unbounded. A webdecoy_flush_violations cron (every 15 min)
  drains anything left behind.
- clearance tokens survive the spool round-trip, so the tripwire→deny loop
  still works after a retry.
- Cloud-gated: no API key -> no spooling, no reporting; rules still enforce.

Verified drain success/retry-once/drop/recovery/hard-cap and clearance
preservation with a stubbed $wpdb harness.

Closes #7. Part of #16.
Co-authored-by: Claude <noreply@anthropic.com>
@cport1
cport1 merged commit 8d90ac9 into main Jul 19, 2026
3 checks passed
@cport1
cport1 deleted the feat/violation-reporting-resilience branch July 19, 2026 20:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Violation event batch reporting to ingest

1 participant