docs: the convention docs were describing a different codebase

Second pass. These three are the ones a new contributor reads first, and all three were
teaching things that are not true here.

src/databases/CLAUDE.md claimed "Three PostgreSQL databases", listed two, and there is
exactly one. Its type examples were Screenshot / Experiment / Company / GanOauth — none of
which have ever existed in this repo; it had been carried over from another project
wholesale. Rewritten against the real schema, queries and types, and it now carries the two
things that actually bite: push-not-migrations, and the rule that the schema is the source
of truth for what the database may CONTAIN, not just its shape — with the sql.raw trap in
check() written down, since getting it wrong breaks push for the whole schema.

src/apps/CLAUDE.md had the same problem in its examples (useExperimentsList, ExperimentCard,
a state/ directory layout that does not exist), listed a `useWebsockets` hook that is not
there while omitting useChatWebSocket, usePanelChannel and useJobs, and closed with links to
three app docs that have never existed. Examples now use real hooks, and it points at the
navigation audit — a frontend doc that did not mention the one rule the platform CLAUDE.md
calls authoritative was a real gap.

CONVENTIONS.md said, in bold, that useMemo and useCallback are "strictly prohibited" because
"React 19's compiler handles memoization automatically". Wrong twice: the React Compiler is
an opt-in build plugin that is NOT installed here, so React 19 memoizes nothing on its own —
and roughly 40 files use each hook regardless, including code added this week. Replaced with
guidance that matches both reality and the actual tradeoff, and says plainly what it used to
claim. A rule that is false and universally ignored makes every other rule in the file look
optional.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-31 16:42:47 +00:00
co-authored by Claude Opus 5
parent 04c0d89057
commit db9d17d6fe
3 changed files with 116 additions and 94 deletions
+21 -9
View File
@@ -129,22 +129,34 @@ export const useFeatureManager = () => {
## React Patterns
### No useMemo or useCallback (React 19)
### Reach for useMemo / useCallback only when they do work
**NEVER** use `useMemo` or `useCallback`. React 19's compiler handles memoization automatically. Importing and using these hooks is strictly prohibited.
Default to writing the code plainly. Most derived values are cheap and re-computing them per render costs
less than the memo that guards them.
```tsx
// ✅ Good - just write the code naturally
// ✅ Fine — cheap, so just write it
const filteredItems = items.filter((item) => item.active);
const handleClick = () => doSomething();
const stats = computeStats(data);
// ❌ Never do this - remove all useMemo/useCallback
const filteredItems = useMemo(() => items.filter((item) => item.active), [items]);
const handleClick = useCallback(() => doSomething(), []);
```
**Rationale:** React 19's compiler optimizes re-renders automatically. Manual memoization adds complexity without benefit and can actually prevent optimizations. The compiler is smarter than manual memoization.
But they are ordinary tools, not forbidden ones. Use them where they earn it:
- a value or callback in a **dependency array**, where an unstable identity re-runs an effect or
re-subscribes a socket every render;
- a genuinely **expensive** computation over a large list;
- a prop passed to a **memoized** child.
```tsx
// ✅ Earns it — an unstable callback here would re-subscribe on every render
const onConnectionChange = useCallback((state) => setConnState(state), [setConnState]);
```
**This section used to say "NEVER — React 19's compiler handles memoization automatically", which was
wrong twice.** The React Compiler is a separate, opt-in build plugin and it is **not installed here**
(there is no `babel-plugin-react-compiler` in `package.json`); React 19 on its own memoizes nothing. And
the codebase never followed the rule — some 40 files use each hook. A convention that is both false and
universally ignored is worse than none, because it makes every other rule in this file look optional.
### Computation Functions Outside Components