Agentic Trading
Development

Contributing

How we work on this codebase.

How we work on this codebase.

Branch and PR flow

  1. Branch from main: git checkout -b <name>/<short-description>
  2. Commit early and often locally; tidy commits before PR
  3. Open a PR against main. CI runs lint + typecheck + tests + builds preview deploy
  4. Get a review, address feedback
  5. Merge — squash by default unless the commits genuinely tell a story

PR title: present-tense, imperative. Example: add paper broker partial fill support. PR description: what changed and why. Link the relevant ADR if applicable.

Commits

  • Imperative present tense: add X, not added X or adds X
  • One logical change per commit (within reason — don't split rename + edit hair-splitty)
  • Don't commit console.log debugging
  • Don't commit commented-out code. If it's worth keeping, it's worth a real implementation; if not, delete

Code style

  • TypeScript strict mode everywhere. No any, no @ts-ignore without a comment explaining why.
  • Prefer type over interface unless declaration merging is needed.
  • Functions over classes unless state genuinely benefits from class encapsulation.
  • Named exports over default exports, except where a tool / framework expects defaults (Next.js page/layout/route, default-exported tool definitions).
  • Path imports: @repo/<package> for cross-package; relative for within-package.
  • No barrel re-exports that hide where things live (i.e., don't make a packages/everything/index.ts).
  • Comments: only when the why isn't obvious from the code. Never describe what the code does — the code does that.

ESLint + Prettier enforce most of this. CI fails if pnpm lint fails.

Adding a new tool

  1. Create packages/tools/src/tools/<name>.ts exporting defineTool(...)
  2. Register it in packages/tools/src/registry.ts
  3. Write a unit test in packages/tools/src/tools/__tests__/<name>.test.ts
  4. If it's mode-restricted (e.g., write-only), set modes accordingly
  5. If it's an introspection tool, also add to introspectionToolNames
  6. Verify it shows up in the tool catalog UI by running pnpm dev and opening the skill editor

Adding a new database table or column

  1. Create a new migration: supabase migration new <description>
  2. Write the SQL in the generated file
  3. Apply locally: supabase migration up
  4. Regenerate types: supabase gen types typescript > packages/db/types.ts
  5. Update docs/architecture/data-model.md with the new shape + RLS notes
  6. PR — CI applies the migration to the dev project on preview deploy

Migrations are append-only. Don't edit a migration that has merged. Add a new one to change it.

Adding a new ADR

When you make a non-trivial architectural decision:

  1. Copy docs/decisions/0000-template.md to docs/decisions/<next-number>-<slug>.md
  2. Fill it out — Context, Decision, Alternatives, Consequences
  3. Update docs/README.md to list the new ADR
  4. Reference it from any relevant doc that touches the decision
  5. PR with the code change + the ADR together

A decision is non-trivial if:

  • It affects multiple packages / services
  • It commits us to a vendor / library / pattern
  • It has a real alternative that wasn't picked
  • A future reader would ask "why did they do it this way?"

Trivial decisions (file naming, choice of one helper library among equivalents) don't need ADRs.

Tests

  • Co-locate tests next to source: foo.ts + foo.test.ts (or in __tests__/foo.test.ts for many tests)
  • Unit tests with vitest — fast, watchable
  • Integration tests for the Execution Engine and broker adapters
  • For the agent runtime, use AI SDK's MockLanguageModelV2 to keep tests deterministic
  • No live network calls in tests (no real Hyperliquid, no real model calls)

Coverage isn't a number we enforce. Cover what's load-bearing — the engine, the schemas, anything where a bug means lost money.

Documentation

If your change affects how the system works:

  • Update the relevant doc in docs/
  • A docs-only PR is fine; small docs updates with code changes are even better
  • If you add a new package or service, add it to docs/architecture/overview.md's component list

If your change introduces a new vocabulary term: add it to docs/product/glossary.md.

Reviewing PRs

When reviewing:

  • Read the description — confirm what the PR claims to do matches the diff
  • Check trust boundaries — does the diff cross a boundary defined in trust-boundaries.md? Extra scrutiny.
  • Check engine path — any change to packages/execution-engine, packages/brokers/*, or risk caps gets careful read
  • Run it — for UI changes, pull the preview deploy and click around
  • Test scenarios the PR didn't cover — edge cases, empty states, error paths
  • Question additions — every new file, dependency, abstraction is debt; the bar is "do we need this?"

Approve when it ships value without regressions. Request changes when something is wrong, not when it's stylistic.

Don't

  • Don't add a dependency without checking bundle impact for client code, security history (npm audit), and license
  • Don't disable CI checks with --no-verify to land a PR. Fix the underlying issue.
  • Don't merge with failing CI. If CI is flaky, fix the flake, don't bypass.
  • Don't bypass the Execution Engine. Every code path that hits a broker goes through it.
  • Don't add if (process.env.NODE_ENV === 'production') { ... } for behavior differences. Use real config / feature flags.
  • Don't catch and swallow errors. Log + rethrow, or handle deliberately.
  • Don't write comments that restate the code. Write code that doesn't need them.

What to do when you find a bug

  1. Reproduce locally
  2. Write a failing test that captures the bug
  3. Fix the bug
  4. Confirm the test passes
  5. PR

For trading-critical bugs (anything in the engine, risk path, or broker adapters): also flag in the PR description so reviewers know to look closely.

Releases

In MVP: continuous deployment. Merge to main = prod deploy. No release process beyond that.

Post-MVP, we may introduce a release-train pattern if deploy cadence outpaces our ability to QA. Adding this isn't planned, just acknowledged.

When in doubt

  • Re-read the relevant ADR
  • Ask in PR comments
  • Open an issue for discussion before writing code if the direction isn't clear

The cost of confirming a direction is low. The cost of rewriting after merging the wrong direction is high.

On this page