poe2-agent 0.5.0

AI agent for Path of Exile 2 build analysis
Documentation
# Build Generation Workflow

This document describes the internal workflow the agent follows when generating a build. It sits between:
- **User layer** ([interaction.md]./interaction.md) - how users provide input and receive output
- **PoB layer** ([pob-integration.md]./pob-integration.md) - how builds are constructed and validated

## 1. Invariant Extraction

The first step transforms a user's freeform prompt into structured constraints (class, ascendancy, damage type, goals, etc.) with provenance tracking (explicit, inferred, default).

Single-shot extraction — the LLM parses the prompt and outputs structured invariants in one pass, flagging at most one critical ambiguity. See [prompts/invariant-extraction.md](./prompts/invariant-extraction.md) for the full prompt template and examples.

---

## 2. Modes

The workflow operates in different modes depending on context. Mode determines entry point and exploration budget.

| Mode | Trigger | Entry Point | Exploration Budget |
|------|---------|-------------|-------------------|
| **Initial** | New build request | decompose | Minimal — use defaults, validate quickly |
| **Refinement** | User asks to improve specific aspect | explore (targeted sub-problems) | Focused — compare 2-4 realistic options |
| **Strategic** | User asks for fundamental change | decompose (rethink intent) | Deep — may rebuild significant portions |

See [exploration-model.md](./exploration-model.md) for detailed mode behavior and guidelines on when to experiment vs decide directly.

---

## 3. BuildState

The agent maintains a `BuildState` structure during generation. This is internal working state, distinct from:
- **Invariants** - user-facing constraints that persist across refinements
- **PoB XML** - the final build output

The structure tracks **7 sub-problems** (questions to answer), where each sub-problem's answer draws from multiple **solution spaces** (mechanisms). See [sub-problems/index.md](./sub-problems/index.md) for the framework.

### Status Values

| Status | Meaning |
|--------|---------|
| `pending` | Not yet addressed |
| `exploring` | Generating candidates |
| `decided` | Solution chosen (may not be validated yet) |
| `blocked` | Waiting on dependency or conflict resolution |

### Status Transitions

```
        +----------------------------------+
        |                                  |
        v                                  |
    pending --> exploring --> decided ------+
                    |          (conflict invalidates)
                    |
                    v
                 blocked
                    |
                    | (deps resolved)
                    v
                exploring
```

- `pending -> exploring`: Sub-problem work begins
- `exploring -> decided`: Solution chosen
- `exploring -> blocked`: Dependencies not yet satisfied
- `blocked -> exploring`: Dependencies resolved
- `decided -> exploring`: Conflict requires re-evaluation (iteration)

### Phase Transitions

```
                    +------------------------------------------------+
                    |                                                 |
   START --> decompose --> explore --> construct --> validate --> complete
                              ^                         |
                              |                         | (conflicts found)
                              |                         v
                              +-------------------- iterate
```

**decompose:** Parse invariants, identify which sub-problems are pre-decided (e.g., ascendancy from user prompt), set dependencies.

**explore:** For each sub-problem (respecting dependencies), generate candidates and make intent-level decisions. Phase ends when all sub-problems have `decided` status. This phase uses domain knowledge and static data — it does not build anything in PoB.

**construct:** Translate intent into a concrete build in PoB. Allocate passives, equip gear, socket gems. Where decisions can't be validated without simulation (e.g., passive tree pathing), run experiments to compare options. See [exploration-model.md](./exploration-model.md) for experiment patterns and iterative deepening.

**validate:** Run quality checks against the constructed build. Rule-based checks (res capped, enough life, DPS thresholds) plus LLM assessment (content fit, overall coherence). Transitions to `complete` (no conflicts) or `iterate` (conflicts found).

**iterate:** Analyze conflicts, adjust decisions, mark affected sub-problems as `exploring` again. Returns to `explore`.

**complete:** Build is valid. State can be presented to user.

### PoB's Dual Role

PoB participates in two phases for different purposes:

| Phase | PoB Role | Purpose |
|-------|----------|---------|
| **construct** | Simulator | Build the thing, run experiments, compare options |
| **validate** | Validator | Check the result against quality bars and invariants |

During **construct**, PoB is an exploration tool — the agent proposes changes, observes results, and makes evidence-based decisions. During **validate**, PoB is a gatekeeper — the agent checks whether the final build meets requirements.

For the full `BuildState` YAML structure and evolution examples, see [state-examples.md](./state-examples.md).

---

## 4. Reasoning Step Prompts

Four phases drive build generation: **decompose**, **explore**, **construct**, and **validate**. Each has distinct responsibilities and prompt structures.

### Design Principles

1. **Domain injection** - Prompts reference `{domain:file}` placeholders filled at runtime from `docs/domain/`
2. **Structured output** - YAML responses matching `BuildState` schema
3. **Explicit unknowns** - Where domain knowledge is incomplete, prompts note "best effort" behavior

### Prompt Templates

Each phase has its own prompt file:

| Phase | Prompt File | Purpose |
|-------|-------------|---------|
| Decompose | [prompts/decompose.md]./prompts/decompose.md | Initialize BuildState from invariants |
| Explore (generic) | [prompts/explore.md]./prompts/explore.md | Generate candidates, select best option (intent) |
| Explore (per sub-problem) | [prompts/explore-{name}.md]./prompts/ | Sub-problem-specific context and queries |
| Construct | [exploration-model.md]./exploration-model.md | Build in PoB, run experiments for unclear decisions |
| Validate | [prompts/validate.md]./prompts/validate.md | Rule-based + LLM checks, conflict detection |
| Iterate | [prompts/iterate.md]./prompts/iterate.md | Conflict resolution, sub-problem re-opening |

### Prompt Chaining Summary

```
Invariant Extraction (§1)
         |
         v
    +---------+
    |Decompose| --- sets up BuildState
    +----+----+
         |
         v
    +---------------------------------------------+
    |              Explore Loop (intent)            |
    |  for each ready sub-problem:                 |
    |    1. Pre-gather data -> discoveries         |
    |    2. Run explore prompt (LLM reasons)       |
    |    3. Record intent decision + alternatives  |
    +----+-----------------------------------------+
         | (all decided)
         v
    +---------------------------------------------+
    |              Construct (PoB)                  |
    |  Translate intent into concrete build:       |
    |    1. Apply decisions to PoB                 |
    |    2. Where unclear → run experiments        |
    |    3. Interpret results → refine decisions   |
    |  See exploration-model.md for details        |
    +----+-----------------------------------------+
         |
         v
    +---------+
    |Validate | --- rule checks + LLM assessment
    +----+----+
         |
    conflicts? --yes--> Iterate: mark stale discoveries,
         |              re-open affected sub-problems
         |              +---> back to Explore
         no
         v
    Complete --> Present to user
```

### Domain Injection Points

The prompts reference domain knowledge via `{domain:filename}` placeholders. Current state:

| File | Status | Used By |
|------|--------|---------|
| `scaling.md` | Exists | damage_delivery, supports, tree, gear |
| `defenses.md` | Exists | survivability, tree, gear, validate |
| `skills.md` | TODO | damage_delivery, supports |
| `classes.md` | TODO | ascendancy, tree |
| `uniques.md` | TODO | gear |
| `runes.md` | TODO | gear, stat_requirements |
| `solution-budgets.md` | TODO | all sub-problems (quick reference) |
| `dependency_rules.md` | TODO | decompose (conditional dependencies) |

**Fallback behavior:** When a domain file doesn't exist, the prompt proceeds without it. The LLM uses general knowledge (which may be outdated or PoE1-based). Flag in output: `domain_gaps: [missing files]`.

For solution space budgets, see [sub-problems/index.md](./sub-problems/index.md#solution-space-budgets).

---

## 5. Conflict Detection

Conflicts surface at two points, each with different detection mechanics.

### Construct-Time Detection

Experiments during construct may reveal that intent doesn't translate to reality. The agent's response depends on severity:

- **Core assumption invalidated** (skill doesn't function as intended, ascendancy node unavailable) → halt construct, create blocking conflict, iterate immediately
- **Gap another sub-problem may cover** (tree pathing tight but gear not finalized, resist short but flask slots open) → note as provisional conflict, continue constructing
- **Shortfall within tolerances** (ES 10% below target, one resist slightly short) → note, validate will catch if unresolved

Provisional conflicts carry forward to validate. If the completed build resolves them (other sub-problems compensated), they're dropped.

### Validate-Time Detection

Systematic checks on the fully constructed build:

- **Rule-based** — quantitative thresholds per sub-problem (DPS, EHP, resists, mana sustain, Spirit balance, attribute requirements, etc.)
- **Qualitative** — LLM assessment of goal alignment, internal consistency, practical concerns

See [prompts/validate.md](./prompts/validate.md) for check tables, conflict types, and severity definitions.

### Cross-Sub-Problem Budget Checks

Per-sub-problem checks can all pass individually while the aggregate fails. Budget checks detect conflicts that only emerge when solutions are combined:

| Check | Condition | Typical Affects |
|-------|-----------|-----------------|
| Tree point overflow | Allocated points > 123 | damage_delivery, survivability |
| Gear slot contention | Incompatible mod requirements on same slot | competing sub-problems |
| Attribute squeeze | Support color total > attribute/5 | stat_requirements, damage_delivery |
| Spirit overflow | Total reservations > Spirit pool | spirit_allocation |

These run during validate alongside per-sub-problem checks.

### Conflict Dependency Analysis

Before entering resolution, the agent identifies root causes vs symptoms:

1. **Map chains** — if stat_requirement failure prevents equipping a weapon, that causes a downstream damage_gap. Root: stat_requirements.
2. **Group shared-root conflicts** — multiple conflicts caused by the same decision get resolved together.
3. **Tag** each conflict as `root` or `symptom`. Symptoms don't get independent resolution attempts — they're expected to resolve when their root is fixed.

This analysis feeds directly into resolution priority ordering (§6).

---

## 6. Conflict Resolution

When blocking conflicts exist, the iterate phase resolves them. Full resolution logic and prompt template in [prompts/iterate.md](./prompts/iterate.md).

### Priority Ordering

Multiple conflicts are resolved in this order:

1. **Blocking before warning** — warnings don't trigger iteration
2. **Root before symptom** — from dependency analysis (§5). Symptoms may resolve automatically
3. **Shared-root grouping** — same root cause → single resolution pass
4. **Fewer affected sub-problems first** — cheaper resolutions yield faster progress and may simplify remaining conflicts

### Resolution Flow

For each conflict (or conflict group):

1. Select strategy from `suggested_solutions` (least-disruptive first)
2. Re-open only the affected sub-problems (status → `exploring`)
3. Inject conflict context as constraints on re-exploration
4. Preserve prior attempt so explore avoids the same solution
5. Mark dependent discoveries stale

### Limits and Escalation

| Limit | Value | On Breach |
|-------|-------|-----------|
| Per-conflict attempts | 3 | Try next `suggested_solution`; if exhausted, escalate |
| Global iterations | 5 | Present best attempt with caveats |
| Emergency stop | Blocking count ↑ from previous iteration | Backtrack to snapshot |

When limits are reached, present the build with unresolved conflicts, what was tried, and suggested manual adjustments. See [interaction.md](./interaction.md) for intermediate presentation.

---

## 7. Example Walkthrough

See [walkthrough-cold-dot.md](./walkthrough-cold-dot.md) for a complete end-to-end trace of **"cold DoT occultist for bossing"** through every phase: invariant extraction → decompose → explore → construct → validate → iterate (mana conflict) → re-validate → complete.

---

## Related Documents

- [interaction.md]./interaction.md - User interaction model
- [reasoning-model.md]./reasoning-model.md - High-level reasoning loop
- [sub-problems/index.md]./sub-problems/index.md - Build sub-problems
- [exploration-model.md]./exploration-model.md - Construct phase: PoB simulation, experiments, iterative deepening
- [state-examples.md]./state-examples.md - BuildState YAML examples and evolution
- [walkthrough-cold-dot.md]./walkthrough-cold-dot.md - Complete example walkthrough

## Related Systems

- [Learning System]../../.project/systems/learning-system.md - How the agent persists knowledge (scored lists, soft invariants, eliminations)
- [Skill System]../../.project/systems/skill-system.md - Agent capabilities and opportunity cost reasoning
- [Architecture]../../.project/systems/architecture.md - Port/adapter patterns for persistence