Imported from bruin-data/bruin (
AGENTS.md). Install upstream withnpx skills add bruin-data/bruin. Copyright stays with the author.
AGENTS.md/CLAUDE.md - AI Agent Contribution Guide
This document gives AI agents the project-specific operating guidance needed to work safely in Bruin.
Before You Finish: Checks
You MUST run these commands before completing any task that modifies application code:
- Format the code: Run
make formatin the project root. Checkgit diffafterward — if there are formatting changes, stage and include them in your work. - Run the tests: Run
make testin the project root. If any tests fail, fix the issues before finishing.
Do not consider an application-code task complete until both checks pass. Use the /format-fix and /test commands if needed.
For changes that only touch non-application files, such as documentation, GitHub Actions workflows, agent instructions, repository metadata, or other configuration that does not affect the Bruin binary/runtime behavior, do not run the full make format / make test suite by default. Instead, run the smallest relevant validation available for the changed files, such as YAML syntax checks, Markdown checks, workflow review, or git diff inspection, and clearly report what was and was not run.
Table of Contents
- Project Overview
- Architecture & Core Concepts
- Development Environment
- Build System
- CLI Source of Truth
- Codebase Organization
- Testing Strategy
- Contributing Guidelines
- Common Development Tasks
Project Overview
Bruin is a CLI-first data framework for ingestion, SQL/Python/R transformations, data quality, materialization, lineage, and pipeline execution across many data platforms.
Most behavior is configured in version-controlled text files: pipeline.yml, asset files, templates, docs, and connection/config files. When changing behavior, prefer existing package patterns and keep docs/tests aligned with user-visible changes.
Core Features
- Data Ingestion: Using
ingestrand Python scripts - Transformations: SQL, Python, and R on multiple platforms
- Data Quality: Built-in quality checks and validations
- Materializations: Table/view materializations and incremental tables
- Python Isolation: Isolated Python environments via
uv - Templating: Jinja templating for reusable code
- Lineage: Dependency visualization and tracking
- Multi-platform Execution: Runs locally, on EC2, or GitHub Actions
- Secrets Management: Environment variable injection
- VS Code Extension: Enhanced developer experience
Architecture & Core Concepts
Assets
Anything that carries value derived from data:
- Tables/views in databases
- Files in S3/GCS
- Machine learning models
- Documents (Excel, Google Sheets, Notion, etc.)
Assets consist of:
- Definition: Metadata enabling Bruin to understand the asset
- Content: The actual query/logic that creates the asset
Pipelines
Groups of assets executed together in dependency order. Structure:
my-pipeline/
├─ pipeline.yml
└─ assets/
├─ asset1.sql
└─ asset2.py
Pipeline Runs
Execution instances containing one or more asset instances with specific configuration and timing.
Development Environment
Prerequisites
- Go: Use the version declared in
go.mod - Python: For Python asset development and formatting
- CGO: Required for DuckDB support
- Git: For version control and repository detection
Dependencies
The project uses extensive Go dependencies including:
- CLI framework:
urfave/cli - Database drivers: BigQuery, Snowflake, PostgreSQL, MySQL, DuckDB, etc.
- Cloud SDKs: AWS, GCP
- Templating: Jinja via Gonja
- Testing: Testify
Build System
The Makefile provides comprehensive build and development targets:
Core Targets
Build Targets
make build # Build with DuckDB support (CGO_ENABLED=1)
make build-no-duckdb # Build without DuckDB (CGO_ENABLED=0)
Development Targets
make deps # Install dependencies and tools
make clean # Remove build artifacts
make format # Format Go/Python and run fast changed-package lint
make lint # Run fast lint on changed packages in every Go module
make lint-full # Run all Go linters across the primary Go modules
make tools-update # Update development tools
Testing Targets
make test # Run fast unit tests
make test-full # Run unit tests with race detection
make test-unit # Run unit tests specifically
make integration-test # Full integration tests with ingestr
make integration-test-light # Light integration tests without ingestr
make integration-test-cloud # Cloud-specific integration tests
Development Utilities
make lint-python # Format and lint Python code
make refresh-integration-expectations # Update integration test expectations
Build Configuration
- Build metadata: The Makefile injects build metadata via linker flags
- Telemetry: Controlled via
TELEMETRY_KEYandTELEMETRY_OPTOUTenvironment variables - Tags: Uses
no_duckdb_arrowfor standard builds,bruin_no_duckdbfor no-DuckDB builds
CLI Source of Truth
Do not treat this guide as a current command inventory. If a task depends on commands, flags, hidden subcommands, or runtime help text, verify against the source of truth:
- Check
main.gofor top-level command registration. - Check
cmd/*.goandcmd/mcp/*.gofor command definitions, flags, and action wiring. - After
make build, use./bin/bruin --helpand./bin/bruin <command> --helpto confirm runtime behavior. - Check
docs/commands/when changing user-facing command behavior, and update docs when behavior changes.
When adding or changing a command, update the command implementation, tests, and user-facing docs together.
Codebase Organization
Package Structure (pkg/)
The codebase is organized into focused packages:
Core Packages
pipeline/: Pipeline parsing, execution, and managementconfig/: Configuration file handling (.bruin.yml)connection/: Database connection managementexecutor/: Asset execution enginelineage/: Dependency tracking and visualizationquery/: Query execution and management
Data Platform Packages
Each supported platform has its own package:
- Database platforms:
bigquery/,snowflake/,postgres/,mysql/,duckdb/,clickhouse/,athena/,mssql/,databricks/,oracle/,sqlite/,trino/,synapse/,hana/,spanner/ - Cloud storage:
s3/,gcs/ - Ingestion sources: 50+ packages for different data sources (e.g.,
shopify/,hubspot/,salesforce/,stripe/, etc.)
Utility Packages
jinja/: Template processingpython/: Python asset executionlint/: Code linting and validationdiff/: Data comparison functionalitypath/: File system utilitiesgit/: Git repository operationstelemetry/: Usage analyticssecrets/: Secret managementlogger/: Logging utilities
Command Implementation (cmd/)
Each CLI command is implemented in its own file:
- Command structure definition
- Flag parsing and validation
- Business logic delegation to appropriate packages
- Error handling and output formatting
Testing Strategy
Test Types
Unit Tests
- Location: Throughout
pkg/packages with*_test.gofiles - Execution:
make test-unit - Coverage: Fast local tests by default;
make test-fulladds race detection - Scope: Excludes cloud integration tests
Use narrow test loops while developing, then run the required full checks before finishing:
# Target one package or test while iterating
go test -tags="no_duckdb_arrow" ./pkg/foo -run TestName
go test -tags="no_duckdb_arrow" ./cmd/... ./pkg/...
# Required final unit-test command for application-code changes
make test
Integration Tests
- Light Integration:
make integration-test-light(excludes ingestr) - Full Integration:
make integration-test(includes ingestr) - Cloud Integration:
make integration-test-cloud(cloud platforms)
Use make integration-test-light for changes that affect parsing, command workflows, local pipeline execution, or integration-test fixtures. Use full integration tests when touching ingestr behavior. Cloud integration tests require local cloud credentials/config and may skip tests when matching connections are absent.
Test Data
- Location:
integration-tests/test-pipelines/ - Coverage: Parse tests, lineage tests, execution tests
- Expectations: JSON files with expected outputs
- Refresh:
make refresh-integration-expectationsupdates expectations
Test Patterns
- Mock databases with existing SQL mock helpers
- Mock PostgreSQL with existing pgx mock patterns
- Use existing concurrency helpers for parallel work
- Use the existing file system abstraction patterns in packages that already use them
Contributing Guidelines
Code Style & Formatting
Go Code
Tools automatically installed and run via make format:
gci: Import organizationgofumpt: Stricter Go formattinggolangci-lint: Fast changed-package linting;make lint-fullruns the comprehensive suitegovet: Enabled throughgolangci-lint
Python Code
Tools run via make lint-python:
ruff format: Code formattingruff check --fix: Linting with auto-fixes
Secrets, Credentials, and Generated Files
- Do not commit local credentials, tokens, keys, or personal environment files.
- Treat
.bruin.yml,.bruin.cloud.yml, cloud integration configs, and local connection files as sensitive unless they are clearly committed examples. - If a task requires cloud integration config, use local untracked files and document what was needed.
make refresh-integration-expectationsrewrites JSON expectations. Inspect the diff carefully and include only intentional expectation changes.- Do not commit build outputs, virtual environments, local caches, logs, or generated binaries unless the repository already tracks that exact artifact and the change is intentional.
Development Workflow
- Setup:
make depsto install tools and dependencies - Development: Edit code with VS Code extension for enhanced experience
- Formatting:
make formatbefore committing - Testing:
make testfor unit tests, integration tests as appropriate - Building:
make buildto verify compilation
Adding New Data Platforms
- Create package:
pkg/newplatform/ - Implement interfaces: Connection, query execution, schema introspection
- Add CLI command: Register in main command list
- Add tests: Unit and integration tests
- Update documentation: Add to supported platforms list
Adding New CLI Commands
- Create command file:
cmd/newcommand.go - Implement command structure: Using
cli.Commandpattern - Add business logic: In appropriate
pkg/package - Register command: In
main.gocommands slice - Add tests: Command and business logic tests
Common Development Tasks
Running Locally
# Basic build and run
make build
./bin/bruin --help
# Development mode with debug
make build
./bin/bruin --debug [command]
Adding New Asset Types
- Define asset type in
pkg/pipeline/asset.go - Implement execution logic in
pkg/executor/ - Add parsing logic if needed
- Update lineage detection if applicable
- Add tests and integration tests
Debugging Integration Tests
# Run specific test pipeline
(cd integration-tests && ../bin/bruin run test-pipelines/your-test)
# Refresh expectations after changes from the repository root
make refresh-integration-expectations
Working with Templates
# Test template rendering
./bin/bruin render path/to/template.sql
# Test complete pipeline parsing
./bin/bruin internal parse-pipeline path/to/pipeline
# Regenerate the docs pages that mirror a template README
make sync-template-docs
Most templates have a docs page under docs/getting-started/templates-docs/ that
is written by hand and diverges from the template's own README. For the templates
listed in SYNCED in scripts/sync_template_docs.py, the docs page is instead
generated from the README: edit templates/<name>/README.md, run
make sync-template-docs, and commit both. Those pages open with a
<!-- Generated from … --> comment; make test fails if one has drifted.
Database Connection Testing
# List connections
./bin/bruin connections list
# Test connection
./bin/bruin connections test --name connection-name
# Add new connection
./bin/bruin connections add
This guide provides the foundational knowledge needed to contribute effectively to the Bruin project. For specific implementation details, refer to the extensive documentation in the docs/ directory and examine existing patterns in the codebase.