Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
44 lines
4.1 KiB
Markdown
44 lines
4.1 KiB
Markdown
---
|
|
description: learned preferences, project conventions, and Do-Not-Repeat rules
|
|
budget_tokens: 2000
|
|
---
|
|
# Cerebrum
|
|
|
|
> OpenWolf's learning memory. Updated automatically as the AI learns from interactions.
|
|
> Do not edit manually unless correcting an error.
|
|
> Last updated: 2026-10-06
|
|
|
|
## User Preferences
|
|
|
|
<!-- How the user likes things done. Code style, tools, patterns, communication. -->
|
|
- Writes in Portuguese (pt-BR); answer in Portuguese. Wants things finished end to end: merged, released, deployed and checked in production, without being asked again (said so on 2026-10-22).
|
|
- Likes a clean interface with every function reachable (Apple / Anthropic as references, Outlook over Gmail), dark theme by default with a light one.
|
|
|
|
## Key Learnings
|
|
|
|
- **Project:** LambdaMail
|
|
- **Description:** A self-hosted mail server with an integrated webmail and admin console, built to
|
|
|
|
## Do-Not-Repeat
|
|
|
|
<!-- Mistakes made and corrected. Each entry prevents the same mistake recurring. -->
|
|
<!-- Format: [YYYY-MM-DD] Description of what went wrong and what to do instead. -->
|
|
- [2026-10-22] `git add -A` swept the untracked `.wolf/` and `CLAUDE.md` into a public repo. Add explicit paths (`git add services migrations`), never `-A`.
|
|
- [2026-10-22] Deploy is two steps: PATCH the Coolify env `IMAGE_TAG` to `sha-<commit>` and only then POST /deploy. A deploy without the PATCH redeploys the old image and still says "finished". Wait for the Release run to be `completed`, not just for `gh run watch` to return.
|
|
- [2026-10-22] `pkill -f <pattern>` kills the shell that is running it when the pattern appears in the command text. Use a bracket such as `[m]ock.mjs`, and never in a command that also contains the pattern as plain text.
|
|
- [2026-10-22] `~/.claude/tools/chrome-claude --print-path` launches Chrome. Pass the wrapper only as `executablePath`.
|
|
- [2026-10-22] `services/protocols` e2e tests apply only migration 0001. Delivery code must not call SQL functions or columns from later migrations.
|
|
- [2026-10-22] A `<Button>` inside a `<form>` submits it unless `type="button"` (Undo send used to resend the message).
|
|
- [2026-10-22] Never run side effects inside a React state updater (it can run twice).
|
|
- [2026-10-23] Inside a JS template literal `\\d` silently becomes `d`. For scripts embedded in template strings write `[0-9]` instead of `\\d`, and test the script's behaviour, not only that it is present.
|
|
|
|
## Decision Log
|
|
|
|
<!-- Significant technical decisions with rationale. Why X was chosen over Y. -->
|
|
- 2026-10-22 Sessions: webmail session is 30 days and renewed daily while in use; each account is also a `lm_acct_<id>` cookie, `lm_user_session` stays the active one so the Go service and the middleware needed no change. Console stays at 8 hours.
|
|
- 2026-10-22 Trusted senders live in table `trusted_senders`; delivery rescues a Junk verdict only when DMARC passed, or SPF passed for the From domain (a forged From must not be rescued).
|
|
- 2026-10-22 Conversations: `thread_id` is written at delivery (Message-ID, then In-Reply-To/References, then Re:-subject); NULL means "its own conversation" via COALESCE(thread_id, id). Subject key is computed in Go at delivery and in SQL (`lm_subject_key`) for the backfill; a test holds them equal.
|
|
- 2026-10-22 Themes: every colour is a CSS variable per theme (`globals.css`), Tailwind scales (slate, indigo, amber, rose, emerald) read them, `ink` is the on-ground colour. Dark is default; the theme is chosen by a script in `<head>` before first paint. Font Geist is self-hosted (@fontsource-variable/geist).
|
|
- 2026-10-23 Logo: a lambda of two straight strokes of one weight, ends cut square, joined without a seam, flat ultramarine tile with continuous corners. The first version (round caps, gradient, envelope flap) read as childish; do not go back to round-capped strokes. Generator: `scripts/brand/` (mark.py, icons.mjs); `Logo.tsx` carries the same path.
|
|
- 2026-10-23 Reader: a message written plainly is drawn in the app's colours (transparent frame, text lifted if too dark, white backdrops cleared); a designed one (backgrounds, bgcolor, 3+ tables) keeps a white sheet. Decided by `looksDesigned` in `lib/emailBody.ts`; a reply's quoted history folds behind a button.
|