The snapshot streamed tables by name and rows by pk_json text, so a child
(or a self-reference whose parent's key sorts later) reached the receiver
first, failed its immediate FK check and was dead-lettered - permanently,
since the snapshot's watermark and ack covered it (LocalDb-002).
Sender: stream referenced tables first (Kahn order, name tie-break).
Receiver: SnapshotApplier defers rows that fail only
SQLITE_CONSTRAINT_FOREIGNKEY, retries them as rows land, and dead-letters
true orphans at SnapshotComplete. Delta path unchanged; wire unchanged.
Claude-Session: https://claude.ai/code/session_01GT67AEHd2Acv1YPwGfXEoV
LocalDbSyncService never read request headers, so setting
LocalDb:Replication:ApiKey on both nodes left the passive endpoint open
(LocalDb-001). It now requires Authorization: Bearer <key> (constant-time)
before the handshake and before newest-wins takeover, refusing anything else
with Unauthenticated. A blank key keeps the old accept-all behaviour and
logs a startup warning. Wire-compatible: the initiator has always sent the
header when the key is set; ScadaBridge/OtOpcUa interceptors use the same key.
LocalDb 0.3.5 -> 0.3.6 (unpublished).
Claude-Session: https://claude.ai/code/session_01GT67AEHd2Acv1YPwGfXEoV
First reviews of Secrets, LocalDb, GalaxyRepository and Overview, and
2026-11-09 re-reviews of Auth, Health, Theme, Telemetry, Audit and
Configuration, all at 91fb2b4. 49 new open findings, each with a P1/P2/P3
priority and a failure scenario: 1 P1, 13 P2, 35 P3. README regenerated;
REVIEW-PROCESS, template and regen script now cover all ten libraries and
the Priority field.
Claude-Session: https://claude.ai/code/session_01GT67AEHd2Acv1YPwGfXEoV