Skip to content

Includes System

Reuse configurations across multiple projects through inheritance and composition.

Overview

Includes work through configuration inheritance:

  1. Define common rules once in a shared configuration
  2. Share rules, context, and skills across projects
  3. Mix and match includes to create project-specific configurations
  4. Track changes through version control

How Includes Work

Includes allow one .ai-rulez/ configuration to inherit content from other configurations. Use for:

  • Organization-wide coding standards
  • Framework-specific guidelines (React, Go, Python)
  • Consistent security policies
  • Team-specific workflows

Basic Example

Creating a Shared Configuration

Create a .ai-rulez/ directory that others can include:

shared-rules/.ai-rulez/config.toml:

version = "4.0"
name = "shared-rules"
description = "Organization-wide AI rules"

presets = []

[profiles]
default = []

shared-rules/.ai-rulez/rules/security.md:

---
priority: critical
---

# Security Standards

- Always validate user input
- Use parameterized queries
- Never hardcode secrets
- Rotate credentials regularly

Including in Your Project

In your project's .ai-rulez/config.toml, reference the shared rules:

version = "4.0"
name = "my-project"

# Include rules from another directory
includes = [
  { name = "shared-rules", source = "../shared-rules/.ai-rulez" }
]

presets = ["claude", "cursor"]

[profiles]
default = []

Now your project includes all content from the shared configuration.

Include Paths

Includes can be:

  1. Relative paths: ../shared-rules/.ai-rulez, ./team-guidelines/.ai-rulez
  2. Absolute paths: /etc/ai-rulez-standards/.ai-rulez
  3. Git URLs: https://github.com/org/shared-rules.git, git@github.com:org/shared-rules.git

Examples

Sibling directory:

[[includes]]
name = "shared-rules"
source = "../shared-rules"
include = ["rules", "context"]
merge_strategy = "local-override"

Subdirectory:

[[includes]]
name = "team-config"
source = "./config/shared"
include = ["rules", "skills"]
merge_strategy = "local-override"

Git repository (HTTPS):

[[includes]]
name = "org-standards"
source = "https://github.com/myorg/shared-rules.git"
ref = "main"
include = ["rules", "context", "skills", "agents"]
merge_strategy = "local-override"

Git repository (SSH):

[[includes]]
name = "company-policies"
source = "git@github.com:company/ai-rulez.git"
ref = "v1.2.3"
include = ["rules", "context"]
merge_strategy = "local-override"

Multiple includes:

[[includes]]
name = "team-guidelines"
source = "../team-guidelines"
include = ["rules", "context"]
merge_strategy = "local-override"

[[includes]]
name = "org-standards"
source = "git@gitlab.com:org/standards.git"
ref = "main"
include = ["rules", "skills"]
merge_strategy = "local-override"

[[includes]]
name = "security-policies"
source = "./security-policies"
include = ["rules"]
merge_strategy = "local-override"

Supported Git URL Formats

  • HTTPS: https://github.com/owner/repo.git
  • SSH: git@github.com:owner/repo.git
  • SSH protocol: ssh://git@github.com/owner/repo.git
  • GitLab: https://gitlab.com/owner/repo.git, git@gitlab.com:owner/repo.git
  • Self-hosted GitLab: git@git.example.com:owner/repo.git, https://git.example.com/owner/repo.git

SSH Cloning for Private Repositories

For private repositories that require SSH authentication, ai-rulez automatically uses git clone when it detects SSH URLs (git@... or ssh://...). This leverages your existing SSH key configuration.

Benefits of SSH cloning:

  • Works with private repositories without needing access tokens
  • Uses your configured SSH keys and agent
  • Supports self-hosted Git servers (GitLab, Gitea, Gogs, etc.)
  • Ideal for local development and multi-repo setups

Example with SSH:

includes:
  - name: private-rules
    source: git@git.example.com:company/ai-rulez.git
    ref: main
    include:
      - rules
      - context
    merge_strategy: local-override

Requirements:

  • Git must be installed and available in your PATH
  • SSH keys must be configured for the git host
  • SSH agent should be running (for passphrase-protected keys)

Repository Structure Support

An include source does not have to wrap its content in a .ai-rulez/ folder. ai-rulez supports both a wrapped and a bare (flattened) layout and auto-detects which one a source uses.

  1. Wrapped structure: Content lives inside a .ai-rulez/ subdirectory
my-repo/
├── .ai-rulez/
│   ├── config.toml
│   ├── rules/
│   ├── context/
│   ├── skills/
│   └── agents/
└── other files...
  1. Bare / flattened structure (recommended for shared-module repos): the directory exposes rules/, context/, skills/, and agents/ directly — no .ai-rulez/ wrapper needed. This works at the repository root or at any sub-path:
my-repo/
└── modules/
    └── core/
        ├── rules/
        ├── context/
        ├── skills/
        └── agents/

Point an include at the sub-path with the path field:

[[includes]]
name = "core"
source = "https://github.com/org/shared-modules.git"
path = "modules/core"     # resolves modules/core/rules, modules/core/skills, ...
include = ["rules", "skills"]
merge_strategy = "local-override"

ai-rulez detects the layout automatically: it first looks for a .ai-rulez/ directory (at the source root or under path), and otherwise treats a directory that contains any of rules/, context/, skills/, or agents/ as a bare ai-rulez structure. The flat layout keeps shared modules — especially skill-first modules that ship mostly skills/<id>/SKILL.md — clean and free of boilerplate wrapping.

Private Repository Authentication (HTTPS)

When working with private Git repositories in includes, you can authenticate using an access token.

Set the AI_RULEZ_GIT_TOKEN environment variable with your access token:

export AI_RULEZ_GIT_TOKEN="ghp_your_github_token_here"
ai-rulez generate

This is the recommended approach for CI/CD environments and automation scripts.

Using CLI Flag

Pass the token directly via the --token flag:

ai-rulez generate --token "ghp_your_github_token_here"

Creating Access Tokens

GitHub:

  1. Go to Settings → Developer settings → Personal access tokens
  2. Click "Generate new token (classic)"
  3. Select scopes:
  4. repo - Required for accessing private repositories
  5. Generate and copy the token

GitLab:

  1. Go to User Settings → Access Tokens
  2. Click "Add new token"
  3. Select scopes:
  4. read_repository - Required for reading private repositories
  5. Create token and copy it

Other Git Hosts:

Most Git hosting platforms that support Bearer token authentication will work with ai-rulez. The token is sent as a Bearer token in the Authorization header when fetching repository archives.

Security Best Practices

  • Never commit tokens to your repository or configuration files
  • Use environment variables in CI/CD pipelines (GitHub Actions secrets, GitLab CI/CD variables, etc.)
  • Store tokens securely using secret management systems (AWS Secrets Manager, HashiCorp Vault, etc.)
  • Rotate tokens regularly to limit exposure from potential leaks
  • Use minimal permissions - only grant the token access to what's needed (read-only repository access)
  • Use organization-level tokens when possible to manage access centrally

Example: CI/CD Integration

GitHub Actions:

name: Generate AI Rules
on: [push]
jobs:
  generate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Generate
        env:
          AI_RULEZ_GIT_TOKEN: ${{ secrets.GIT_TOKEN }}
        run: npx ai-rulez@latest generate

GitLab CI:

generate:
  script:
    - export AI_RULEZ_GIT_TOKEN="$CI_JOB_TOKEN"
    - ai-rulez generate

Include Options

  • name: Unique identifier for the include
  • source: Path or Git URL to the configuration
  • path: (Optional) Sub-path within the source to resolve (e.g. modules/core). Supports the bare/flattened layout described above; defaults to the source root
  • ref: (Git only) Branch, tag, or commit SHA (default: main)
  • include: List of content types to fetch: rules, context, skills, agents
  • merge_strategy: How to handle conflicts:
  • local-override: Local content takes precedence (default)
  • remote-override: Remote content takes precedence

Include Priority

When the same file exists in multiple includes and your configuration:

  1. Your configuration takes precedence (highest priority)
  2. Includes are merged in order
  3. Later includes override earlier ones

Example:

includes:
  - ../base-rules/.ai-rulez # Loaded first
  - ../team-rules/.ai-rulez # Overrides base-rules
  # Your rules/ directory overrides both

If multiple includes define .ai-rulez/rules/security.md, the last one wins.

Common Patterns

Organization-Wide Standards

Create a central repository with baseline rules:

Repository structure:

org-standards/
└── .ai-rulez/
    ├── config.toml
    ├── rules/
    │   ├── security.md
    │   ├── code-quality.md
    │   └── git-workflow.md
    └── context/
        └── company-values.md

Each project includes it:

includes:
  - https://github.com/myorg/standards/.ai-rulez

Framework-Specific Rules

Create separate includes for each framework:

frameworks/
├── go-backend/
│   └── .ai-rulez/
│       ├── config.toml
│       └── rules/
│           ├── project-layout.md
│           ├── error-handling.md
│           └── testing.md
├── react-frontend/
│   └── .ai-rulez/
│       └── rules/
│           ├── component-guidelines.md
│           ├── hooks-patterns.md
│           └── styling.md
└── python-ml/
    └── .ai-rulez/
        └── rules/
            ├── numpy-conventions.md
            └── ml-best-practices.md

Your project uses them:

includes:
  - ../../frameworks/go-backend/.ai-rulez
  - ../../frameworks/react-frontend/.ai-rulez

presets:
  - claude
  - cursor

profiles:
  backend:
    - backend
  frontend:
    - frontend
  full:
    - backend
    - frontend

Monorepo with Shared and Team-Specific Rules

Repository structure:

monorepo/
├── shared-rules/.ai-rulez/     # Used by all teams
├── backend-team/
│   └── .ai-rulez/              # Includes shared + backend-specific
├── frontend-team/
│   └── .ai-rulez/              # Includes shared + frontend-specific
└── mobile-team/
    └── .ai-rulez/              # Includes shared + mobile-specific

backend-team/.ai-rulez/config.toml:

version = "4.0"
name = "backend-api"

includes = [
  { name = "shared-rules", source = "../shared-rules/.ai-rulez" }
]

presets = ["claude", "cursor"]

[profiles]
default = []

Multi-Level Hierarchy

Includes can themselves include other includes:

hierarchy:

org-base/
├── rules/
│   └── security.md
└── .ai-rulez/config.toml

go-framework/
└── .ai-rulez/config.toml
    includes:
      - ../org-base/.ai-rulez

my-project/
└── .ai-rulez/config.toml
    includes:
      - ../go-framework/.ai-rulez
      - ../team-standards/.ai-rulez

When you generate from my-project, it loads:

  1. org-base rules (base layer)
  2. go-framework rules (framework-specific)
  3. team-standards rules (team-specific)
  4. my-project rules (project-specific)

Collision Handling

When includes define the same file:

shared-rules/.ai-rulez/rules/testing.md
go-framework/.ai-rulez/rules/testing.md
my-project/.ai-rulez/rules/testing.md

Resolution order (last one wins):

  1. shared-rules/rules/testing.md (loaded first)
  2. go-framework/rules/testing.md (overrides shared)
  3. my-project/rules/testing.md (overrides both)

A warning is logged:

⚠️  Content collision: rules/testing.md found in multiple includes
    → Using: my-project/.ai-rulez/rules/testing.md

Best Practices

Organize by Specificity

org-wide-rules/           Applies to everything
team-rules/               Team-specific
framework-rules/          Technology-specific
project-rules/            Project-specific

Use Clear Naming

Good:

  • org-standards/.ai-rulez
  • react-best-practices/.ai-rulez
  • backend-security/.ai-rulez

Bad:

  • rules/.ai-rulez (ambiguous)
  • base/.ai-rulez (unclear scope)

Document Includes

Add comments to your config explaining why includes are needed:

version = "4.0"
name = "my-backend"

# Organization-wide coding standards
# Go-specific conventions
# Backend team standards
includes = [
  { name = "org-standards", source = "../org-standards/.ai-rulez" },
  { name = "go-guidelines", source = "../go-guidelines/.ai-rulez" },
  { name = "backend-team", source = "../backend-team/.ai-rulez" }
]

presets = ["claude", "cursor"]

Keep Includes Focused

Each include should have a single purpose:

Good:
security-policies/       Rules for security
error-handling/          Rules for error handling
code-style/              Rules for code style

Bad:
everything/              Security, errors, style, testing, etc.

Version Your Includes

Tag releases and reference specific versions:

git tag v1.0.0 org-standards/

includes:
  - https://github.com/org/standards/.ai-rulez@v1.0.0

Troubleshooting

Include Path Not Found

ls -la ../shared-rules/.ai-rulez/config.toml

# Try absolute path
includes:
  - /path/to/shared-rules/.ai-rulez

Circular Includes

If a includes b, and b includes a:

# Error: Circular include detected
#   a -> b -> a

# Solution: Restructure to avoid cycles
# Create a base layer that both include from

Conflicting Rules

Use project-level rules to override, or change include order:

includes:
  - ../stricter-rules/.ai-rulez # Load strict rules first
  - ../lenient-rules/.ai-rulez # Load lenient rules last (wins)

Your .ai-rulez/rules/security.md overrides both includes.

Content Not Merging

cat .ai-rulez/config.toml | grep includes
ls -la ../shared-rules/.ai-rulez/
ai-rulez validate --verbose

Migration Path

If you're currently using separate configurations:

  1. Extract common rules into a shared include:
mkdir -p ../shared-rules/.ai-rulez/rules
# Move common rules there
  1. Add include to your config:
includes:
  - ../shared-rules/.ai-rulez
  1. Regenerate and test:
ai-rulez validate
ai-rulez generate
  1. Commit the include:
git add ../shared-rules/
git commit -m "chore: extract shared rules"

Next Steps