Contributing to Lucid Layer
Thank you for your interest in contributing to Lucid — the autonomous AI infrastructure layer. Whether you’re fixing a bug, adding a feature, improving docs, or writing tests, your contribution matters.Table of Contents
- Getting Started
- Development Workflow
- Project Structure
- Code Standards
- Commit Conventions
- Testing
- Working with Solana Programs
- Working with EVM Contracts
- Working with the Offchain Engine
- Pull Request Process
- Reporting Issues
- Architecture Guidelines
- License
Getting Started
Prerequisites
| Tool | Version | Required for |
|---|---|---|
| Node.js | 20+ | Offchain engine + API |
| npm | 9+ | Package management |
| Rust + Cargo | Latest stable | Solana programs |
| Solana CLI | 1.18+ | On-chain development |
| Anchor | 0.30+ | Solana program framework |
| Docker | 24+ | Local deployment testing |
Development Workflow
Project Structure
gateway-litemay import fromengineenginemust NEVER import fromgateway-lite(ESLint-enforced)
Code Standards
TypeScript
- Strict mode — all new code must compile under
strict: true - No
any— use proper types.unknown+ type guards when truly dynamic. - No
import typein test files — babel/jest doesn’t support it. Use regularimport. - Feature-domain organization — code lives in its domain folder (memory, payment, deployment), not grouped by technical layer
- Interface-first — new features should define an
I*interface, then implement (e.g.,IDeploymentStore→PostgresDeploymentStore+InMemoryDeploymentStore) - Factory pattern — use
getXxx()singletons withresetXxx()for test teardown
Naming
| Element | Convention | Example |
|---|---|---|
| Files | camelCase | agentDeploymentService.ts |
| Interfaces | I prefix | IDeploymentStore |
| Types/Enums | PascalCase | ActualState, DeploymentEventType |
| Constants | UPPER_SNAKE | VALID_TRANSITIONS |
| Functions | camelCase | getDeploymentStore() |
| Test files | *.test.ts | control-plane.test.ts |
What NOT to do
- Don’t add comments to code you didn’t change
- Don’t add error handling for scenarios that can’t happen
- Don’t create abstractions for one-time operations
- Don’t add backward-compatibility shims — just change the code
- Don’t introduce circular dependencies between packages
Commit Conventions
Follow Conventional Commits:Types
| Type | When |
|---|---|
feat | New feature |
fix | Bug fix |
refactor | Code restructuring (no behavior change) |
test | Adding or updating tests |
docs | Documentation only |
chore | Build, CI, tooling, dependencies |
Scopes
Use the domain:memory, deployment, payment, receipt, epoch, identity, anchoring, reputation, compute, db.
Examples
Testing
Running tests
Writing tests
- Every new feature needs tests. No exceptions.
- Use
InMemory*stores for unit tests (fast, deterministic) - Mock external dependencies — deployers, providers, LLMs
- Follow existing patterns — look at nearby
__tests__/folders - Test the contract, not the implementation — test via the interface, not internal methods
Test structure
__tests__/ folder next to the source code.
Working with Solana Programs
Program layout
Each program lives inprograms/<name>/src/lib.rs with Anchor macros. PDAs follow the pattern ["seed", key.as_ref()].
Working with EVM Contracts
contracts/src/ — full parity with Solana programs where applicable.
Working with the Offchain Engine
Adding a new feature
- Define the interface in
engine/src/<domain>/ - Implement InMemory (tests) + Postgres (production) versions
- Add factory in
index.tswithgetXxx()/resetXxx() - Write tests in
__tests__/using the InMemory implementation - Add routes in
gateway-lite/src/routes/(thin handlers, delegate to engine) - Update OpenAPI in
openapi.yaml
Key patterns to follow
| Pattern | Where to look |
|---|---|
| Interface + InMemory + Postgres | deployment/control-plane/store.ts |
| Factory + singleton + reset | deployment/control-plane/index.ts |
| Status machine + transitions | deployment/control-plane/state-machine.ts |
| Optimistic locking | deployment/control-plane/in-memory-store.ts |
| DePIN dispatch | anchoring/dispatcher.ts |
| Memory type managers | memory/managers/ |
| Route handlers (thin) | gateway-lite/src/routes/ |
Pull Request Process
- Branch from
master— usefeat/,fix/,refactor/prefixes - All checks must pass — type-check + tests + lint
- No regressions — test count should stay the same or increase
- One concern per PR — don’t mix features with refactors
- Describe the why — PR description should explain motivation, not just list changes
- Update docs if needed — CLAUDE.md, OpenAPI, README
PR template
Reporting Issues
Open a GitHub issue with:- What you expected to happen
- What actually happened (include error messages, logs)
- Steps to reproduce (minimal, specific)
- Environment — OS, Node.js version, Solana CLI version, relevant env vars
Architecture Guidelines
Before making significant changes, understand the core principles:- Lucid is the control plane, not the execution authority. Agents run on decentralized providers. Lucid coordinates — it doesn’t own.
- Local truth, global supervision. Agent memory is agent-owned (SQLite). Deployment state is fleet-wide (Supabase). Never mix these.
-
Interface-first, swap later. Every external dependency (
IDepinStorage,INFTProvider,IDeploymentStore,ISecretsResolver) is behind a swappable interface. - Events, not coupling. State changes emit events. Consumers react. Don’t create direct cross-domain function calls.
- L3 is operational, not canonical. Supabase stores operational projections. Chain + DePIN are the source of truth. If Supabase is lost, rebuild from L1+L2.
License
By contributing, you agree that your contributions will be licensed under:- Engine & programs: Apache License 2.0
- Gateway-lite: AGPL-3.0
.png?fit=max&auto=format&n=VsjUqn6fLqEhBiuI&q=85&s=8b4c7e6431e9a6af1ef23b77bb4ff5fd)
.png?fit=max&auto=format&n=VsjUqn6fLqEhBiuI&q=85&s=d5651a45e4bfbabc33f74e146af3f94a)