DEV Community

Cover image for Managing goose Configurations Across Multiple Projects
Lymah
Lymah

Posted on

Managing goose Configurations Across Multiple Projects

As development teams scale their use of goose across multiple projects, a new challenge emerges: how do you maintain consistent configurations while adapting to each project's unique needs? In my previous post on team environments, we explored shared workflows within a single project. Now, let's tackle the multi-project configuration challenge.

The Multi-Project Configuration Problem

When working with goose across multiple projects, teams often face:

  • Configuration drift between projects leading to inconsistent behavior
  • Duplicated configuration that becomes painful to maintain
  • Context switching overhead when moving between projects
  • Onboarding friction as team members learn different configurations for each project

The goal is to establish a scalable configuration strategy that maintains consistency where needed while allowing project-specific customization.

Configuration Hierarchy Strategy

The most effective approach uses a three-tier configuration hierarchy:

1. Global Base Configuration

Create a shared base configuration that defines organization-wide standards:

# ~/.config/goose/profiles.yaml (global)
default:
  provider: openai
  processor: gpt-4
  accelerator: gpt-4
  moderator: truncate

organization-standards:
  provider: openai
  processor: gpt-4
  accelerator: gpt-4
  moderator: truncate
  toolkits:
    - name: developer
    - name: github
      requires:
        GITHUB_TOKEN: github-token
Enter fullscreen mode Exit fullscreen mode

This global configuration serves as your baseline, ensuring all projects start with consistent standards.

2. Project-Specific Configuration

Each project maintains its own .goose/profiles.yaml that extends or overrides the base:

# project-a/.goose/profiles.yaml
default:
  provider: openai
  processor: gpt-4
  accelerator: gpt-4
  moderator: truncate
  toolkits:
    - name: developer
    - name: github
      requires:
        GITHUB_TOKEN: github-token
    - name: repo_context
      requires:
        path: .

backend-dev:
  extends: default
  toolkits:
    - name: docker
    - name: database
Enter fullscreen mode Exit fullscreen mode

3. Personal Overrides

Individual developers can customize further with local overrides:

# project-a/.goose/profiles.local.yaml (gitignored)
default:
  provider: anthropic  # Personal preference
  processor: claude-sonnet-4.5
Enter fullscreen mode Exit fullscreen mode
## Practical Implementation Strategies

### Strategy 1: Configuration Templates Repository

Create a dedicated repository for configuration templates:
goose-configs/
├── README.md
├── templates/
│   ├── base/
│   │   └── profiles.yaml
│   ├── web-app/
│   │   └── profiles.yaml
│   ├── api-service/
│   │   └── profiles.yaml
│   └── data-pipeline/
│       └── profiles.yaml
└── scripts/
    ├── init-project.sh
    └── sync-config.sh
Enter fullscreen mode Exit fullscreen mode

init-project.sh example:

#!/bin/bash
# Initialize goose config for a new project

PROJECT_TYPE=$1
TEMPLATE_PATH="templates/${PROJECT_TYPE}/profiles.yaml"

if [ ! -f "$TEMPLATE_PATH" ]; then
    echo "Unknown project type: $PROJECT_TYPE"
    echo "Available types: base, web-app, api-service, data-pipeline"
    exit 1
fi

mkdir -p .goose
cp "$TEMPLATE_PATH" .goose/profiles.yaml

echo "✓ goose configuration initialized for $PROJECT_TYPE"
echo "Next steps:"
echo "1. Review .goose/profiles.yaml"
echo "2. Add .goose/profiles.local.yaml to .gitignore"
echo "3. Commit .goose/profiles.yaml to version control"
Enter fullscreen mode Exit fullscreen mode

Strategy 2: Configuration as Code with Validation

Implement configuration validation to catch issues early:

# .goose/profiles.yaml with schema validation
default:
  provider: openai
  processor: gpt-4
  accelerator: gpt-4
  moderator: truncate

  # Validation metadata
  _metadata:
    schema_version: "1.0"
    required_env_vars:
      - OPENAI_API_KEY
      - GITHUB_TOKEN
    team: "platform-team"
    last_updated: "2025-10-30"
Enter fullscreen mode Exit fullscreen mode

Create a validation script:

# scripts/validate-goose-config.py
import yaml
import os
import sys

def validate_config(config_path):
    """Validate Goose configuration file"""
    errors = []

    with open(config_path) as f:
        config = yaml.safe_load(f)

    # Check required environment variables
    metadata = config.get('default', {}).get('_metadata', {})
    required_vars = metadata.get('required_env_vars', [])

    for var in required_vars:
        if not os.getenv(var):
            errors.append(f"Missing required environment variable: {var}")

    # Validate profile structure
    for profile_name, profile in config.items():
        if profile_name.startswith('_'):
            continue

        if 'provider' not in profile:
            errors.append(f"Profile '{profile_name}' missing required 'provider' field")

    return errors

if __name__ == '__main__':
    errors = validate_config('.goose/profiles.yaml')
    if errors:
        print("❌ Configuration validation failed:")
        for error in errors:
            print(f"  - {error}")
        sys.exit(1)
    else:
        print("✓ Configuration valid")
Enter fullscreen mode Exit fullscreen mode

Strategy 3: Environment-Specific Profiles

Structure profiles to handle different environments:

# .goose/profiles.yaml
default:
  provider: openai
  processor: gpt-4
  accelerator: gpt-4
  moderator: truncate
  toolkits:
    - name: developer

development:
  extends: default
  toolkits:
    - name: developer
    - name: github
    - name: docker
      requires:
        DOCKER_HOST: "unix:///var/run/docker.sock"

staging:
  extends: default
  toolkits:
    - name: developer
    - name: github
    - name: kubernetes
      requires:
        KUBE_CONFIG: staging-config

production:
  extends: default
  toolkits:
    - name: developer
    - name: github  
    - name: kubernetes
      requires:
        KUBE_CONFIG: production-config
  # More restrictive settings for production
  moderator: conservative
Enter fullscreen mode Exit fullscreen mode

Syncing Configurations Across Projects

Automated Sync Script

#!/bin/bash
# scripts/sync-goose-configs.sh
# Sync base configuration across all projects

CONFIG_REPO="git@github.com:your-org/goose-configs.git"
TEMP_DIR=$(mktemp -d)

# Clone config repository
git clone "$CONFIG_REPO" "$TEMP_DIR"

# Find all projects with goose configs
find ~/projects -name ".goose" -type d | while read goose_dir; do
    project_dir=$(dirname "$goose_dir")
    project_name=$(basename "$project_dir")

    echo "Syncing config for $project_name..."

    # Backup existing config
    cp "$goose_dir/profiles.yaml" "$goose_dir/profiles.yaml.bak"

    # Merge base config with project-specific settings
    python3 "$TEMP_DIR/scripts/merge-configs.py" \
        "$TEMP_DIR/templates/base/profiles.yaml" \
        "$goose_dir/profiles.yaml" \
        > "$goose_dir/profiles.yaml.new"

    # Replace if merge successful
    if [ $? -eq 0 ]; then
        mv "$goose_dir/profiles.yaml.new" "$goose_dir/profiles.yaml"
        echo "✓ Updated $project_name"
    else
        echo "✗ Failed to update $project_name"
        rm "$goose_dir/profiles.yaml.new"
    fi
done

# Cleanup
rm -rf "$TEMP_DIR"
Enter fullscreen mode Exit fullscreen mode

Best Practices for Multi-Project Management

1. Document Your Configuration Strategy

Create a clear README in your configuration repository:

# goose Configuration Standards

## Configuration Hierarchy

1. **Global base** (~/.config/goose/profiles.yaml)
2. **Project-specific** (.goose/profiles.yaml) - Committed to git
3. **Personal overrides** (.goose/profiles.local.yaml) - Gitignored

## Project Types and Templates

- **web-app**: Frontend applications (React, Vue, Angular)
- **api-service**: Backend APIs and microservices
- **data-pipeline**: ETL and data processing projects
- **infrastructure**: Terraform, Kubernetes configurations

## Adding a New Project

`./scripts/init-project.sh <project-type>`


## Updating Configurations

Run monthly to sync base configurations:

`./scripts/sync-goose-configs.sh`
Enter fullscreen mode Exit fullscreen mode

2. Version Control Strategy

DO commit to git:

.goose/profiles.yaml (project configuration)
.goose/toolkit-configs/ (shared toolkit settings)
Documentation about configuration choices

DO NOT commit to git:

.goose/profiles.local.yaml (personal overrides)
.goose/sessions/ (session history)
API keys or secrets

Add to .gitignore:

# Goose personal configurations and sessions
.goose/profiles.local.yaml
.goose/sessions/
.goose/**/*.log
Enter fullscreen mode Exit fullscreen mode

3. Toolkit Management Across Projects

Standardize commonly used toolkits:

# Standard toolkit configurations
default:
  toolkits:
    # Core toolkits - always included
    - name: developer

    # Version control - most projects
    - name: github
      requires:
        GITHUB_TOKEN: github-token

    # Project-specific toolkits added per project
    # Examples: docker, kubernetes, database, etc.
Enter fullscreen mode Exit fullscreen mode

4. Environment Variable Management

Use a consistent approach for environment variables across projects:
Option A: .env files (per project)

# .env.goose (gitignored)
GOOSE_PROVIDER=openai
OPENAI_API_KEY=sk-...
GITHUB_TOKEN=ghp_...
Enter fullscreen mode Exit fullscreen mode

Option B: Shared secrets manager

# Use tools like 1Password, AWS Secrets Manager, or HashiCorp Vault
export OPENAI_API_KEY=$(op read "op://Development/Goose/OPENAI_API_KEY")
Enter fullscreen mode Exit fullscreen mode

5. Testing Configuration Changes

Before rolling out configuration changes, test in a sandbox:

# Test configuration in a sandbox project
mkdir -p /tmp/goose-config-test
cd /tmp/goose-config-test
cp -r ~/goose-configs/templates/base/.goose .
goose session start --profile default

# Verify configuration loaded correctly
# Test key workflows
# Check for errors or warnings

## Advanced Patterns

### Pattern 1: Monorepo Configuration

For monorepos with multiple sub-projects:

monorepo/
├── .goose/
│   └── profiles.yaml          # Root configuration
├── packages/
│   ├── frontend/
│   │   └── .goose/
│   │       └── profiles.yaml  # Frontend-specific
│   ├── backend/
│   │   └── .goose/
│   │       └── profiles.yaml  # Backend-specific
│   └── shared/
│       └── .goose/
│           └── profiles.yaml  # Shared library config
Enter fullscreen mode Exit fullscreen mode

Pattern 2: Dynamic Profile Selection

Use shell aliases to quickly switch contexts:

# ~/.bashrc or ~/.zshrc
alias goose-fe='cd ~/projects/myapp/frontend && goose session start --profile frontend'
alias goose-be='cd ~/projects/myapp/backend && goose session start --profile backend'
alias goose-infra='cd ~/projects/myapp/infra && goose session start --profile infrastructure'
Enter fullscreen mode Exit fullscreen mode

Pattern 3: Configuration Inheritance Chain

# Complex inheritance for specialized needs
base:
  provider: openai
  processor: gpt-4

python-base:
  extends: base
  toolkits:
    - name: developer
    - name: python

django-app:
  extends: python-base
  toolkits:
    - name: database
    - name: docker

ml-pipeline:
  extends: python-base
  toolkits:
    - name: jupyter
    - name: data-science
Enter fullscreen mode Exit fullscreen mode

Monitoring and Maintenance

Configuration Drift Detection

Create a script to identify configuration drift:

# scripts/detect-config-drift.py
import yaml
import os
from pathlib import Path

def compare_configs(base_config, project_config):
    """Compare project config against base and report differences"""
    differences = []

    # Compare provider settings
    if project_config.get('provider') != base_config.get('provider'):
        differences.append(
            f"Provider mismatch: {project_config.get('provider')} vs {base_config.get('provider')}"
        )

    # Add more comparison logic
    return differences

# Scan all projects
projects_dir = Path.home() / 'projects'
for goose_config in projects_dir.glob('**/.goose/profiles.yaml'):
    # Load and compare...
    pass
Enter fullscreen mode Exit fullscreen mode

Regular Maintenance Schedule

Establish a maintenance routine:

  • Weekly: Review new toolkit releases and compatibility
  • Monthly: Audit configurations across projects for drift
  • Quarterly: Update base templates and roll out to projects
  • Annually: Review and refactor configuration strategy

Troubleshooting Common Issues

Issue 1: Configuration Not Loading

Problem: Goose not picking up project configuration
Solution: Check configuration precedence

# Debug which config is being used
goose config show --verbose

# Verify file exists and is valid YAML
cat .goose/profiles.yaml | python -m yaml
Enter fullscreen mode Exit fullscreen mode

Issue 2: Toolkit Conflicts

Problem: Toolkits behaving differently across projects
Solution: Standardize toolkit versions and dependencies

default:
  toolkits:
    - name: developer
      version: "1.0.0"  # Pin versions when possible
Enter fullscreen mode Exit fullscreen mode

Issue 3: Environment Variable Confusion

Problem: Different projects expecting different environment variables
Solution: Use project-specific .env files and document clearly

# Add to project README
## Required Environment Variables
- GOOSE_PROVIDER: OpenAI or Anthropic
- OPENAI_API_KEY: Your OpenAI API key
- GITHUB_TOKEN: GitHub personal access token
Enter fullscreen mode Exit fullscreen mode

Conclusion

Managing goose configurations across multiple projects requires a thoughtful strategy that balances consistency with flexibility. By implementing a configuration hierarchy, using templates, automating synchronization, and following best practices, you can scale goose across your organization without sacrificing maintainability.

Key takeaways

  • Establish a clear hierarchy: Global base → Project-specific → Personal overrides
  • Use configuration templates: Create reusable templates for common project types
  • Automate where possible: Scripts for initialization, validation, and synchronization
  • Version control strategically: Commit shared configs, ignore personal overrides
  • Document thoroughly: Make it easy for team members to understand and follow standards
  • Monitor for drift: Regularly audit configurations to maintain consistency.

As your team grows and adopts goose more widely, these strategies will help you maintain a scalable, consistent configuration management approach that empowers developers rather than constrains them.


Do you have questions about managing Goose across your projects? Drop a comment below

Top comments (0)