LC-209-DOC-DRIFT: reconcile email-ingress/bridge docs + env tables with post-arc behavior #279

Closed
opened 2026-05-31 03:13:41 +02:00 by longjacksonle · 0 comments

Problem

The LC-77 / LC-78 / LC-77-SMTP-SEAL arc shipped behavior that invalidated several operator-facing doc claims. Each below is confirmed against current code. None is a one-line typo: they actively mislead operators (one advertises a security vulnerability that no longer exists; one hides an operator-visible default-on toggle). Batched as one doc-accuracy sweep.

Findings

  • D1 (security claim, wrong). docs/email-ingress.md:270 says the SMTP password "is currently stored plaintext... tracked as LC-77-SMTP-SEAL." That ticket shipped: SMTP fields were dropped from settings.db (server/migrations/settings/0006_drop_smtp_settings.sql) and SMTP is now env-var-only (server/src/mail.rs:31-54, LETS_CHAT_SMTP_*). The doc advertises a plaintext-at-rest vuln that no longer exists. Fix: remove the claim, document the env-var-only posture.

  • D2 (self-contradiction). docs/email-ingress.md lines 13 and 108 say reply-by-email is "deferred / stage 2," while lines 5 and 148-150 of the same doc say "LC-77-REPLY (#201, shipped)" and "the IMAP poll loop now consumes replies" (matching server/src/email_ingress/reply_actor.rs + resolve.rs). Stale v1 sentences survived the stage-2-shipped edit. Fix: delete the "deferred" sentences.

  • D3 (incomplete taxonomy). docs/email-ingress.md:81-88 drop-reason table lists 6 reasons; server/src/email_ingress/mod.rs:39-79 defines 8 DropReason variants. Missing: reply_expired and duplicate (the latter is in prose at doc line 240 but not the table). Fix: add the two rows.

  • D4 (self-contradiction). docs/protocol-bridges.md:89 says foreign_avatar "must be absent or null in v1. Any non-null value is rejected with HTTP 400." Avatar-proxy is on by default in v2 (server/src/routes/api.rs:317-343): a non-null value is accepted unless LETS_CHAT_BRIDGE_AVATAR_PROXY_ENABLED=false. Leftover v1 validation text contradicts lines 27-31/40/69 of the same doc. Fix: rewrite line 89 for the v2 default-on behavior.

  • D5 (undocumented operator toggle). LETS_CHAT_BRIDGE_AVATAR_PROXY_ENABLED (read at server/src/bridge_avatar.rs:205, default on, accepts false/0/no/off) is missing from BOTH the README and CLAUDE.md env tables. Per the LC-209 operator-visible convention this default-on toggle also never got an [operator-action] marker when it shipped. CLAUDE.md additionally omits LETS_CHAT_BASE_URL, LETS_CHAT_PUSH_CONTACT, and the 6 LETS_CHAT_SMTP_* vars (README has those). Fix: add the proxy toggle to both tables; backfill the others into CLAUDE.md.

Scope

Pure documentation + env-table edits across docs/email-ingress.md, docs/protocol-bridges.md, README.md, CLAUDE.md. No code change. Migration files are NOT touched (immutability rule); D1's posture note goes in the doc and, if needed, the Mailer::from_env doc-comment, not the historic migration.

Acceptance

Each of D1-D5 reconciled against the cited code line. SMTP plaintext claim removed; reply-by-email described as shipped; drop taxonomy complete; foreign_avatar v2 behavior correct; the bridge-avatar-proxy toggle documented in both env tables.

Anchored to LC-209 (operator-visible-change + docs convention). Severity: documentation, but D1/D5 are operator-visible and worth doing promptly.

## Problem The LC-77 / LC-78 / LC-77-SMTP-SEAL arc shipped behavior that invalidated several operator-facing doc claims. Each below is confirmed against current code. None is a one-line typo: they actively mislead operators (one advertises a security vulnerability that no longer exists; one hides an operator-visible default-on toggle). Batched as one doc-accuracy sweep. ## Findings - **D1 (security claim, wrong).** `docs/email-ingress.md:270` says the SMTP password "is currently stored plaintext... tracked as LC-77-SMTP-SEAL." That ticket shipped: SMTP fields were dropped from `settings.db` (`server/migrations/settings/0006_drop_smtp_settings.sql`) and SMTP is now env-var-only (`server/src/mail.rs:31-54`, `LETS_CHAT_SMTP_*`). The doc advertises a plaintext-at-rest vuln that no longer exists. Fix: remove the claim, document the env-var-only posture. - **D2 (self-contradiction).** `docs/email-ingress.md` lines 13 and 108 say reply-by-email is "deferred / stage 2," while lines 5 and 148-150 of the same doc say "LC-77-REPLY (#201, shipped)" and "the IMAP poll loop now consumes replies" (matching `server/src/email_ingress/reply_actor.rs` + `resolve.rs`). Stale v1 sentences survived the stage-2-shipped edit. Fix: delete the "deferred" sentences. - **D3 (incomplete taxonomy).** `docs/email-ingress.md:81-88` drop-reason table lists 6 reasons; `server/src/email_ingress/mod.rs:39-79` defines 8 `DropReason` variants. Missing: `reply_expired` and `duplicate` (the latter is in prose at doc line 240 but not the table). Fix: add the two rows. - **D4 (self-contradiction).** `docs/protocol-bridges.md:89` says `foreign_avatar` "must be absent or null in v1. Any non-null value is rejected with HTTP 400." Avatar-proxy is on by default in v2 (`server/src/routes/api.rs:317-343`): a non-null value is accepted unless `LETS_CHAT_BRIDGE_AVATAR_PROXY_ENABLED=false`. Leftover v1 validation text contradicts lines 27-31/40/69 of the same doc. Fix: rewrite line 89 for the v2 default-on behavior. - **D5 (undocumented operator toggle).** `LETS_CHAT_BRIDGE_AVATAR_PROXY_ENABLED` (read at `server/src/bridge_avatar.rs:205`, **default on**, accepts `false`/`0`/`no`/`off`) is missing from BOTH the README and CLAUDE.md env tables. Per the LC-209 operator-visible convention this default-on toggle also never got an `[operator-action]` marker when it shipped. CLAUDE.md additionally omits `LETS_CHAT_BASE_URL`, `LETS_CHAT_PUSH_CONTACT`, and the 6 `LETS_CHAT_SMTP_*` vars (README has those). Fix: add the proxy toggle to both tables; backfill the others into CLAUDE.md. ## Scope Pure documentation + env-table edits across `docs/email-ingress.md`, `docs/protocol-bridges.md`, `README.md`, `CLAUDE.md`. No code change. Migration files are NOT touched (immutability rule); D1's posture note goes in the doc and, if needed, the `Mailer::from_env` doc-comment, not the historic migration. ## Acceptance Each of D1-D5 reconciled against the cited code line. SMTP plaintext claim removed; reply-by-email described as shipped; drop taxonomy complete; `foreign_avatar` v2 behavior correct; the bridge-avatar-proxy toggle documented in both env tables. Anchored to LC-209 (operator-visible-change + docs convention). Severity: documentation, but D1/D5 are operator-visible and worth doing promptly.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/lets-chat#279
No description provided.