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