|
| 1 | +# Bug agent |
| 2 | + |
| 3 | +> **Tier: conductor** — a front-door agent you *drive*. The organism's |
| 4 | +> **immune system**: it recognises a pathogen (a bug, regression, failing test or |
| 5 | +> PyAutoHeart finding), tells it from benign self, types the threat, recalls whether |
| 6 | +> it has met it before, and mounts a *targeted* response — neutralising the defect at |
| 7 | +> its source without harming healthy tissue. It *consults* the read-only vitals |
| 8 | +> faculty (`--check-health`), never queries Heart directly, and never wields the |
| 9 | +> scalpel itself. (Organism-facing name: *Immune Agent*.) |
| 10 | +
|
| 11 | +The **immune response** of PyAutoBrain. Where the Feature Agent grows the organism and |
| 12 | +the Health conductor keeps it in homeostasis, the Bug Agent answers a *specific threat*: |
| 13 | +it detects and classifies a defect, tells a real pathogen from benign self (an expected |
| 14 | +failure, a flaky test, a mis-filed feature), consults immune **memory** (PyAutoMemory) |
| 15 | +for prior/recurring/flaky cases, and produces a precise repair plan the `start_dev → |
| 16 | +ship_*` workflow executes. It reasons; it does not edit source. |
| 17 | + |
| 18 | +``` |
| 19 | +report / failing test / issue / PyAutoHeart finding |
| 20 | + → Bug Agent → start_dev → start_library / ship_library |
| 21 | + → start_workspace / ship_workspace |
| 22 | + consults ↘ ↙ consults |
| 23 | + vitals faculty PyAutoMemory (recurring failures, prior fixes, flaky tests) |
| 24 | +``` |
| 25 | + |
| 26 | +## Fundamental principle — a precise response, no autoimmunity |
| 27 | + |
| 28 | +A healthy immune response neutralises the pathogen at its source and spares healthy |
| 29 | +tissue. The most delicate tissue here is the **user-facing workspace scripts — they are |
| 30 | +documentation.** A fix that injects test env-vars, hard-codes a path, mutates |
| 31 | +`os.environ`, or drops a silent guard into a tutorial script is an **autoimmune |
| 32 | +reaction** — it damages what it exists to protect. So before proposing any patch the Bug |
| 33 | +Agent asks *where the fix belongs*, and strongly prefers a **general fix in library |
| 34 | +source**. It edits a workspace script only when the defect truly lives there, never in a |
| 35 | +way that reduces clarity; sanctioned knobs go through `config/build/env_vars.yaml` / |
| 36 | +`no_run.yaml`, not inline edits. This surfaces as the `Fix locus:` field of every |
| 37 | +decision. See [`BUG_TAXONOMY.md`](./BUG_TAXONOMY.md) for the full fix-locus rules. |
| 38 | + |
| 39 | +## It reasons; it does not build |
| 40 | + |
| 41 | +The Bug Agent never edits source, opens PRs, or runs builds — that is the existing |
| 42 | +`start_dev` / `ship_*` workflow (and PyAutoBuild at release). It never *runs* tests or |
| 43 | +health checks either: reproduction means **identifying** the repro command or the Heart |
| 44 | +check, and validation is delegated to the vitals faculty. It emits a `BugDecision`; the |
| 45 | +workflow acts on it. |
| 46 | + |
| 47 | +## Four modes |
| 48 | + |
| 49 | +| Mode | Trigger | What it does | |
| 50 | +|------|---------|--------------| |
| 51 | +| **specific** | a `bug/…md` path (or a report) is given | Classify (severity/scope/type/confidence), locate the owner, decide the fix locus + strategy, and produce a `start_dev`-ready plan. | |
| 52 | +| **selection** | nothing given | Scan `bug/**`, rank **severity-first** (a bug list is a triage queue), down-rank in-flight work (`active.md`/`planned.md`), and recommend the next bug — with the reason. | |
| 53 | +| **difficulty-constrained** | `--difficulty` / `--model` / `--budget` / `--ambitious` / `--impact` | Estimate difficulty per bug and select to match (easy/weak/limited-token → small; ambitious → large; impact → highest severity). | |
| 54 | +| **health** | `health` subcommand | Read **two** health inputs — the live **vitals verdict** and the **filed PyAutoHeart GitHub issues** — and route real defects to `bug/health_fixes/`. | |
| 55 | + |
| 56 | +## Classification |
| 57 | + |
| 58 | +Every decision types the threat (heuristic first pass — the reasoning layer refines it): |
| 59 | + |
| 60 | +- **severity:** `critical | high | medium | low` |
| 61 | +- **scope:** `single-file | single-repo | multi-repo | ecosystem` |
| 62 | +- **type:** `test-failure | runtime-error | wrong-result | docs-error | workflow-error | config-error | release-error | flaky | unknown` |
| 63 | +- **confidence:** `high | medium | low` |
| 64 | + |
| 65 | +If a `bug/` prompt is really a feature, refactor, docs or research task, the agent says |
| 66 | +so (`rehome_suggestion`) instead of planning a fix. |
| 67 | + |
| 68 | +## Health mode — two inputs, one router |
| 69 | + |
| 70 | +The bug can come from PyAutoHeart. `bug.sh health` gathers both signals and hands them |
| 71 | +to `_bug.py`, which classifies each finding **real-bug / flaky / config / expected** and |
| 72 | +decides whether the fix belongs in the affected repo, PyAutoHeart, PyAutoBuild or |
| 73 | +PyAutoBrain: |
| 74 | + |
| 75 | +1. the **live vitals verdict** — via the vitals faculty (never Heart directly); |
| 76 | +2. the **filed PyAutoHeart issues** — `gh issue list --repo PyAutoLabs/PyAutoHeart` |
| 77 | + (`$PYAUTO_HEART_REPO` overridable), the durable findings Heart authored. |
| 78 | + |
| 79 | +Real defects become `PyAutoMind/bug/health_fixes/<name>.md` prompts (its README already |
| 80 | +cites Heart issue #27); flaky/expected findings are left to the Health conductor. |
| 81 | + |
| 82 | +> **Boundary with the Health conductor.** The Health conductor drives the assess → |
| 83 | +> triage → dispatch loop toward GREEN — its cut is *validation + recommend, no edit-in |
| 84 | +> fixes*. The Bug Agent is that deferred edit-in-fix arm: Health hands it a red that is a |
| 85 | +> genuine *code* failure, and the Bug Agent turns it into a repair plan. No duplicated |
| 86 | +> triage, no re-implemented Heart checks. |
| 87 | +
|
| 88 | +## BugDecision (the structured return) |
| 89 | + |
| 90 | +``` |
| 91 | +Bug · Mode · Classification (severity / scope / type / confidence) · Likely owner |
| 92 | +Reproduction (known / unknown / PyAutoHeart check) · Relevant context (PyAutoMemory) |
| 93 | +Fix locus (library-source-first · workspace-config · workspace-script[justified] · infra) |
| 94 | +Fix strategy (direct · investigate-first · split-into-phases · defer/re-home) |
| 95 | +Recommended workflow (library | workspace | combined | infrastructure) |
| 96 | +Health validation (vitals checks required before shipping) · Risks · Next action |
| 97 | +``` |
| 98 | + |
| 99 | +`--json` returns the same shape (JSON-consistent with the Feature Agent's |
| 100 | +`FeatureDecision`, plus `classification` and `fix_locus`), so a future Python |
| 101 | +`BugAgent().decide(...)` can return it verbatim. |
| 102 | + |
| 103 | +## Run |
| 104 | + |
| 105 | +```bash |
| 106 | +bin/pyauto-brain bug # selection mode (severity-first) |
| 107 | +bin/pyauto-brain bug bug/autoarray/rect_adapt.md # specific mode |
| 108 | +bin/pyauto-brain bug select --difficulty easy # easy bug for limited tokens |
| 109 | +bin/pyauto-brain bug select --impact # highest-severity bug |
| 110 | +bin/pyauto-brain bug health # vitals verdict + Heart issue scan |
| 111 | +bin/pyauto-brain bug --json bug/autofit/x.md # machine-readable BugDecision |
| 112 | +bin/pyauto-brain bug --check-health bug/autolens/x.md # also annotate with the vitals verdict |
| 113 | +``` |
| 114 | +
|
| 115 | +Exit codes mirror the Feature Agent: `0` produced a decision · `4` no prompts / |
| 116 | +could-not-resolve mind · `5` bad usage. The analysis core (`_bug.py`) is stdlib-only, |
| 117 | +does no network/Git, and never writes — `bug.sh` feeds it the verdict + Heart issues. |
| 118 | +
|
| 119 | +## Faculties (a seam, not yet built) |
| 120 | +
|
| 121 | +The Bug Agent ships as a **conductor only**, consulting the existing `vitals` faculty. |
| 122 | +Its pure, side-effect-free reasoning — classify + locate + fix-locus — is the shape of a |
| 123 | +future read-only **`diagnosis` faculty** (reusable by the Feature Agent's re-homing and |
| 124 | +the Health conductor). Keeping the conductor set small, that split is deferred with a |
| 125 | +clean seam, exactly as Release stayed a mode of Build. See |
| 126 | +[`BUG_TAXONOMY.md`](./BUG_TAXONOMY.md). |
| 127 | +
|
| 128 | +## What this agent must never do |
| 129 | +
|
| 130 | +- Edit source, open PRs, or run builds — that is `start_dev` / `ship_*` / PyAutoBuild. |
| 131 | +- Run tests or health checks, or re-implement a PyAutoHeart check — consult the vitals |
| 132 | + faculty (`--check-health`) and let Heart measure. |
| 133 | +- Query PyAutoHeart directly — only the vitals faculty talks to the Heart organ. |
| 134 | +- **Degrade a user-facing workspace script** to mask a symptom (the autoimmune failure |
| 135 | + mode) — prefer a general library-source fix. |
| 136 | +- Just pick the first bug in selection mode — rank severity-first and explain the choice. |
| 137 | +
|
| 138 | +See [`BUG_TAXONOMY.md`](./BUG_TAXONOMY.md) for the classification taxonomy, the fix-locus |
| 139 | +rules, the two health inputs, and the reuse of the Feature difficulty heuristic. |
0 commit comments