01

Git & Branch Standards

Branch Naming

All branches must follow this format. Use kebab-case (lowercase, hyphens) and always include the ticket/issue number when one exists.

format
# Pattern
<prefix>/<ticket>-<description>

# Examples
feature/HE2-142-add-team-invite-flow
bugfix/HE2-305-fix-thread-pagination
hotfix/HE2-410-patch-auth-redirect
chore/HE2-99-upgrade-nextjs
refactor/HE2-200-simplify-billing-service
Prefix Use When
feature/Adding new functionality
bugfix/Fixing a bug
hotfix/Urgent production fix
release/Preparing a release
chore/Maintenance, dependency updates
docs/Documentation changes only
refactor/Code restructuring without behavior change
Not Allowed
myfix                          # No prefix, no ticket
Feature/add-stuff              # Wrong case
feature/addTeamInviteFlow      # camelCase not allowed
fix_something_quick            # Underscores not allowed
john/testing                   # Developer names are not prefixes

Main Branch

The main branch is main
Never push directly to main — always go through a PR
All feature branches are merged via squash-and-merge

Branch Cleanup

Mandatory Cleanup Policy

Branches are deleted immediately after PR merge — no exceptions. Enable "Delete branch after merge" in your GitHub settings. Branches inactive for more than 2 weeks without an open PR will be deleted automatically.

Enable "Delete branch after merge" in GitHub settings
Do not keep stale branches around
Before starting work, always pull the latest from main and create a fresh branch
02

Commit Message Standards

All commits must follow the Conventional Commits format.

format
<type>(<scope>): <subject>

Rules

Subject: imperative mood, max 72 characters, no trailing period
Scope: the domain or area affected (e.g., auth, billing, agent, frontend)
Body (optional): explain why, not what — the diff shows what changed

Allowed Types

TypeWhen to Use
featNew feature or functionality
fixBug fix
docsDocumentation only
refactorCode change that neither fixes a bug nor adds a feature
testAdding or updating tests
choreBuild process, tooling, dependency updates
ciCI/CD pipeline changes
perfPerformance improvement

Examples

bash
feat(agent): add retry logic for failed sandbox executions
fix(billing): prevent duplicate Stripe webhook processing
refactor(knowledge-base): extract chunking into dedicated service
test(auth): add integration tests for phone auth flow
chore(deps): upgrade @tanstack/react-query to v5
ci(deploy): add staging environment to GitHub Actions
perf(redis): batch cache invalidation for thread updates
Not Allowed
fixed stuff                    # No type, vague description
feat: Add New Feature.         # Trailing period, wrong case
update                         # No type, no scope, no description
WIP                            # Never commit WIP to shared branches
No Co-Author Attribution

Do not add Co-Authored-By lines for Anthropic or Claude in commit messages.

03

Pull Request Standards

PR Size Limits

Target < 400 lines
Needs justification 400–1000 lines
Not allowed > 1000 lines

If your PR is growing large, split it into logical, independently reviewable chunks. Each chunk should be functional on its own.

PR Title

Follow the same Conventional Commits format as commit messages:

example
feat(agent): add retry logic for failed sandbox executions

PR Description (Required)

Every PR must include the following sections:

markdown
## Summary
<!-- 2-3 bullet points explaining WHAT changed and WHY -->
- Added retry logic for sandbox execution failures
- Implements exponential backoff with max 3 retries
- Addresses intermittent timeout issues reported in #142

## Related Issue
Fixes #142

## Type of Change
- [ ] New feature
- [ ] Bug fix
- [ ] Refactor
- [ ] Documentation
- [ ] CI/CD
- [ ] Other (describe)

## Testing
- [ ] Unit tests added/updated
- [ ] Integration tests added/updated
- [ ] Manual testing performed (describe steps)
- [ ] Feature flag verified in staging

## Self-Review Checklist
- [ ] Code follows project conventions
- [ ] No secrets, API keys, or tokens committed
- [ ] No console.log or debug statements left in
- [ ] No any types in TypeScript
- [ ] Feature flag wraps new functionality
- [ ] Database migrations are backward-compatible
- [ ] Error handling follows project patterns
- [ ] Accessibility checked (if UI change)

PR Review Rules

Minimum 1 approval required before merge
All CI checks must pass
Resolve all review comments before merging
Do not merge your own PR without at least one review
Use "Request Changes" for blocking issues, "Comment" for suggestions
04

Feature Flags

Mandatory for All New Changes

Every new feature, UI change, or behavioral modification must be wrapped in a feature flag. This allows safe rollback without redeployment, gradual rollout, A/B testing, and decoupling deployment from release.

Implementation

typescript — frontend
// Use the feature flag hook
const { isEnabled } = useFeatureFlag('new-thread-ui');

if (isEnabled) {
  return <NewThreadUI />;
}
return <LegacyThreadUI />;
python — backend
from utils.feature_flags import is_feature_enabled

async def process_request(team_id: str):
    if await is_feature_enabled("new-billing-logic", team_id):
        return await new_billing_flow()
    return await legacy_billing_flow()

Feature Flag Lifecycle

1
Create
Add the flag before starting development
2
Develop
All new code behind the flag (default: OFF)
3
Test
Enable in staging, run full test suite
4
Release
Gradually enable: 10% → 50% → 100%
5
Cleanup
Remove flag and dead code after 2+ weeks at 100%

Naming Convention

format
<domain>-<feature-description>

# Examples
agent-retry-logic
billing-new-checkout
thread-markdown-preview
05

Security & Secrets

Zero-Tolerance Policy

Committing secrets (API keys, tokens, passwords, credentials) is a terminable offense in regulated environments. This policy has no exceptions.

Banned from Source Code

API keys (Anthropic, Gemini, Stripe, Tavily, Daytona, etc.)
Database connection strings
JWT secrets or signing keys
OAuth client secrets
AWS credentials or access keys
Any .env or .env.local file contents
Private keys, certificates, or PEM files

Where Secrets Belong

EnvironmentMethod
Local development.env / .env.local files (already in .gitignore)
CI/CDGitHub Actions secrets or environment variables
Staging/ProductionAWS Secrets Manager / environment variables

Pre-Commit Checks

A pre-commit hook scans for potential secrets before allowing commits
If the hook blocks your commit, do not bypass it with --no-verify
If you accidentally commit a secret, notify the team immediately — the secret must be rotated, not just removed from history

Frontend Security

Never expose server-side keys via NEXT_PUBLIC_ prefix
Never use dangerouslySetInnerHTML without DOMPurify sanitization
Set auth cookies as HttpOnly, Secure, SameSite=Strict
Never return raw exception details to the client

Backend Security

Use secrets module for OTP/token generation — never random
Use hmac.compare_digest for comparisons — never ==
Never log PII in plaintext — always mask
Encrypt PII fields at rest
Use verified SSL for all database and API connections
06

Environment & Tooling

Tool Versions

All developers must use the versions specified in mise.toml. Use mise to manage tool versions automatically.

Node.js
20
🐍
Python
3.11.10
UV
0.6.5

Running Commands in the Right Directory

Common Mistake

Running npm install from the project root will create a rogue node_modules/ and package-lock.json in the root — this breaks the build and pollutes the repo.

CommandRun FromNot From
npm installfrontend/Never from project root
npm run devfrontend/Never from project root
npm run buildfrontend/Never from project root
uv syncbackend/Never from project root
uv run api.pybackend/Never from project root
uv run pytestbackend/Never from project root
docker compose uphe2-beta/ (root)Not from subdirectories
python setup.pyhe2-beta/ (root)Not from subdirectories

Local Development Setup

bash
# 1. Clone and enter the repo
git clone <repo-url> && cd he2-beta

# 2. Run the setup wizard
python setup.py

# 3. Install frontend dependencies
cd frontend && npm install

# 4. Install backend dependencies
cd ../backend && uv sync

# 5. Start Redis (required for backend)
docker compose up redis

# 6. Start backend (new terminal, from backend/)
cd backend && source .venv/bin/activate && uv run api.py

# 7. Start frontend (new terminal, from frontend/)
cd frontend && npm run dev

Environment Variables

Backend (.env in backend/):

REDIS_HOST — use localhost for local dev, redis inside Docker
ANTHROPIC_API_KEY, GEMINI_API_KEY — LLM provider keys
DAYTONA_API_KEY — sandbox provider
TAVILY_API_KEY — web search

Frontend (.env.local in frontend/):

NEXT_PUBLIC_BACKEND_URL — defaults to http://localhost:8000/api
NEXT_PUBLIC_ENV_MODE — environment mode flag
07

Frontend Standards

TypeScript

Strict mode — no exceptions
No any types — use proper typing or unknown if truly needed
Use TypeScript interfaces/types for all props, API responses, and state

Components

Always use shadcn/ui components from components/ui/ — never raw HTML elements (<button>, <input>, <select>, etc.)
Always use Remix Icons via <i className="ri-icon-name-line"> — never import from react-icons
Functional components with hooks only — no class components
Keep components focused and small

State Management

WhatTool
Server state (API data)React Query (@tanstack/react-query)
Global client stateZustand stores (stores/)
Local component stateuseState / useReducer
Form stateReact Hook Form

Styling

Tailwind CSS 4 for all styling
shadcn/ui + DaisyUI for component primitives
CSS variables for theming
No inline style={{}} attributes unless absolutely necessary
No external CSS files for component-specific styles

Code Quality

No console.log in committed code — use proper logging or remove
No commented-out code blocks — delete them, git has history
No unused imports or variables
Run npm run lint and npm run format:check before pushing
08

Backend Standards

Python

All functions must have type annotations
Use async/await for all I/O operations (database, API calls, file I/O)
Use Pydantic models for all request/response schemas

Follow the domain-driven structure:

structure
domain/
  <feature>/
    api/          # Routes
    service/      # Business logic
    repository/   # Data access
    models/       # Data models

Database

All database operations use asyncpg (async)
Migrations go in backend/supabase/migrations/ as SQL files
Migrations must be backward-compatible — never drop columns that production code still reads
Always add indexes for columns used in WHERE clauses or JOINs
Use parameterized queries — never string-concatenate SQL

Error Handling

Never expose internal error details to the client
Use structured error responses with appropriate HTTP status codes
Log errors with context using structlog
Never catch and silently swallow exceptions

LLM Integration

All LLM calls go through the LiteLLM abstraction (infrastructure/llm/)
Never hardcode model names — use configuration
Always handle rate limits and timeouts gracefully
09

Testing Standards

Backend

Coverage Threshold: 70% Minimum

PRs that drop coverage below 70% will be blocked. Write tests for all new business logic.

MarkerWhen to Use
@pytest.mark.unitNo external dependencies needed
@pytest.mark.integrationRequires DB, Redis, or external services
@pytest.mark.propertyHypothesis property-based tests
@pytest.mark.slowTests that take >5 seconds
bash
# Run unit tests before pushing
uv run pytest -m "not integration"
Mock external services, not internal ones

Frontend

Write tests for utility functions and hooks
Use React Testing Library for component tests
Test user interactions, not implementation details
bash
# Run tests before pushing
npm test
10

Code Review Checklist

Use this checklist when reviewing (or self-reviewing) a PR. Every item must be checked before approving.

General

Code Quality

Security

Architecture

Testing

0 / 23 checked

Quick Reference Card

Everything you need at a glance. Bookmark this section.

Branch
feature/HE2-123-add-widget
Commit
feat(widget): add interactive widget to dashboard
PR Title
feat(widget): add interactive widget to dashboard
PR Size
< 400 lines
Secrets
.env only, never in code
npm
Run from frontend/, NEVER from root
uv
Run from backend/
Feature Flags
All new features behind feature flags
Branches
Deleted after merge
Tests
Required, 70% coverage minimum
Types
No `any` in TypeScript, type all Python functions
Compliance
SOC 2 Type 2 + GDPR — check compliance/policies/ when in doubt