F FourIA GitHub ↗

FourIA — Contributing Guidelines

On this page

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:

# 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:

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:

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):

mix credo --strict
mix check
mix precommit

Dependency Automation

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

EcosystemScopeSchedule
mixapps/lerma (Elixir deps)weekly
bunworkspace root (bun.lock)weekly
github-actionsCI workflowsweekly

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

ComponentUnit Test CoverageIntegration Test Coverage
API implementations≥ 95%≥ 80%
Business logic≥ 80%≥ 80%
UI components≥ 80%N/A
Config/IaC modules≥ 80%N/A

Testing Tools

ToolPurpose
VitestUnit + integration tests (all packages)
cctrCLI corpus tests for E2E (CLI tools)
PlaywrightBrowser E2E testing for the dashboard
jsdomDOM 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.

ContextCommand
Installbun install
Run scriptbun run <script>
Testbun run test
Add depbun add <package>
Run filebun <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:

DependencyVersionPurpose
typescript^5.9.3Type checking (strict mode)
vitest^4.1.8Test runner (all packages)
oxlintlatestLinting
oxfmtlatestFormatting
wrangler^4.97.0Cloudflare Workers CLI
@cloudflare/vitest-pool-workers0.16.12Vitest integration for Workers

Catalog dependencies (shared version pinning):

PackageVersion
openclaw^2026.6.6
wranglerlatest
@types/bunlatest

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

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