Evolution Taxonomy Classifier
Overview
Your agent has diagnosed a reasoning failure. The execution graph shows where
it went wrong and the cognitive-fault isolator has classified the breakdown.
Now what? The temptation is to jump straight to a fix: tweak a prompt, retrain
an adapter, add a guardrail. But self-evolution spans more than a single lever: it is a
four-dimensional design space, and pulling the wrong lever wastes compute,
introduces regressions, or both.
This skill locates any proposed evolution on the four Gao et al. axes:
- WHAT evolves —
model (weights or prompts; needs execution graphs for
causal tracing) | context (retrieval; this IS graph evolution: rewire
edges, merge nodes, prune subgraphs) | tool (rewires the tool subgraph by
reweighting task-type-to-tool edges on observed success) | architecture
(graph surgery on the workflow graph itself).
- WHEN it fires —
intra_test_time (within one request; must be
sub-second; Reflect-Retry-Reward) | inter_test_time (between requests; can
afford fine-tuning or graph restructuring; SEAL overnight, semantic
backpropagation).
- HOW the agent learns —
reward_based (scalar signals: InfoGain, user
satisfaction) | imitation_based (copy successful trajectories) |
population_based (maintain variants, select fittest).
- WHERE it applies —
general_purpose (all tasks) | domain_specialized
(one vertical, e.g. cascade failures in microservice topologies).
Every axis requires graph structure to operate. As the chapter states: the
graph is not optional infrastructure here, it is the substrate that makes any
of these axes operable. Alshikh's production research reinforces the point: the
first methodology is GNN-inspired, where "each adaptation becomes a traceable
node." The classifier attaches that graph-dependency rationale to every value
it assigns, and route_failure maps a diagnosed failure to its axis per Table
7-1.
When to Use
- AFTER a diagnostic report exists and you are deciding which evolution lever
to pull
- To sanity-check a proposed evolution: is this really model evolution, or is
it context evolution wearing a model-evolution costume?
- To route a diagnosed failure type (FORMAT, REASONING, KNOWLEDGE) to its
primary axis, timing, and mechanism
- When designing a self-evolution loop and you need the four-axis vocabulary to
keep intra-test-time and inter-test-time paths distinct
Phrases: "which evolution lever", "classify this evolution", "self-evolution
taxonomy", "what evolves / when / how / where", "route this failure",
"Table 7-1 routing", "is this model or context evolution".
When NOT to Use
- Producing the diagnosis. The failure classification comes from the
execution graph plus the cognitive-fault isolator upstream. This skill
consumes a diagnosis; it does not generate one.
- Executing the evolution. This is a Reviewer, not an Actuator. It tells
you
model / inter_test_time / reward_based / domain_specialized; it does not
run the fine-tune, the rerank, or the graph surgery.
- One-shot single-call agents. No evolution loop, no axes to place.
- Choosing K in a retrieval pipeline or any within-axis hyperparameter. The
classifier picks the axis, not the setting inside it.
Process
| Step |
Input |
Action |
Output |
Verification |
| 1 |
(none) |
cli.py axes |
Pretty-print the four axes, allowed values, and each value's graph rationale |
Four axes printed; every value has a non-empty rationale line |
| 2 |
what + when + how + where (+ notes) |
lib.classify_from_signals(...) |
EvolutionClassification with graph_rationale filled per axis |
Each axis value in its allowed set; unknown value raises ValueError |
| 3 |
free-form proposal dict {description, target, timing, mechanism, scope} |
lib.classify(proposal) |
EvolutionClassification (keywords mapped to axis values, then delegated to step 2) |
"fine-tune adapter" -> model; "rerank KG subgraph" -> context; "API endpoint" -> tool |
| 4 |
failure_type (+ recurring, + is_format) |
lib.route_failure(...) |
{evolution_axis, timing, mechanism, rationale} per Table 7-1 |
FORMAT -> architecture / structural-constraint / inter; REASONING single-node -> model / prompt / intra; KNOWLEDGE systemic -> model / fine-tune / inter |
| 5 |
classification |
EvolutionClassification.to_dict() |
JSON-serializable dict |
Round-trips through json.dumps without error |
| 6 |
scenario name devops |
cli.py scenario devops |
Classifies the DevOps prompt-refinement evolution (model / inter_test_time / reward_based / domain_specialized) |
Output places all four axes and prints the failure routing for the cascade-misprediction pattern |
| 6b |
when_fires + measured op ms + request budget ms |
lib.budget_check(when, ms, budget) |
verdict OK_IN_PATH / MOVE_TO_INTER / OK_OFF_PATH |
an over-budget intra-test-time op MUST verdict MOVE_TO_INTER |
| 7 |
(none) |
cli.py benchmark |
Assertion battery |
Prints N/M passed, exits 0 on all-pass |
Rationalizations
| Agent rationalization |
Documented rebuttal |
| "The diagnosis is clear, I'll just fix it — I don't need to classify." |
The chapter is explicit: "self-evolution is not a single lever. It is a four-dimensional design space, and pulling the wrong lever wastes compute, introduces regressions, or both." Classification is what prevents the wrong lever. |
| "Rerankng retrieval is model evolution — the model does the reranking." |
No. Ch7: context evolution "restructures what the agent retrieves." It IS graph evolution: "you evolve context by rewiring edges, merging redundant nodes, and pruning stale subgraphs." Reranking a subgraph touches context, not model. Calling it model evolution routes you to a fine-tune you do not need. |
| "A format error just needs the model to speak JSON better — that's fine-tuning." |
Ch7 rejects this directly: "Rather than teaching the model to speak JSON better through more training, attach an output schema constraint directly to that specific node." FormatViolation routes to architecture (structural constraint), a permanent fix, not model. |
| "Intra-test-time and inter-test-time are the same thing at different speeds." |
The distinction is what the latency budget rests on: "intra-test-time evolution must be fast (sub-second decisions), while inter-test-time evolution can afford expensive operations like fine-tuning or graph restructuring." Mis-timing a fine-tune into the request path breaks the latency budget. |
| "One localized reasoning miss means we should fine-tune." |
Ch7 three-way strategy: a "localized reasoning failure (low InfoGain on one or two steps)" calls for prompt refinement, which is "fast, reversible, and the right first resort." Fine-tuning is for a "recurring pattern of the same reasoning failure type." recurring=False stays on the prompt path. |
| "Domain-specialized versus general-purpose is a soft preference, not a real axis." |
Ch7: "Your DevOps agent does not need to improve at poetry, but it absolutely needs to get better at predicting cascade failures in microservice topologies." WHERE scopes the evolution to a subgraph region; skipping it spends compute improving tasks the agent will never run. |
Red Flags
- A context-evolution proposal classified as
model. Reranking, merging
memory nodes, or pruning subgraphs is graph evolution. Routing it to a
fine-tune wastes a heavyweight lever on a retrieval fix.
- A FormatViolation routed to
model / fine-tune. The chapter's permanent
fix is a structural constraint on the workflow-graph node, not more training.
- A fine-tune assigned
intra_test_time. Fine-tuning cannot run sub-second
inside a request. If the timing says intra, the mechanism is wrong.
graph_rationale empty for a chosen axis value. The whole point is that
every axis depends on graph structure; an empty rationale means the
classifier bypassed the chapter grounding.
route_failure called on an undiagnosed failure string. Unknown
failure_type raises ValueError by design; catch it and go back to the
diagnosis, do not guess an axis.
Non-Negotiable Verification
- Run the benchmark battery.
python cli.py benchmark must report all
gates passed:
- every axis value validates through
classify_from_signals
- an unknown value on any axis raises ValueError
classify() maps a "fine-tune adapter" proposal to what=model and a
"rerank KG subgraph" proposal to what=context
route_failure(FORMAT) returns architecture / structural-constraint;
REASONING single-node returns model / prompt / intra_test_time;
recurring REASONING and systemic KNOWLEDGE escalate to model /
fine-tune / inter_test_time
graph_rationale is populated for all four chosen axis values
- Run the DevOps scenario.
python cli.py scenario devops classifies the
prompt-refinement evolution as model / inter_test_time / reward_based / domain_specialized and prints the failure routing for the recurring
cascade-misprediction pattern.
- Verify CLI help.
python cli.py --help exits 0 and prints the SKILL.md
description.
Security Posture
- Prompt injection. The free-form proposal passed to
classify is treated
as untrusted text. Keyword matching is read-only substring inspection; no
part of the proposal is executed, eval'd, or used to construct a shell
command. A proposal that embeds instructions has no path to action here: the
output is a fixed-vocabulary classification, never a passthrough of proposal
text into a privileged call.
- Data exfiltration.
lib.py makes no network calls. Classification runs
entirely in-memory over the caller-supplied dict and the module's own axis
constants. CLI output goes to stdout; the caller owns downstream piping.
- Privilege escalation. No shell invocation, no concatenated input to a
shell, no file writes. The only file read is an optional
--path proposal.json the caller names explicitly, plus SKILL.md for the help
description. Axis constants are author-controlled and stdlib-only.
Composition
- Composes with the
execution-graph primitive (the substrate every axis
depends on). The diagnosis this skill consumes is a query over that graph.
- Composes with the three-way intervention strategy (prompt / fine-tune /
constrain):
route_failure is the routing function Ch7 Example 7 describes,
turning a diagnostic report's failure type into an axis, timing, and
mechanism.
- Feeds the actuation layer (semantic backpropagation, SEAL, TPT,
Reflect-Retry-Reward). This skill picks the lever; those frameworks pull it.
- Reviewer, does not compose with, any actuator: it emits a classification
and a route, never a weight update or a graph mutation.
Source Attribution
Distilled from Agentic GraphRAG (O'Reilly, by Anthony Alcaraz and Sam Julien),
Chapter 7 — Self-Evolution and Evaluation, the "A Taxonomy for Self-Evolution"
section, Table 7-1 (failure-to-evolution routing), and the intervention-routing
Example. Key references named in the chapter: Gao et al. (2025) four-axis
self-evolution taxonomy; Waseem Alshikh (2025) production research on
self-evolving models, GNN-inspired methodology where "each adaptation becomes a
traceable node"; the SEAL, TPT, and Reflect-Retry-Reward learning frameworks.
This skill is the Reviewer-pattern routing front end for that section: it
classifies and routes, and the downstream frameworks execute the evolution.
1---2name: evolution-taxonomy-classifier3description: Locate a proposed self-evolution in the four-dimensional design space Gao et al. (2025) formalize: WHAT evolves (model / context / tool / architecture), WHEN it fires (intra-test-time within one request / inter-test-time between requests), HOW the agent learns (reward / imitation / population), and WHERE it applies (general-purpose / domain-specialized). Each axis value carries the graph-dependency rationale the chapter gives, and a diagnosed failure type routes to its primary evolution axis, timing, and mechanism (Table 7-1). Use AFTER the diagnostic report exists and BEFORE you pull an evolution lever, so you fix the right target instead of wasting compute or introducing regressions. NOT for producing the diagnosis itself (that is the execution-graph plus cognitive-fault-isolator upstream), NOT for executing the evolution (this classifies and routes; it does not fine-tune, rerank, or restructure).4---56# Evolution Taxonomy Classifier78## Overview910Your agent has diagnosed a reasoning failure. The execution graph shows where11it went wrong and the cognitive-fault isolator has classified the breakdown.12Now what? The temptation is to jump straight to a fix: tweak a prompt, retrain13an adapter, add a guardrail. But self-evolution spans more than a single lever: it is a14four-dimensional design space, and pulling the wrong lever wastes compute,15introduces regressions, or both.1617This skill locates any proposed evolution on the four Gao et al. axes:1819- **WHAT evolves** — `model` (weights or prompts; needs execution graphs for20 causal tracing) | `context` (retrieval; this IS graph evolution: rewire21 edges, merge nodes, prune subgraphs) | `tool` (rewires the tool subgraph by22 reweighting task-type-to-tool edges on observed success) | `architecture`23 (graph surgery on the workflow graph itself).24- **WHEN it fires** — `intra_test_time` (within one request; must be25 sub-second; Reflect-Retry-Reward) | `inter_test_time` (between requests; can26 afford fine-tuning or graph restructuring; SEAL overnight, semantic27 backpropagation).28- **HOW the agent learns** — `reward_based` (scalar signals: InfoGain, user29 satisfaction) | `imitation_based` (copy successful trajectories) |30 `population_based` (maintain variants, select fittest).31- **WHERE it applies** — `general_purpose` (all tasks) | `domain_specialized`32 (one vertical, e.g. cascade failures in microservice topologies).3334Every axis requires graph structure to operate. As the chapter states: the35graph is not optional infrastructure here, it is the substrate that makes any36of these axes operable. Alshikh's production research reinforces the point: the37first methodology is GNN-inspired, where "each adaptation becomes a traceable38node." The classifier attaches that graph-dependency rationale to every value39it assigns, and `route_failure` maps a diagnosed failure to its axis per Table407-1.4142## When to Use4344- AFTER a diagnostic report exists and you are deciding which evolution lever45 to pull46- To sanity-check a proposed evolution: is this really model evolution, or is47 it context evolution wearing a model-evolution costume?48- To route a diagnosed failure type (FORMAT, REASONING, KNOWLEDGE) to its49 primary axis, timing, and mechanism50- When designing a self-evolution loop and you need the four-axis vocabulary to51 keep intra-test-time and inter-test-time paths distinct5253Phrases: "which evolution lever", "classify this evolution", "self-evolution54taxonomy", "what evolves / when / how / where", "route this failure",55"Table 7-1 routing", "is this model or context evolution".5657## When NOT to Use5859- **Producing the diagnosis.** The failure classification comes from the60 execution graph plus the cognitive-fault isolator upstream. This skill61 consumes a diagnosis; it does not generate one.62- **Executing the evolution.** This is a Reviewer, not an Actuator. It tells63 you `model / inter_test_time / reward_based / domain_specialized`; it does not64 run the fine-tune, the rerank, or the graph surgery.65- **One-shot single-call agents.** No evolution loop, no axes to place.66- **Choosing K in a retrieval pipeline or any within-axis hyperparameter.** The67 classifier picks the axis, not the setting inside it.6869## Process7071| Step | Input | Action | Output | Verification |72|------|-------|--------|--------|--------------|73| 1 | (none) | `cli.py axes` | Pretty-print the four axes, allowed values, and each value's graph rationale | Four axes printed; every value has a non-empty rationale line |74| 2 | what + when + how + where (+ notes) | `lib.classify_from_signals(...)` | `EvolutionClassification` with `graph_rationale` filled per axis | Each axis value in its allowed set; unknown value raises ValueError |75| 3 | free-form proposal dict {description, target, timing, mechanism, scope} | `lib.classify(proposal)` | `EvolutionClassification` (keywords mapped to axis values, then delegated to step 2) | "fine-tune adapter" -> model; "rerank KG subgraph" -> context; "API endpoint" -> tool |76| 4 | failure_type (+ recurring, + is_format) | `lib.route_failure(...)` | `{evolution_axis, timing, mechanism, rationale}` per Table 7-1 | FORMAT -> architecture / structural-constraint / inter; REASONING single-node -> model / prompt / intra; KNOWLEDGE systemic -> model / fine-tune / inter |77| 5 | classification | `EvolutionClassification.to_dict()` | JSON-serializable dict | Round-trips through `json.dumps` without error |78| 6 | scenario name `devops` | `cli.py scenario devops` | Classifies the DevOps prompt-refinement evolution (model / inter_test_time / reward_based / domain_specialized) | Output places all four axes and prints the failure routing for the cascade-misprediction pattern |79| 6b | when_fires + measured op ms + request budget ms | `lib.budget_check(when, ms, budget)` | verdict OK_IN_PATH / MOVE_TO_INTER / OK_OFF_PATH | an over-budget intra-test-time op MUST verdict MOVE_TO_INTER |80| 7 | (none) | `cli.py benchmark` | Assertion battery | Prints `N/M passed`, exits 0 on all-pass |8182## Rationalizations8384| Agent rationalization | Documented rebuttal |85|------------------------|--------------------|86| "The diagnosis is clear, I'll just fix it — I don't need to classify." | The chapter is explicit: "self-evolution is not a single lever. It is a four-dimensional design space, and pulling the wrong lever wastes compute, introduces regressions, or both." Classification is what prevents the wrong lever. |87| "Rerankng retrieval is model evolution — the model does the reranking." | No. Ch7: context evolution "restructures what the agent retrieves." It IS graph evolution: "you evolve context by rewiring edges, merging redundant nodes, and pruning stale subgraphs." Reranking a subgraph touches `context`, not `model`. Calling it model evolution routes you to a fine-tune you do not need. |88| "A format error just needs the model to speak JSON better — that's fine-tuning." | Ch7 rejects this directly: "Rather than teaching the model to speak JSON better through more training, attach an output schema constraint directly to that specific node." FormatViolation routes to `architecture` (structural constraint), a permanent fix, not `model`. |89| "Intra-test-time and inter-test-time are the same thing at different speeds." | The distinction is what the latency budget rests on: "intra-test-time evolution must be fast (sub-second decisions), while inter-test-time evolution can afford expensive operations like fine-tuning or graph restructuring." Mis-timing a fine-tune into the request path breaks the latency budget. |90| "One localized reasoning miss means we should fine-tune." | Ch7 three-way strategy: a "localized reasoning failure (low InfoGain on one or two steps)" calls for prompt refinement, which is "fast, reversible, and the right first resort." Fine-tuning is for a "recurring pattern of the same reasoning failure type." `recurring=False` stays on the prompt path. |91| "Domain-specialized versus general-purpose is a soft preference, not a real axis." | Ch7: "Your DevOps agent does not need to improve at poetry, but it absolutely needs to get better at predicting cascade failures in microservice topologies." WHERE scopes the evolution to a subgraph region; skipping it spends compute improving tasks the agent will never run. |9293## Red Flags9495- **A context-evolution proposal classified as `model`.** Reranking, merging96 memory nodes, or pruning subgraphs is graph evolution. Routing it to a97 fine-tune wastes a heavyweight lever on a retrieval fix.98- **A FormatViolation routed to `model` / fine-tune.** The chapter's permanent99 fix is a structural constraint on the workflow-graph node, not more training.100- **A fine-tune assigned `intra_test_time`.** Fine-tuning cannot run sub-second101 inside a request. If the timing says intra, the mechanism is wrong.102- **`graph_rationale` empty for a chosen axis value.** The whole point is that103 every axis depends on graph structure; an empty rationale means the104 classifier bypassed the chapter grounding.105- **`route_failure` called on an undiagnosed failure string.** Unknown106 failure_type raises ValueError by design; catch it and go back to the107 diagnosis, do not guess an axis.108109## Non-Negotiable Verification1101111. **Run the benchmark battery.** `python cli.py benchmark` must report all112 gates passed:113 - every axis value validates through `classify_from_signals`114 - an unknown value on any axis raises ValueError115 - `classify()` maps a "fine-tune adapter" proposal to `what=model` and a116 "rerank KG subgraph" proposal to `what=context`117 - `route_failure(FORMAT)` returns `architecture` / `structural-constraint`;118 REASONING single-node returns `model` / `prompt` / `intra_test_time`;119 recurring REASONING and systemic KNOWLEDGE escalate to `model` /120 `fine-tune` / `inter_test_time`121 - `graph_rationale` is populated for all four chosen axis values1222. **Run the DevOps scenario.** `python cli.py scenario devops` classifies the123 prompt-refinement evolution as `model / inter_test_time / reward_based /124 domain_specialized` and prints the failure routing for the recurring125 cascade-misprediction pattern.1263. **Verify CLI help.** `python cli.py --help` exits 0 and prints the SKILL.md127 description.128129## Security Posture130131- **Prompt injection.** The free-form proposal passed to `classify` is treated132 as untrusted text. Keyword matching is read-only substring inspection; no133 part of the proposal is executed, eval'd, or used to construct a shell134 command. A proposal that embeds instructions has no path to action here: the135 output is a fixed-vocabulary classification, never a passthrough of proposal136 text into a privileged call.137- **Data exfiltration.** `lib.py` makes no network calls. Classification runs138 entirely in-memory over the caller-supplied dict and the module's own axis139 constants. CLI output goes to stdout; the caller owns downstream piping.140- **Privilege escalation.** No shell invocation, no concatenated input to a141 shell, no file writes. The only file read is an optional `--path142 proposal.json` the caller names explicitly, plus `SKILL.md` for the help143 description. Axis constants are author-controlled and stdlib-only.144145## Composition146147- **Composes with** the `execution-graph` primitive (the substrate every axis148 depends on). The diagnosis this skill consumes is a query over that graph.149- **Composes with** the three-way intervention strategy (prompt / fine-tune /150 constrain): `route_failure` is the routing function Ch7 Example 7 describes,151 turning a diagnostic report's failure type into an axis, timing, and152 mechanism.153- **Feeds** the actuation layer (semantic backpropagation, SEAL, TPT,154 Reflect-Retry-Reward). This skill picks the lever; those frameworks pull it.155- **Reviewer, does not compose with,** any actuator: it emits a classification156 and a route, never a weight update or a graph mutation.157158## Source Attribution159160Distilled from *Agentic GraphRAG* (O'Reilly, by Anthony Alcaraz and Sam Julien),161Chapter 7 — Self-Evolution and Evaluation, the "A Taxonomy for Self-Evolution"162section, Table 7-1 (failure-to-evolution routing), and the intervention-routing163Example. Key references named in the chapter: Gao et al. (2025) four-axis164self-evolution taxonomy; Waseem Alshikh (2025) production research on165self-evolving models, GNN-inspired methodology where "each adaptation becomes a166traceable node"; the SEAL, TPT, and Reflect-Retry-Reward learning frameworks.167This skill is the Reviewer-pattern routing front end for that section: it168classifies and routes, and the downstream frameworks execute the evolution.