Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,42 @@ openchat/
- Assume dev servers are already running; do not start `bun dev*` unless explicitly requested.
- Prefer build/typecheck/test verification when runtime validation is needed.

## Coding Standards & Banned Patterns

These rules apply to all AI agents and human contributors working in this repository.

### Choose Your Bug — Why We Ban useEffect Misuse

Misusing `useEffect` doesn't help you avoid bugs — it just lets you choose which bug you get. Every effect that syncs state, fetches data, or reacts to user actions is a latent race condition, stale closure, or infinite loop waiting to happen. The rules below eliminate this entire class of bugs.

### Rules

**Rule 1 — BAN direct use of `useEffect`**

Do not use `useEffect` directly. Use `useMountEffect()` only for rare, justified external side-effect syncs (e.g. third-party SDK initialization). Any other use must be approved and documented with a comment explaining why no alternative works.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 useMountEffect has no defined source or import path

Rule 1 instructs contributors to "Use useMountEffect()", but this hook does not exist in React's core API, and a project-wide search confirms it appears nowhere else in the codebase — no custom hook file, no react-use import, no @react-hookz/web dependency. An AI agent or human contributor following this rule literally has no way to know where to import it from, making the rule unenforceable as written.

You should either:

  • Create and export a useMountEffect utility hook (e.g. apps/web/src/hooks/useMountEffect.ts) and reference its import path here, or
  • Replace the reference with an existing, well-known alternative like useEffect with [] (alongside a clear explanation of the constraints), or reference a specific library (e.g. useEffectOnce from react-use) that is already in package.json.

Confidence this is correct: 5/5 — confirmed by grep across the entire repository.


**Rule 2 — BAN `as any` casts**

Do not use TypeScript `as any` casts. Use proper types, generics, or type guards. If you cannot type something, use `unknown` and narrow it explicitly. `as any` silences the compiler and hides real bugs.

**Rule 3 — Derive state inline, never sync it with effects**

Do not use `useEffect` + `useState` to sync or transform other state. Derive computed values inline during render, or use `useMemo` if the computation is expensive. Effect-based state sync always has at least one render where the derived state is stale.

**Rule 4 — Use data-fetching libraries instead of fetch-in-effect**

Do not fetch data inside `useEffect`. Use `useQuery` (TanStack Query) or an equivalent data-fetching library. These libraries handle caching, deduplication, background refetching, loading states, and error states correctly. Effect-based fetching is a manual reimplementation of these features, done worse.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Rule 4 ambiguously excludes Convex's useQuery

The rule currently reads: "Use useQuery (TanStack Query) or an equivalent data-fetching library." However, this project's backend is Convex, and practically all server-state queries are performed via Convex's useQuery (imported from convex/react) — not TanStack Query. An AI agent reading this strictly might flag or avoid Convex's useQuery as non-compliant.

The PR description clarifies this intent, but the actual rule text in AGENTS.md does not. Consider making this explicit in the rule itself:

Suggested change
Do not fetch data inside `useEffect`. Use `useQuery` (TanStack Query) or an equivalent data-fetching library. These libraries handle caching, deduplication, background refetching, loading states, and error states correctly. Effect-based fetching is a manual reimplementation of these features, done worse.
Do not fetch data inside `useEffect`. Use `useQuery` (TanStack Query), Convex's `useQuery` (`convex/react`), or an equivalent data-fetching library. These libraries handle caching, deduplication, background refetching, loading states, and error states correctly. Effect-based fetching is a manual reimplementation of these features, done worse.

Confidence this is correct: 4/5 — the current wording creates genuine ambiguity for a codebase that relies heavily on Convex's reactive queries.


**Rule 5 — Use event handlers for user actions, not effect flags**

Do not use `useEffect` to react to user interactions by watching a flag or state change. Put the logic directly in the event handler. Effects that watch for 'action triggers' fire one render late and make code impossible to follow.

**Rule 6 — Reset components with keys, not dependency choreography**

Do not use complex `useEffect` dependency arrays to reset or reinitialize component state when an ID or key prop changes. Instead, pass the relevant value as the `key` prop to the component — React will fully remount it, resetting all state cleanly with zero effect logic.

## ANTI-PATTERNS (THIS PROJECT)
- Follow **Coding Standards & Banned Patterns** above for enforced React and TypeScript rules (`useEffect` misuse, `as any`, and related patterns).
- Do not use `NEXT_PUBLIC_*` env vars in web code.
Comment on lines 88 to 90

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 apps/web/AGENTS.md ANTI-PATTERNS not cross-referenced

The cross-reference to Coding Standards & Banned Patterns was added to the root AGENTS.md's ANTI-PATTERNS section, but apps/web/AGENTS.md — the most relevant child file since it governs all React/UI code — has its own ANTI-PATTERNS section that was not updated. AI agents working exclusively in apps/web/ will load the child AGENTS.md first, and may miss the new coding standards entirely.

Consider adding a pointer in apps/web/AGENTS.md's ANTI-PATTERNS section, e.g.:

- Follow **Coding Standards & Banned Patterns** in root `AGENTS.md` for all React and TypeScript rules (`useEffect` misuse, `as any`, etc.).

Confidence this is correct: 3/5 — the root policy technically applies globally, but discoverability from the child file is meaningfully lower without an explicit reference.

- Do not treat `docs-site/` like a regular workspace; it is a git subtree.
- Do not introduce new logic against deprecated message fields when `chainOfThoughtParts` exists.
Expand Down
Loading