policyengine-aggregation

PolicyEngine aggregation patterns - using adds attribute and add() function for summing variables across entities

16 stars

Best use case

policyengine-aggregation is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

PolicyEngine aggregation patterns - using adds attribute and add() function for summing variables across entities

Teams using policyengine-aggregation should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/policyengine-aggregation/SKILL.md --create-dirs "https://raw.githubusercontent.com/diegosouzapw/awesome-omni-skill/main/skills/development/policyengine-aggregation/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/policyengine-aggregation/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How policyengine-aggregation Compares

Feature / Agentpolicyengine-aggregationStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

PolicyEngine aggregation patterns - using adds attribute and add() function for summing variables across entities

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# PolicyEngine Aggregation Patterns

Essential patterns for summing variables across entities in PolicyEngine.

## Quick Decision Guide

```
Is the variable ONLY a sum of other variables?
│
├─ YES → Use `adds` attribute (NO formula needed!)
│         adds = ["var1", "var2"]
│
└─ NO → Use `add()` function in formula
         (when you need max_, where, conditions, etc.)
```

## Quick Reference

| Need | Use | Example |
|------|-----|---------|
| Simple sum | `adds` | `adds = ["var1", "var2"]` |
| Sum from parameters | `adds` | `adds = "gov.path.to.list"` |
| Sum + max_() | `add()` | `max_(0, add(...))` |
| Sum + where() | `add()` | `where(cond, add(...), 0)` |
| Sum + conditions | `add()` | `if cond: add(...)` |
| Count booleans | `adds` | `adds = ["is_eligible"]` |

---

## 1. `adds` Class Attribute (Preferred When Possible)

### When to Use
Use `adds` when a variable is **ONLY** the sum of other variables with **NO additional logic**.

### Syntax
```python
class variable_name(Variable):
    value_type = float
    entity = Entity
    definition_period = PERIOD

    # Option 1: List of variables
    adds = ["variable1", "variable2", "variable3"]

    # Option 2: Parameter tree path
    adds = "gov.path.to.parameter.list"
```

### Key Points
- ✅ No `formula()` method needed
- ✅ Automatically handles entity aggregation (person → household/tax_unit/spm_unit)
- ✅ Clean and declarative

### Example: Simple Income Sum
```python
class tanf_gross_earned_income(Variable):
    value_type = float
    entity = SPMUnit
    label = "TANF gross earned income"
    unit = USD
    definition_period = MONTH

    adds = ["employment_income", "self_employment_income"]
    # NO formula needed! Automatically:
    # 1. Gets each person's employment_income
    # 2. Gets each person's self_employment_income
    # 3. Sums all values across SPM unit members
```

### Example: Using Parameter List
```python
class income_tax_refundable_credits(Variable):
    value_type = float
    entity = TaxUnit
    definition_period = YEAR

    adds = "gov.irs.credits.refundable"
    # Parameter file contains list like:
    # - earned_income_tax_credit
    # - child_tax_credit
    # - additional_child_tax_credit
```

### Example: Counting Boolean Values
```python
class count_eligible_people(Variable):
    value_type = int
    entity = SPMUnit
    definition_period = YEAR

    adds = ["is_eligible_person"]
    # Automatically sums True (1) and False (0) across members
```

---

## 2. `add()` Function (When Logic Needed)

### When to Use
Use `add()` inside a `formula()` when you need:
- To apply `max_()`, `where()`, or conditions
- To combine with other operations
- To modify values before/after summing

### Syntax
```python
from policyengine_us.model_api import *

def formula(entity, period, parameters):
    result = add(entity, period, variable_list)
```

**Parameters:**
- `entity`: The entity to operate on
- `period`: The time period for calculation
- `variable_list`: List of variable names or parameter path

### Example: With max_() to Prevent Negatives
```python
class adjusted_earned_income(Variable):
    value_type = float
    entity = SPMUnit
    definition_period = MONTH

    def formula(spm_unit, period, parameters):
        # Need max_() to clip negative values
        gross = add(spm_unit, period, ["employment_income", "self_employment_income"])
        return max_(0, gross)  # Prevent negative income
```

### Example: With Additional Logic
```python
class household_benefits(Variable):
    value_type = float
    entity = Household
    definition_period = YEAR

    def formula(household, period, parameters):
        # Sum existing benefits
        BENEFITS = ["snap", "tanf", "ssi", "social_security"]
        existing = add(household, period, BENEFITS)

        # Add new benefit conditionally
        new_benefit = household("special_benefit", period)
        p = parameters(period).gov.special_benefit

        if p.include_in_total:
            return existing + new_benefit
        return existing
```

### Example: Building on Previous Variables
```python
class total_deductions(Variable):
    value_type = float
    entity = TaxUnit
    definition_period = YEAR

    def formula(tax_unit, period, parameters):
        p = parameters(period).gov.irs.deductions

        # Get standard deductions using parameter list
        standard = add(tax_unit, period, p.standard_items)

        # Apply phase-out logic
        income = tax_unit("adjusted_gross_income", period)
        phase_out_rate = p.phase_out_rate
        phase_out_start = p.phase_out_start

        reduction = max_(0, (income - phase_out_start) * phase_out_rate)
        return max_(0, standard - reduction)
```

---

## 3. Common Anti-Patterns to Avoid

### ❌ NEVER: Manual Summing
```python
# WRONG - Never do this!
def formula(spm_unit, period, parameters):
    person = spm_unit.members
    employment = person("employment_income", period)
    self_emp = person("self_employment_income", period)
    return spm_unit.sum(employment + self_emp)  # ❌ BAD
```

### ✅ CORRECT: Use adds
```python
# RIGHT - Clean and simple
adds = ["employment_income", "self_employment_income"]  # ✅ GOOD
```

### ❌ WRONG: Using add() When adds Suffices
```python
# WRONG - Unnecessary complexity
def formula(spm_unit, period, parameters):
    return add(spm_unit, period, ["income1", "income2"])  # ❌ Overkill
```

### ✅ CORRECT: Use adds
```python
# RIGHT - Simpler
adds = ["income1", "income2"]  # ✅ GOOD
```

---

## 4. Entity Aggregation Explained

When using `adds` or `add()`, PolicyEngine automatically handles entity aggregation:

```python
class household_total_income(Variable):
    entity = Household  # Higher-level entity
    definition_period = YEAR

    adds = ["employment_income", "self_employment_income"]
    # employment_income is defined for Person (lower-level)
    # PolicyEngine automatically:
    # 1. Gets employment_income for each person in household
    # 2. Gets self_employment_income for each person
    # 3. Sums all values to household level
```

This works across all entity hierarchies:
- Person → Tax Unit
- Person → SPM Unit
- Person → Household
- Tax Unit → Household
- SPM Unit → Household

---

## 5. Parameter Lists

Parameters can define lists of variables to sum:

**Parameter file** (`gov/irs/credits/refundable.yaml`):
```yaml
description: List of refundable tax credits
values:
  2024-01-01:
    - earned_income_tax_credit
    - child_tax_credit
    - additional_child_tax_credit
```

**Usage in variable**:
```python
adds = "gov.irs.credits.refundable"
# Automatically sums all credits in the list
```

---

## 6. Decision Matrix

| Scenario | Solution | Code |
|----------|----------|------|
| Sum 2-3 variables | `adds` attribute | `adds = ["var1", "var2"]` |
| Sum many variables | Parameter list | `adds = "gov.path.list"` |
| Sum + prevent negatives | `add()` with `max_()` | `max_(0, add(...))` |
| Sum + conditional | `add()` with `where()` | `where(eligible, add(...), 0)` |
| Sum + phase-out | `add()` with calculation | `add(...) - reduction` |
| Count people/entities | `adds` with boolean | `adds = ["is_child"]` |

---

## 7. Key Principles

1. **Default to `adds` attribute** when variable is only a sum
2. **Use `add()` function** only when additional logic is needed
3. **Never manually sum** with `entity.sum(person(...) + person(...))`
4. **Let PolicyEngine handle** entity aggregation automatically
5. **Use parameter lists** for maintainable, configurable sums

---

## Related Skills

- **policyengine-period-patterns-skill**: For period conversion when summing across different time periods
- **policyengine-core-skill**: For understanding entity hierarchies and relationships

---

## For Agents

When implementing or reviewing code:

1. **Check if `adds` can be used** before writing a formula
2. **Prefer declarative over imperative** when possible
3. **Follow existing patterns** in the codebase
4. **Test entity aggregation** carefully in YAML tests
5. **Document parameter lists** clearly for `adds` references

---

## Common Use Cases

### Earned Income
```python
adds = ["employment_income", "self_employment_income"]
```

### Unearned Income
```python
adds = ["interest_income", "dividend_income", "rental_income"]
```

### Total Benefits
```python
adds = ["snap", "tanf", "wic", "ssi", "social_security"]
```

### Tax Credits
```python
adds = "gov.irs.credits.refundable"
```

### Counting Children
```python
adds = ["is_child"]  # Returns count of children
```

Related Skills

bgo

10
from diegosouzapw/awesome-omni-skill

Automates the complete Blender build-go workflow, from building and packaging your extension/add-on to removing old versions, installing, enabling, and launching Blender for quick testing and iteration.

Coding & Development

vercel-deploy

16
from diegosouzapw/awesome-omni-skill

Deploy applications and websites to Vercel. Use this skill when the user requests deployment actions such as "Deploy my app", "Deploy this to production", "Create a preview deployment", "Deploy and give me the link", or "Push this live". No authentication required - returns preview URL and claimable deployment link.

vercel-deploy-claimable

16
from diegosouzapw/awesome-omni-skill

Deploy applications and websites to Vercel. Use this skill when the user requests deployment actions such as 'Deploy my app', 'Deploy this to production', 'Create a preview deployment', 'Deploy and...

vercel-composition-patterns

16
from diegosouzapw/awesome-omni-skill

React composition patterns that scale. Use when refactoring components with boolean prop proliferation, building flexible component libraries, or designing reusable APIs. Triggers on tasks involving compound components, render props, context providers, or component architecture. Includes React 19 API changes.

vercel-ai-sdk-development

16
from diegosouzapw/awesome-omni-skill

Use when building AI-powered applications with the Vercel AI SDK (V6+). Covers agents (ToolLoopAgent), tool design with execution approval and strict mode, MCP client integration, structured output with tool calling, streaming patterns, DevTools debugging, reranking, provider-specific tools, and UI integration with React/Next.js.

vercel-ai-sdk-best-practices

16
from diegosouzapw/awesome-omni-skill

Best practices for using the Vercel AI SDK in Next.js 15 applications with React Server Components and streaming capabilities.

venice-router

16
from diegosouzapw/awesome-omni-skill

Supreme model router for Venice.ai — the privacy-first, uncensored AI platform. Automatically classifies query complexity and routes to the cheapest adequate model. Supports web search, uncensored mode, private-only mode (zero data retention), conversation-aware routing, cost budgets, function calling, thinking/reasoning mode, and 35+ Venice.ai text models. Use when the user wants to chat via Venice.ai, send prompts through Venice, or needs smart model selection to minimize API costs while keeping data private from Big Tech.

validator-workflow

16
from diegosouzapw/awesome-omni-skill

Phase-level validation workflow for validator agents. Handles loading project rules, reading phase files, running /code-review, conditional verification (unit tests + typecheck + E2E/DB tests based on phase type), determining verdict, and reporting to the orchestrator. Invoke this skill as your first action — not user-invocable.

V3 Core Implementation

16
from diegosouzapw/awesome-omni-skill

Core module implementation for claude-flow v3. Implements DDD domains, clean architecture patterns, dependency injection, and modular TypeScript codebase with comprehensive testing.

uvicorn

16
from diegosouzapw/awesome-omni-skill

ASGI server for Python web applications - Fast, production-ready server for async frameworks

using-superantigravity

16
from diegosouzapw/awesome-omni-skill

Use when starting any conversation — establishes how to find and use skills, requiring skill check before ANY response including clarifying questions

using-neon

16
from diegosouzapw/awesome-omni-skill

Guides and best practices for working with Neon Serverless Postgres. Covers getting started, local development with Neon, choosing a connection method, Neon features, authentication (@neondatabase/...