Skip to content

Developer Guide

Complete workflow for contributing to Nova AI from issue discovery to PR merge.

Table of Contents


Getting Started

Prerequisites

  • Python 3.11+
  • Git
  • Claude Code CLI
  • GitHub account

Initial Setup

# 1. Fork the repository
gh repo fork Jaureguy760/nova_ai --clone

# 2. Install dependencies
cd nova_ai
pip install -e ".[dev]"

# 3. Verify installation
pytest tests/ -v
ruff check src/

# 4. Set up pre-commit hooks
pre-commit install

Environment Configuration

# Copy example env file
cp .env.example .env

# Edit .env with your credentials
# Required:
ANTHROPIC_API_KEY=your-key-here

# Optional (for MCP servers):
GITHUB_TOKEN=your-token
LANGFUSE_PUBLIC_KEY=your-key
LANGFUSE_SECRET_KEY=your-secret

Development Workflow

1. Find or Create an Issue

Browse Issues:

# View all open issues
gh issue list

# View issues by label
gh issue list --label "good first issue"
gh issue list --label "bug"
gh issue list --label "feature"

Create New Issue:

# Use issue templates
gh issue create --template bug_report.yml
gh issue create --template feature_request.yml
gh issue create --template agent_enhancement.yml

2. Create Feature Branch

# Branch naming convention:
# - feat/description - New features
# - fix/description - Bug fixes
# - docs/description - Documentation
# - refactor/description - Code refactoring
# - test/description - Test additions

git checkout main
git pull origin main
git checkout -b feat/user-authentication

3. Implement Changes

Use Nova AI slash commands to assist:

# Planning
/novaai plan implementation for user authentication

# Implementation
/novaai implement user authentication with JWT

# Testing
/novaai create tests for authentication module

# Review
/novaai review my changes for security issues

Manual Implementation:

# 1. Create new files in appropriate location
# src/auth/authentication.py

# 2. Write code following standards
# See docs/coding-style.md

# 3. Add docstrings (Google style)
def authenticate_user(username: str, password: str) -> User:
    """Authenticate user with credentials.

    Args:
        username: User's username
        password: User's password

    Returns:
        User object if authentication successful

    Raises:
        AuthenticationError: If credentials invalid
    """
    ...

# 4. Add type hints
# All functions must have parameter and return types

4. Write Tests

Test Structure:

tests/
├── unit/           # Unit tests (fast, isolated)
├── integration/    # Integration tests (slower, dependencies)
├── performance/    # Performance benchmarks
└── security/       # Security tests

Example Test:

# tests/unit/test_authentication.py
import pytest
from src.auth.authentication import authenticate_user
from src.auth.exceptions import AuthenticationError

def test_authenticate_valid_user():
    """Test authentication with valid credentials."""
    user = authenticate_user("admin", "password123")
    assert user.username == "admin"
    assert user.is_authenticated

def test_authenticate_invalid_password():
    """Test authentication fails with invalid password."""
    with pytest.raises(AuthenticationError):
        authenticate_user("admin", "wrong-password")

@pytest.mark.asyncio
async def test_authenticate_async():
    """Test async authentication."""
    user = await authenticate_user_async("admin", "password123")
    assert user is not None

Run Tests:

# Run all tests
pytest tests/ -v

# Run specific test file
pytest tests/unit/test_authentication.py -v

# Run with coverage
pytest tests/ --cov=src --cov-report=html

# Run only fast tests
pytest tests/ -m "not slow"

5. Code Quality Checks

Before Committing:

# Lint with ruff
ruff check src/ tests/

# Auto-fix issues
ruff check --fix src/ tests/

# Format code
ruff format src/ tests/

# Type checking
mypy src/

# Security scan
bandit -r src/

Pre-commit Hooks:

Automatically runs on git commit: - Trailing whitespace removal - End of file fixes - YAML/JSON validation - Large file detection - Private key detection - Ruff linting

6. Commit Changes

Conventional Commits Format:

# Feature
git commit -m "feat: add JWT authentication

- Implement token generation
- Add token validation
- Add refresh token support"

# Bug fix
git commit -m "fix: resolve authentication timeout

- Increase timeout to 30s
- Add retry logic for transient errors"

# Documentation
git commit -m "docs: add authentication guide

- Add usage examples
- Document configuration options"

# Refactor
git commit -m "refactor: simplify authentication flow

- Extract token validation to separate function
- Reduce cyclomatic complexity from 15 to 8"

# Tests
git commit -m "test: add authentication edge cases

- Test expired tokens
- Test malformed tokens
- Test concurrent authentication"

Commit Message Guidelines: - Type: feat, fix, docs, refactor, test, chore - Scope (optional): area affected (auth, kb, mcp) - Subject: imperative mood, lowercase, no period - Body (optional): detailed explanation - Footer (optional): breaking changes, issue references

7. Push and Create PR

# Push branch
git push -u origin feat/user-authentication

# Create PR
gh pr create \
  --title "feat: Add JWT authentication" \
  --body "$(cat <<EOF
## Summary
Implements JWT-based authentication for API endpoints.

## Changes
- Add JWT token generation
- Add token validation middleware
- Add refresh token support
- Add authentication tests

## Testing
- [x] Unit tests pass (98% coverage)
- [x] Integration tests pass
- [x] Manual testing completed
- [x] Security scan clean

## Breaking Changes
None

## Related Issues
Closes #123
EOF
)"

Code Standards

Python Style

  • Formatter: ruff (auto-format on save)
  • Linter: ruff + mypy
  • Line Length: 100 characters
  • Docstrings: Google style
  • Type Hints: Required for all public functions

Example:

from __future__ import annotations

from typing import Protocol

class AuthProvider(Protocol):
    """Protocol for authentication providers."""

    def authenticate(self, username: str, password: str) -> User:
        """Authenticate user with credentials."""
        ...

def authenticate_user(
    username: str,
    password: str,
    provider: AuthProvider,
    *,
    timeout: int = 30,
) -> User:
    """Authenticate user with given provider.

    Args:
        username: User's username
        password: User's password
        provider: Authentication provider implementation
        timeout: Timeout in seconds (default: 30)

    Returns:
        Authenticated user object

    Raises:
        AuthenticationError: If authentication fails
        TimeoutError: If authentication times out

    Examples:
        >>> user = authenticate_user("admin", "pass", JWTProvider())
        >>> print(user.username)
        admin
    """
    try:
        return provider.authenticate(username, password)
    except Exception as e:
        raise AuthenticationError(f"Authentication failed: {e}") from e

Agent Development

When creating new agents:

---
name: my-agent
description: Brief description of agent purpose
tools:
  - Read
  - Write
  - Edit
  - Grep
  - Glob
  - Bash
model: sonnet
---

# Agent Instructions

Clear, concise instructions for the agent...

Guidelines: - Keep agents focused (single responsibility) - Minimal tool set (only what's needed) - Use Sonnet 4.5 (Anthropic recommendation) - Document expected inputs/outputs

Skills Development

---
name: my-skill
description: Brief skill description
allowed-tools: Read, Write, Grep, Glob, Bash
---

# Skill Documentation

Progressive disclosure:
1. YAML metadata (always loaded)
2. SKILL.md (loaded when triggered)
3. Referenced files (loaded on-demand)

Keep SKILL.md under 500 lines.

Testing Requirements

Coverage Targets

Component Min Coverage Target
Core Orchestrator 85% 90%
MCP Servers 80% 85%
KB Store 80% 85%
Utils 75% 80%
Overall 80% 85%

Test Categories

Unit Tests (Fast):

# Isolated, no external dependencies
# Run on every commit
pytest tests/unit/ -v

Integration Tests:

# Test component interactions
# May use mocks for external services
pytest tests/integration/ -v

Performance Tests:

# Benchmark critical paths
# Run before releases
pytest tests/performance/ -v

Security Tests:

# Test security controls
# Run on security-critical changes
pytest tests/security/ -v


Review Process

Self-Review Checklist

Before requesting review:

  • All tests pass locally
  • Code follows style guide
  • New code has tests (80%+ coverage)
  • Docstrings added for public APIs
  • Type hints added
  • Security considerations addressed
  • Performance impact assessed
  • Breaking changes documented

Code Review

Reviewers check for: 1. Security: Vulnerabilities, injection risks, secrets in code 2. Correctness: Logic errors, edge cases, error handling 3. Performance: Inefficient algorithms, memory leaks 4. Maintainability: Code clarity, documentation, tests 5. Standards: Style compliance, best practices

Responding to Reviews:

# Address feedback
git add -A
git commit -m "fix: address review feedback

- Add input validation
- Improve error messages
- Add missing tests"

git push

Approval Criteria: - ✅ 1+ approval from maintainer - ✅ All conversations resolved - ✅ CI checks passing - ✅ No merge conflicts


Deployment

Pre-Merge

# Final checks
pytest tests/ -v
ruff check src/ tests/
mypy src/
bandit -r src/

Merge

# Squash and merge (preferred)
gh pr merge --squash

# Standard merge (for multiple logical commits)
gh pr merge --merge

# Rebase (for clean history)
gh pr merge --rebase

Post-Merge

# Update local main
git checkout main
git pull origin main

# Delete feature branch
git branch -d feat/user-authentication
gh repo view --web  # View merged PR

Release Process

Handled by maintainers:

  1. Create release tag with version number
  2. Publish release notes (auto-generated by Release Drafter)

Common Tasks

Adding a New Agent

# 1. Create agent file
touch .claude/agents/my-agent.md

# 2. Add YAML frontmatter + instructions
# See existing agents for examples

# 3. Test agent
/novaai test my-agent agent

# 4. Add agent tests
touch tests/agents/test_my_agent.py

# 5. Update agent README
# docs/agents/README.md

Adding a New MCP Server

# 1. Create server file
touch mcp/servers/my_server.py

# 2. Implement using FastMCP
# See existing servers for examples

# 3. Create SDK MCP wrapper
touch src/orchestrator/tools/sdk_mcp_my_server.py

# 4. Integrate with ClaudeSDKExecutor
# Add to src/orchestrator/claude_sdk_executor.py

# 5. Add server tests
touch tests/unit/test_sdk_mcp_my_server.py

# Note: Nova AI uses SDK MCP only (no stdio servers)

Adding a New Skill

# 1. Create skill directory
mkdir -p .claude/skills/category/skill-name

# 2. Create SKILL.md
touch .claude/skills/category/skill-name/SKILL.md

# 3. Add YAML frontmatter + content
# Keep under 500 lines

# 4. Test skill
/novaai test skill-name skill

# 5. Update skills README
# .claude/skills/README.md

Getting Help

Resources

Support Channels

  • GitHub Issues: Bug reports, feature requests
  • GitHub Discussions: Questions, ideas, showcase
  • PR Comments: Code-specific questions

FAQ

Q: How do I run tests for a specific module?

pytest tests/orchestrator/ -v

Q: How do I update dependencies?

# Update pyproject.toml
# Run: pip install --upgrade package-name
# Update requirements.txt: pip-compile pyproject.toml

Q: How do I add a new dependency?

# 1. Add to pyproject.toml [project.dependencies]
# 2. Run: pip install -e ".[dev]"
# 3. Run: pip-compile pyproject.toml --output-file requirements.txt
# 4. Commit both files

Q: Tests are failing locally but pass in CI?

# Clear pytest cache
pytest --cache-clear

# Reinstall dependencies
pip install -e ".[dev]" --force-reinstall


Contribution Tips

Best Practices

  1. Start Small: Pick "good first issue" labels
  2. Ask Questions: Comment on issues before starting
  3. Incremental PRs: Small, focused changes review faster
  4. Tests First: Write tests before implementation (TDD)
  5. Document As You Go: Don't leave docs for last

Common Pitfalls

Don't: - Commit secrets or credentials - Push directly to main - Create massive PRs (>500 lines) - Skip tests - Ignore review feedback

Do: - Use feature branches - Write descriptive commit messages - Add tests for new code - Update documentation - Respond promptly to reviews


Maintainer Workflow

(For maintainers only)

Reviewing PRs

# Checkout PR locally
gh pr checkout 123

# Review changes
git diff main

# Test locally
pytest tests/ -v

# Approve or request changes
gh pr review 123 --approve
gh pr review 123 --request-changes --body "Comments here"

# Merge after approval
gh pr merge 123 --squash

Release Process

# 1. Create and push release tag
git tag v2.4.0
git push origin v2.4.0

# 2. Publish release (auto-generated by Release Drafter)
gh release view v2.4.0 --web

Last Updated: November 7, 2025 Version: 2.3.0