Thank you for your interest in contributing to Aequor! We appreciate your help in building a universal AI orchestration platform that treats AI requests as constraint satisfaction problems.
This guide will help you get started with contributing to the project. Whether you're fixing a bug, implementing a new feature, or improving documentation, we welcome your contributions.
- Code of Conduct
- Getting Started
- Development Workflow
- Project Structure
- Coding Standards
- Testing Guidelines
- Documentation Standards
- Commit Messages
- Pull Request Process
- Reporting Issues
- License
We are committed to providing a welcoming and inclusive environment for all contributors. Please:
- Be respectful and constructive
- Welcome newcomers and help them learn
- Focus on what is best for the community
- Show empathy towards other community members
If you encounter any issues, please contact the maintainers.
Before you begin contributing, ensure you have the following installed:
Required:
Optional (for native modules):
- Rust toolchain (for performance-critical modules)
- Docker (for running PostgreSQL, Redis, ChromaDB)
- Fork the repository on GitHub
- Clone your fork locally:
git clone https://github.com/YOUR_USERNAME/SmartCRDT.git
cd SmartCRDT/demo- Add the upstream remote:
git remote add upstream https://github.com/SuperInstance/SmartCRDT.git- Install dependencies:
npm install- Build all packages:
npm run build- Run tests to verify your setup:
npm testYou're ready to contribute when:
# All packages build successfully
npm run build
# All tests pass
npm test
# Linter passes
npm run lintWe follow a standard Git workflow with feature branches.
Always create a new branch for your work. Never work directly on main.
git checkout -b feature/your-feature-name
# or
git checkout -b fix/your-bug-fixBranch Naming Conventions:
feature/- New featuresfix/- Bug fixesdocs/- Documentation changesrefactor/- Code refactoringtest/- Test additions or changesperf/- Performance improvements
Develop your feature or fix following our Coding Standards.
Before committing, ensure:
# Run all tests
npm test
# Run tests with coverage
npm run test:coverage
# Run linter
npm run lint
# Format code
npm run formatUse Conventional Commits format:
git add .
git commit -m "feat: add new routing algorithm"git push origin feature/your-feature-nameThen create a pull request on GitHub following our PR Process.
Periodically sync with upstream:
git fetch upstream
git rebase upstream/mainAequor is a monorepo using npm workspaces with multiple packages.
demo/
├── packages/ # All packages
│ ├── protocol/ # Protocol definitions (types, interfaces)
│ ├── core/ # Core libcognitive API
│ ├── cascade/ # Cascade router + query analysis
│ ├── superinstance/ # SuperInstance (Context, Intention, LucidDreamer)
│ ├── privacy/ # Privacy suite (encryption, R-A Protocol)
│ ├── swarm/ # CRDT and distributed state
│ ├── cli/ # Command-line interface
│ ├── embeddings/ # Embedding services
│ └── ... # Other packages
├── tests/ # Cross-package integration tests
│ ├── unit/
│ └── e2e/
├── docs/ # Project documentation
├── scripts/ # Build and utility scripts
├── .github/ # GitHub workflows, templates, etc.
├── package.json # Root package.json
├── tsconfig.json # Root TypeScript config
├── .eslintrc.js # ESLint configuration
├── .prettierrc # Prettier configuration
└── CLAUDE.md # AI agent project guide
The dependency hierarchy is:
@lsi/protocol # Base types - no dependencies
↓
@lsi/core # Core API - depends on protocol
↓
@lsi/cascade # Router - depends on protocol, core
↓
@lsi/superinstance # Main platform - depends on all above
↓
@lsi/privacy # Privacy suite - depends on protocol
@lsi/swarm # CRDT store - depends on protocol
Key Rule: Never create circular dependencies. Always depend on lower-level packages.
| What You Want | Where It Is |
|---|---|
| Protocol types | packages/protocol/src/index.ts |
| Cascade router | packages/cascade/src/router/CascadeRouter.ts |
| Intent router | packages/cascade/src/router/IntentRouter.ts |
| Privacy layer | packages/privacy/src/protocol/RedactionAdditionProtocol.ts |
| CRDT store | packages/swarm/src/crdt/CRDTStore.ts |
| Context plane | packages/superinstance/src/context/ContextPlane.ts |
| Intention plane | packages/superinstance/src/intention/IntentionPlane.ts |
| LucidDreamer | packages/superinstance/src/luciddreamer/LucidDreamer.ts |
We use TypeScript with strict type checking throughout the project.
General Rules:
- Use strict TypeScript - Enable all strict checks
- Avoid
any- Useunknownif type is truly unknown - Explicit types on exports - Public APIs must have explicit types
- Prefer
interfacefor public APIs - Usetypefor unions/intersections - Use
readonly- Mark immutable properties as readonly - Prefer
constassertions - Useas constfor literal types
// ✅ Good
interface User {
readonly id: string;
readonly name: string;
email: string;
}
const config = {
endpoint: 'https://api.example.com',
timeout: 5000,
} as const;
// ❌ Bad
const user: any = {};
const data = user.data; // No type safetyFollow these naming conventions:
| Category | Convention | Example |
|---|---|---|
| Files | PascalCase for classes/components | CascadeRouter.ts |
| Files | camelCase for utilities | stringUtils.ts |
| Classes | PascalCase | class SemanticCache {} |
| Interfaces | PascalCase, no I prefix |
interface Query {} |
| Types | PascalCase | type Embedding = number[]; |
| Constants | UPPER_SNAKE_CASE | const MAX_RETRIES = 3; |
| Functions/Methods | camelCase | function calculateScore() {} |
| Private properties | camelCase with _ prefix |
private _cache: Map; |
| Enums | PascalCase | enum LogLevel {} |
Organize files by feature, not by type:
src/
├── router/
│ ├── CascadeRouter.ts
│ ├── IntentRouter.ts
│ └── index.ts
├── cache/
│ ├── SemanticCache.ts
│ ├── CacheEntry.ts
│ └── index.ts
└── utils/
├── embeddings.ts
└── strings.ts
Barrel exports (index.ts): Re-export public APIs
// router/index.ts
export { CascadeRouter } from './CascadeRouter';
export { IntentRouter } from './IntentRouter';Within a file, organize in this order:
- File header comment
- Imports (grouped: stdlib, external, internal)
- Type definitions
- Constants
- Class/function implementations
- Exports
/**
* CascadeRouter implements complexity-based routing for AI queries.
*
* @packageDocumentation
*/
// Stdlib
import { performance } from 'node:perf_hooks';
// External
import { OpenAI } from 'openai';
// Internal
import type { Query, RoutingDecision } from '@lsi/protocol';
// Types
interface RouterConfig {
readonly maxRetries: number;
readonly timeout: number;
}
// Constants
const DEFAULT_TIMEOUT = 5000;
// Implementation
export class CascadeRouter {
// ...
}Required for:
- All exported functions and methods
- All exported classes and interfaces
- Complex types
/**
* Routes a query to the appropriate model based on complexity analysis.
*
* @param query - The query to route
* @param context - Optional context for routing decisions
* @returns Promise resolving to routing decision
* @throws {RoutingError} When routing fails after max retries
*
* @example
* ```typescript
* const router = new CascadeRouter();
* const decision = await router.route(query);
* if (decision.useLocal) {
* // Handle locally
* }
* ```
*/
async route(
query: Query,
context?: RoutingContext
): Promise<RoutingDecision> {
// Implementation
}We use ESLint with TypeScript support. Configuration in .eslintrc.js:
module.exports = {
parser: '@typescript-eslint/parser',
extends: [
'eslint:recommended',
'@typescript-eslint/recommended',
],
rules: {
'no-console': 'warn',
'@typescript-eslint/no-unused-vars': 'error',
'prefer-const': 'error',
},
};We use Prettier for consistent formatting. Configuration in .prettierrc:
{
"semi": true,
"singleQuote": false,
"tabWidth": 2,
"trailingComma": "es5",
"printWidth": 80,
"arrowParens": "avoid",
"endOfLine": "lf"
}Before committing, run:
npm run format# Run all tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm run test:coverage
# Run unit tests only
npm run test:unit
# Run end-to-end tests
npm run test:e2e
# Test specific package
cd packages/cascade && npm test
# Test specific file
npx vitest run packages/cascade/src/router/CascadeRouter.test.tsWe use Vitest as our test runner (compatible with Jest).
Test File Location:
packages/cascade/src/router/
├── CascadeRouter.ts
└── CascadeRouter.test.ts # Test file next to implementation
Test Structure:
import { describe, it, expect, beforeEach } from 'vitest';
import { CascadeRouter } from './CascadeRouter';
describe('CascadeRouter', () => {
let router: CascadeRouter;
beforeEach(() => {
router = new CascadeRouter();
});
describe('route()', () => {
it('should route simple queries locally', async () => {
const query = createSimpleQuery();
const decision = await router.route(query);
expect(decision.useLocal).toBe(true);
expect(decision.model).toBe('local');
});
it('should route complex queries to cloud', async () => {
const query = createComplexQuery();
const decision = await router.route(query);
expect(decision.useLocal).toBe(false);
expect(decision.model).toContain('gpt');
});
it('should throw error for invalid query', async () => {
const query = createInvalidQuery();
await expect(router.route(query)).rejects.toThrow();
});
});
});- Unit Tests - Test individual functions/classes in isolation
- Integration Tests - Test interactions between components
- E2E Tests - Test full workflows from input to output
| Metric | Target | Current |
|---|---|---|
| Overall Coverage | 80% | ~60% |
| Critical Path Coverage | 95% | ~75% |
| New Code Coverage | 90% | Required |
- Test behavior, not implementation - Focus on what, not how
- Use descriptive test names - Should read like documentation
- Arrange-Act-Assert - Structure tests clearly
- Mock external dependencies - Use vi.mock for external services
- Test edge cases - Don't just test happy path
- Keep tests fast - Use unit tests for speed, E2E for verification
// ✅ Good: Tests behavior
it('returns cached result when available', async () => {
const result = await cache.get('key');
expect(result).toBeDefined();
});
// ❌ Bad: Tests implementation
it('calls cache._internalGet()', async () => {
const spy = vi.spyOn(cache, '_internalGet');
await cache.get('key');
expect(spy).toHaveBeenCalled();
});All public APIs must have JSDoc comments:
/**
* Calculates semantic similarity between two embeddings.
*
* @param embedding1 - First embedding vector (768-dimensional)
* @param embedding2 - Second embedding vector (768-dimensional)
* @returns Similarity score between 0 and 1, where 1 is identical
* @throws {ValidationError} If embeddings are not 768-dimensional
*
* @example
* ```typescript
* const similarity = calculateSimilarity(embeddingA, embeddingB);
* console.log(`Similarity: ${similarity.toFixed(2)}`);
* ```
*/
function calculateSimilarity(
embedding1: number[],
embedding2: number[]
): number {
// Implementation
}Each package should have a README.md with:
- Purpose - What does this package do?
- Installation - How to install
- Usage - Basic usage examples
- API - Main classes/functions
- Examples - More detailed examples
- Contributing - Link to main CONTRIBUTING.md
# @lsi/cascade
Cascade routing for cost-optimized AI queries.
## Installation
\`\`\`bash
npm install @lsi/cascade
\`\`\`
## Usage
\`\`\`typescript
import { CascadeRouter } from '@lsi/cascade';
const router = new CascadeRouter();
const decision = await router.route(query);
\`\`\`
## API
### CascadeRouter
Main router class.
#### Methods
- \`route(query)\` - Route a query
- \`setThreshold(threshold)\` - Set complexity threshold
## Examples
See \`examples/\` directory for complete examples.Generate API docs with:
npm run docs:generate
npm run docs:serveUse inline comments sparingly. Code should be self-documenting:
// ✅ Good: Self-documenting code
const userAge = calculateAge(user.birthDate);
// ❌ Bad: Unnecessary comment
// Calculate user's age from birth date
const age = calculateAge(user.birthDate);
// ✅ Good: Comment explains WHY
// Use exponential backoff to avoid overwhelming the server
const delay = Math.pow(2, attemptCount) * BASE_DELAY;We follow the Conventional Commits specification.
<type>(<scope>): <subject>
<body>
<footer>
| Type | Description | Example |
|---|---|---|
feat |
New feature | feat: add new routing algorithm |
fix |
Bug fix | fix: resolve race condition in cache |
docs |
Documentation | docs: update README with new examples |
style |
Formatting, missing semicolons | style: format code with prettier |
refactor |
Code refactoring | refactor: simplify cache implementation |
perf |
Performance improvement | perf: optimize vector similarity calculation |
test |
Adding or updating tests | test: add tests for CascadeRouter |
build |
Build system or dependencies | build: upgrade to TypeScript 5.3 |
ci |
CI/CD changes | ci: add GitHub Actions workflow |
chore |
Other changes | chore: update .gitignore |
Common scopes:
protocol- Protocol definitionscascade- Cascade routersuperinstance- SuperInstance platformprivacy- Privacy suiteswarm- CRDT and distributed statecli- Command-line interfacedocs- Documentationtests- Test infrastructure
# Simple commit
git commit -m "feat: add intent-based routing"
# With scope
git commit -m "feat(cascade): implement complexity scoring"
# With body
git commit -m "fix(router): resolve memory leak in cache
The cache was not properly evicting old entries, causing
memory to grow unbounded over time.
Fixes #123"- Use imperative mood - "add" not "added" or "adds"
- Keep subject line short - Max 50 characters
- Capitalize subject - "Add feature" not "add feature"
- Don't end with period - Subject line should not end with
. - Reference issues - Use
Fixes #123orCloses #456 - Explain WHAT and WHY - Not HOW
# ✅ Good
git commit -m "feat: add semantic caching for queries
This reduces API costs by caching similar queries with 80% hit rate."
# ❌ Bad
git commit -m "added caching feature"
git commit -m "fix bug"
git commit -m "update"- Update your branch with latest main
- Ensure all tests pass -
npm test - Run linter -
npm run lint - Format code -
npm run format - Update documentation - If API changes
- Go to GitHub and click "New Pull Request"
- Choose your branch
- Fill in the PR template
Follow conventional commit format:
feat: add new routing algorithm
fix: resolve race condition in cache
docs: update README with new examples
Use the PR template to describe:
- What does this PR do?
- Why is it needed?
- How does it work?
- Testing - How did you test?
- Breaking changes - Are there any?
Before requesting review, ensure:
- Tests pass locally (
npm test) - Linter passes (
npm run lint) - Code is formatted (
npm run format) - Documentation updated (if needed)
- Commit messages follow convention
- PR description is complete
- Linked to relevant issue (e.g., "Fixes #123")
- Automated checks must pass (CI, tests, linter)
- Code review by maintainers (minimum 1 approval)
- Address feedback - Make requested changes
- Approval - Maintainer approves
- Merge - Maintainer merges (squash and merge)
For reviewers:
- Be constructive - Focus on code, not person
- Explain reasoning - Help contributor learn
- Approve with changes - If minor issues exist
- Request changes - If major issues exist
- Be timely - Review within 48 hours
- All CI checks pass
- At least 1 maintainer approval
- No merge conflicts
- Documentation updated (if needed)
- Tests added/updated (if needed)
- Delete your branch
- Update local main
- Celebrate! You've contributed to Aequor!
Use the bug report template on GitHub:
**Description**
A clear description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '...'
3. Scroll down to '...'
4. See error
**Expected Behavior**
A clear description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Environment**
- OS: [e.g. Ubuntu 22.04]
- Node version: [e.g. 18.17.0]
- Package version: [e.g. 1.0.0]
**Additional Context**
Add any other context about the problem here.Use the feature request template:
**Problem Statement**
What problem does this feature solve? What are you trying to achieve?
**Proposed Solution**
How would you like this feature to work? Provide examples if possible.
**Alternatives**
Describe alternatives you've considered.
**Additional Context**
Add any other context or screenshots about the feature request here.- Search existing issues - Don't create duplicates
- Check if it's a question - Use Discussions for questions
- Include minimal repro - Help us reproduce the issue
- Provide environment info - OS, Node version, package version
By contributing to Aequor, you agree that your contributions will be licensed under the MIT License.
- ✅ Free to use in commercial and personal projects
- ✅ Free to modify and distribute
- ✅ No warranty or liability
- ✅ Keep copyright and license notice
Currently, we do NOT require a separate CLA. By contributing, you implicitly agree to the MIT license terms.
When adding new files, include:
/**
* @license MIT
*
* Copyright (c) 2025 Aequor Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction...
*/- Documentation -
/demo/docs/ - Project Guide -
CLAUDE.md - Architecture -
ARCHITECTURE_DECISIONS.md - Roadmap -
PROJECT_ROADMAP.md
- GitHub Issues - Bug reports and feature requests
- GitHub Discussions - Questions and ideas
- Pull Requests - Code contributions
For urgent issues, contact maintainers via GitHub @mentions in the issue or PR.
Thank you for taking the time to contribute to Aequor! Your contributions help make AI orchestration universal, sovereign, economic, and transparent.
Every contribution matters, whether it's:
- A bug fix
- A new feature
- Documentation improvement
- Test coverage
- Code review
- Answering questions
Together, we're building the "network router for AI" - invisible infrastructure that optimally routes every request while respecting privacy, budget, and hardware constraints.
Let's build the future of AI orchestration together!
Last Updated: 2026-01-02 Version: 1.0.0