# FourIA — Contributing Guidelines

Mandatory development standards for all contributors (humans and AI agents).

---

## Pre-Commit Hook

The `.githooks/pre-commit` hook runs from the repository root on every commit and
only runs the checks that match the staged files:

```bash
# when TypeScript/JavaScript (or other oxfmt-formatted) files are staged:
bun run lint
bun run format:check

# when Elixir files (*.ex/*.exs) are staged:
mix check
```

`mix check` is the root Mix workspace alias. It runs `mix format --check-formatted`
and `mix credo --strict` for every Elixir project under `apps/`. Lerma CI invokes the
same strict Credo command from the root. Enter the root Nix development shell first
(`nix develop .`) so Bun and Mix are available, then fetch all dependencies with
`mix deps.get` followed by `mix workspace.run -t deps.get`.

Bun install configures Git to use `.githooks` through the root package's `prepare`
script. If you are not running `bun install`, enable it manually:

```bash
git config core.hooksPath .githooks
```

The hook is bypassed when `HUSKY=0` or `SKIP_HOOKS=1` is set in the environment
(the release workflow sets `HUSKY=0` so `release-it` can commit version bumps in
CI, which has no Elixir toolchain). When Elixir files are staged but `mix` is not
installed, the hook skips `mix check` with a warning instead of failing — run it
in the Nix dev shell (`nix develop .`) before merging.

**Commits are blocked if linting or formatting fails.** Run these manually before committing:

```bash
bun run lint           # oxlint — static analysis
bun run format:check   # oxfmt — formatting check
bun run format         # auto-fix formatting
bun run lint:fix       # auto-fix linting issues
```

For Elixir changes, run the strict workspace checks (exit 0):

```bash
mix credo --strict
mix check
mix precommit
```

---

## Dependency Automation

Dependencies are updated automatically by **Dependabot** (`.github/dependabot.yml`):

| Ecosystem        | Scope                       | Schedule |
| ---------------- | --------------------------- | -------- |
| `mix`            | `apps/lerma` (Elixir deps)  | weekly   |
| `bun`            | workspace root (`bun.lock`) | weekly   |
| `github-actions` | CI workflows                | weekly   |

Dependabot PRs are labelled `dependencies` (+ `Lerma` or `Fouria`) and must pass CI before merge.

### License Audit (private-source compliance)

Lerma is a private-source project, so its dependencies must not carry copyleft licenses
(GPL, AGPL, LGPL, ...). `mix lerma.license_audit` (run in the `Lerma CI` workflow via the
root `mix license_audit` alias) fails when a dependency declares a license outside the
allowlist in `Lerma.LicenseAudit.allowed_licenses/0`, and also fails when a dependency's
license cannot be determined.
When adding a new dependency, extend the allowlist **deliberately** — never blanket-allow a
license without checking its terms.

---

## Test-Driven Development (TDD)

**TDD is mandatory.** Write failing tests first, then implement.

### Coverage Requirements

| Component           | Unit Test Coverage | Integration Test Coverage |
| ------------------- | ------------------ | ------------------------- |
| API implementations | ≥ 95%              | ≥ 80%                     |
| Business logic      | ≥ 80%              | ≥ 80%                     |
| UI components       | ≥ 80%              | N/A                       |
| Config/IaC modules  | ≥ 80%              | N/A                       |

### Testing Tools

| Tool       | Purpose                                  |
| ---------- | ---------------------------------------- |
| Vitest     | Unit + integration tests (all packages)  |
| cctr       | CLI corpus tests for E2E (CLI tools)     |
| Playwright | Browser E2E testing for the dashboard    |
| jsdom      | DOM simulation for React component tests |

### AI Skills for TDD

Always load these skills before writing code:

- `tdd-workflow` — Test-driven development methodology
- `ai-regression-testing` — Patterns for AI-assisted regression testing
- `webapp-testing` — Playwright-based browser testing
- `e2e-testing` — End-to-end testing patterns
- `openclaw-plugin-tdd` — TDD for OpenClaw provider plugins

### TDD Workflow

1. **RED**: Write failing test → `bun run test` to verify failure
2. **GREEN**: Implement minimal code to pass → `bun run test` to verify
3. **REFACTOR**: Clean up code, keep tests passing
4. **VALIDATE**: `bun run typecheck` + `bun run lint` + `bun run test`

---

## Runtime: Bun over npm

**Always use Bun.** Never use npm, yarn, or pnpm.

| Context    | Command             |
| ---------- | ------------------- |
| Install    | `bun install`       |
| Run script | `bun run <script>`  |
| Test       | `bun run test`      |
| Add dep    | `bun add <package>` |
| Run file   | `bun <file.ts>`     |

**Exception:** CI/CD workflows (GitHub Actions) may use npm for compatibility, but local development MUST use Bun.

---

## Shared Dependencies

Root `package.json` defines shared dev dependencies via the monorepo workspace:

| Dependency                        | Version   | Purpose                        |
| --------------------------------- | --------- | ------------------------------ |
| `typescript`                      | `^5.9.3`  | Type checking (strict mode)    |
| `vitest`                          | `^4.1.8`  | Test runner (all packages)     |
| `oxlint`                          | `latest`  | Linting                        |
| `oxfmt`                           | `latest`  | Formatting                     |
| `wrangler`                        | `^4.97.0` | Cloudflare Workers CLI         |
| `@cloudflare/vitest-pool-workers` | `0.16.12` | Vitest integration for Workers |

Catalog dependencies (shared version pinning):

| Package      | Version     |
| ------------ | ----------- |
| `openclaw`   | `^2026.6.6` |
| `wrangler`   | `latest`    |
| `@types/bun` | `latest`    |

**Always use catalog refs** when adding these to sub-package.json: `"wrangler": "catalog:"`

---

## Code Conventions

### TypeScript

- **Strict mode** (`strict: true` in all tsconfig.json files)
- Prefer explicit types for function signatures
- Use Zod schemas for config validation
- Never use `any` without explicit justification
- One module per file — never nest multiple classes in one file

### Hono (Worker Framework)

- Route handlers should be thin — extract logic to separate modules
- Use `c.json()`, `c.html()` for responses
- Middleware order matters: logging → auth → RBAC → route handler

### Environment Variables

- Secrets come from env vars, never from config files
- Use Worker Secrets (`wrangler secret put`) for production
- Use `.dev.vars` for local development (gitignored)
- If changing env vars: update `.dev.vars.example`, `src/gateway/env.ts`, and relevant docs

### Naming

- Files: kebab-case (`user-secrets-store.ts`)
- Functions: camelCase (`buildEnvVars`)
- Types/Interfaces: PascalCase (`AppEnv`)
- Constants: UPPER_SNAKE_CASE (`GATEWAY_PORT`)

---

## Validation Checklist

**Before submitting any change:**

- [ ] `bun run typecheck` passes
- [ ] `bun run lint` passes
- [ ] `bun run format:check` passes
- [ ] `bun run test` passes (all packages)
- [ ] New code has ≥ 80% unit test coverage (≥ 95% for API routes)
- [ ] Integration tests pass with ≥ 80% coverage (for API changes)
- [ ] If changing env vars: update `.dev.vars.example`, docs, and `src/gateway/env.ts`
- [ ] If adding routes: add tests
- [ ] If releasing: bump component version per [VERSIONING.md](../VERSIONING.md)

---

## Pull Request Guidelines

1. **One concern per PR** — don't mix feature work with refactoring
2. **TDD evidence** — tests committed before or alongside implementation
3. **No commented-out code** — remove debug lines before PR
4. **No secrets** — never commit `.dev.vars`, API keys, or tokens
5. **Use `bun run format`** before final push

---

## AI Agent Guidelines

When AI agents contribute to this codebase:

1. **Read `AGENTS.md` first** — each component has its own AGENTS.md
2. **Load relevant skills** — check the `available_skills` list for domain-specific guidance
3. **Follow TDD** — write tests before implementation, even when suggested by AI
4. **Never commit** without explicit user approval
5. **Read OpenClaw docs** before modifying OpenClaw-related code (config, CLI, gateway)
6. **Use the exploration tools** to understand existing patterns before writing new code
