One event per (session, page, channel) within an aligned window of
readTrail.dedupWindowMinutes (default 5): buckets are
floor(epoch / windowSeconds), and a unique (dedup_key, window_bucket)
pair collapses concurrent duplicates race-free at insert time — the
first access in a window is always recorded, a later duplicate lands on
the unique violation and is skipped quietly (a skipped duplicate is not
a gap; only real write failures still abort the read). Each row carries
windowSeconds, so the evidence states it represents a window, never a
request count.
Reconnects within a window stay one event; a new session records again
even for the same user; channels never collapse into each other; the
page-less attachment key uses the documented `-` placeholder. Load
evidence: 30 collab-token renewals inside one window produce exactly one
event (test), bounding a live editing session at ~12 events/hour/page.
Window semantics documented in ADR 0023, the VS-NfD security
documentation (#228) and as a hardening-guide line for the new setting
(care rule: same PR).
Refs #223.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AUtYMxwTCMHG9mVHnwbFg8
docs/vs-nfd/60-sicherheitsdokumentation.md: component diagram with per-
service purpose and privileges, network plan digit-exact against the
deploy compose (127.0.0.1-only app bindings, internal-only data zone),
data-flow diagrams (auth, realtime editing incl. LISTEN/NOTIFY and the
60s collab token, export via the pinned sidecars, backup incl. the
ADR-0026 allowlist, and every read channel), named trust boundaries
(reverse proxy, plugin sandbox, outbound SMTP/mirror), and the complete
list of content copies — in-database, on-volume and outside the
instance — that the deletion concept in #229 builds on. Mermaid only,
German (assessor audience), with the maintained-in-same-PR rule stated.
Co-Authored-By: Claude Fable 5 (1M context) <noreply@anthropic.com>