This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch blog/let-there-be-chaos
in repository https://gitbox.apache.org/repos/asf/camel-website.git

commit ad12db78d9706f723db5574c61419f9a1d5dcb13
Author: Claus Ibsen <[email protected]>
AuthorDate: Mon Nov 9 22:22:45 2026 +0100

    Blog: chaos in Camel 4.24, part 2 - let there be chaos
    
    An AI explores chaos on a running integration by itself for a time budget
    (camel cmd chaos-explore), with the run of a local model on the shop of the
    chaos example: a figure of the ten minutes, the journal, and what it found.
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../11/let-there-be-chaos/chaos-exploration.svg    | 317 +++++++++++++++++++++
 .../blog/2026/11/let-there-be-chaos/featured.jpg   | Bin 0 -> 122556 bytes
 content/blog/2026/11/let-there-be-chaos/index.md   | 165 +++++++++++
 .../11/let-there-be-chaos/let-there-be-chaos.gif   | Bin 0 -> 166434 bytes
 4 files changed, 482 insertions(+)

diff --git a/content/blog/2026/11/let-there-be-chaos/chaos-exploration.svg 
b/content/blog/2026/11/let-there-be-chaos/chaos-exploration.svg
new file mode 100644
index 00000000..834e3c61
--- /dev/null
+++ b/content/blog/2026/11/let-there-be-chaos/chaos-exploration.svg
@@ -0,0 +1,317 @@
+<svg xmlns="http://www.w3.org/2000/svg"; viewBox="0 0 1200 652" width="1200" 
height="652" font-family="-apple-system, 'Segoe UI', Roboto, Helvetica, Arial, 
sans-serif" role="img" aria-label="Timeline of a ten minute chaos exploration 
of the shop integration: ten experiments, one failed; refunds lost 5 messages 
on the same payment fault that orders survived">
+<rect width="1200" height="652" fill="#fcfcfb"/>
+<text x="24.0" y="34.0" font-size="19" fill="#0b0b0b" font-weight="600" 
text-anchor="start">Ten minutes of chaos: what the AI tried on the shop, and 
what each route did</text>
+<text x="24.0" y="56.0" font-size="13" fill="#52514e" font-weight="normal" 
text-anchor="start">10 experiments chosen by a local model (qwen3.6:35b-mlx), 
one at a time, within a 10 minute budget</text>
+<line x1="96" y1="114" x2="1176" y2="114" stroke="#e4e3df" stroke-width="1"/>
+<line x1="96.0" y1="114" x2="96.0" y2="118" stroke="#8a8984"/>
+<text x="96.0" y="131.0" font-size="10" fill="#8a8984" font-weight="normal" 
text-anchor="middle">0 min</text>
+<line x1="204.0" y1="114" x2="204.0" y2="118" stroke="#8a8984"/>
+<text x="204.0" y="131.0" font-size="10" fill="#8a8984" font-weight="normal" 
text-anchor="middle">1 min</text>
+<line x1="312.0" y1="114" x2="312.0" y2="118" stroke="#8a8984"/>
+<text x="312.0" y="131.0" font-size="10" fill="#8a8984" font-weight="normal" 
text-anchor="middle">2 min</text>
+<line x1="420.0" y1="114" x2="420.0" y2="118" stroke="#8a8984"/>
+<text x="420.0" y="131.0" font-size="10" fill="#8a8984" font-weight="normal" 
text-anchor="middle">3 min</text>
+<line x1="528.0" y1="114" x2="528.0" y2="118" stroke="#8a8984"/>
+<text x="528.0" y="131.0" font-size="10" fill="#8a8984" font-weight="normal" 
text-anchor="middle">4 min</text>
+<line x1="636.0" y1="114" x2="636.0" y2="118" stroke="#8a8984"/>
+<text x="636.0" y="131.0" font-size="10" fill="#8a8984" font-weight="normal" 
text-anchor="middle">5 min</text>
+<line x1="744.0" y1="114" x2="744.0" y2="118" stroke="#8a8984"/>
+<text x="744.0" y="131.0" font-size="10" fill="#8a8984" font-weight="normal" 
text-anchor="middle">6 min</text>
+<line x1="852.0" y1="114" x2="852.0" y2="118" stroke="#8a8984"/>
+<text x="852.0" y="131.0" font-size="10" fill="#8a8984" font-weight="normal" 
text-anchor="middle">7 min</text>
+<line x1="960.0" y1="114" x2="960.0" y2="118" stroke="#8a8984"/>
+<text x="960.0" y="131.0" font-size="10" fill="#8a8984" font-weight="normal" 
text-anchor="middle">8 min</text>
+<line x1="1068.0" y1="114" x2="1068.0" y2="118" stroke="#8a8984"/>
+<text x="1068.0" y="131.0" font-size="10" fill="#8a8984" font-weight="normal" 
text-anchor="middle">9 min</text>
+<line x1="1176.0" y1="114" x2="1176.0" y2="118" stroke="#8a8984"/>
+<text x="1176.0" y="131.0" font-size="10" fill="#8a8984" font-weight="normal" 
text-anchor="middle">10 min</text>
+<text x="84.0" y="107.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="end">when</text>
+<rect x="142.3" y="96" width="74.2" height="16" rx="3" 
fill="#0ca30c"><title>experiment 1: PASS, 0:26 to 1:07</title></rect>
+<path d="M179.4,136 C179.4,150 150.0,144 150.0,158" fill="none" 
stroke="#e4e3df" stroke-width="1.5"/>
+<rect x="223.9" y="96" width="74.2" height="16" rx="3" 
fill="#0ca30c"><title>experiment 2: PASS, 1:11 to 1:52</title></rect>
+<path d="M261.0,136 C261.0,150 258.0,144 258.0,158" fill="none" 
stroke="#e4e3df" stroke-width="1.5"/>
+<rect x="307.3" y="96" width="11.1" height="16" rx="3" 
fill="#d03b3b"><title>experiment 3: FAIL, 1:57 to 2:04</title></rect>
+<path d="M312.9,136 C312.9,150 366.0,144 366.0,158" fill="none" 
stroke="#e4e3df" stroke-width="1.5"/>
+<rect x="348.1" y="96" width="74.2" height="16" rx="3" 
fill="#0ca30c"><title>experiment 4: PASS, 2:20 to 3:01</title></rect>
+<path d="M385.2,136 C385.2,150 474.0,144 474.0,158" fill="none" 
stroke="#e4e3df" stroke-width="1.5"/>
+<rect x="431.5" y="96" width="74.2" height="16" rx="3" 
fill="#0ca30c"><title>experiment 5: PASS, 3:06 to 3:48</title></rect>
+<path d="M468.6,136 C468.6,150 582.0,144 582.0,158" fill="none" 
stroke="#e4e3df" stroke-width="1.5"/>
+<rect x="515.0" y="96" width="163.4" height="16" rx="3" 
fill="#a3a29c"><title>experiment 6: INCONCLUSIVE, 3:53 to 5:24</title></rect>
+<path d="M596.7,136 C596.7,150 690.0,144 690.0,158" fill="none" 
stroke="#e4e3df" stroke-width="1.5"/>
+<rect x="687.6" y="96" width="165.2" height="16" rx="3" 
fill="#0ca30c"><title>experiment 7: PASS, 5:29 to 7:00</title></rect>
+<path d="M770.2,136 C770.2,150 798.0,144 798.0,158" fill="none" 
stroke="#e4e3df" stroke-width="1.5"/>
+<rect x="863.9" y="96" width="74.3" height="16" rx="3" 
fill="#0ca30c"><title>experiment 8: PASS, 7:07 to 7:48</title></rect>
+<path d="M901.0,136 C901.0,150 906.0,144 906.0,158" fill="none" 
stroke="#e4e3df" stroke-width="1.5"/>
+<rect x="949.3" y="96" width="74.2" height="16" rx="3" 
fill="#0ca30c"><title>experiment 9: PASS, 7:54 to 8:35</title></rect>
+<path d="M986.4,136 C986.4,150 1014.0,144 1014.0,158" fill="none" 
stroke="#e4e3df" stroke-width="1.5"/>
+<rect x="1032.7" y="96" width="74.3" height="16" rx="3" 
fill="#0ca30c"><title>experiment 10: PASS, 8:40 to 9:22</title></rect>
+<path d="M1069.9,136 C1069.9,150 1122.0,144 1122.0,158" fill="none" 
stroke="#e4e3df" stroke-width="1.5"/>
+<line x1="1112.6" y1="92" x2="1112.6" y2="114" stroke="#52514e" 
stroke-dasharray="2 2"/>
+<text x="1108.6" y="90.0" font-size="10" fill="#52514e" font-weight="normal" 
text-anchor="end">report</text>
+<circle cx="120.0" cy="174" r="11" fill="#0ca30c"/>
+<text x="120.0" y="178.5" font-size="13" fill="#ffffff" font-weight="700" 
text-anchor="middle">✓</text>
+<text x="136.0" y="172.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="start">#1</text>
+<text x="136.0" y="185.0" font-size="11" fill="#0b0b0b" font-weight="600" 
text-anchor="start">PASS</text>
+<text x="150.0" y="206.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="middle">payment answers</text>
+<text x="150.0" y="220.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="middle">503, 25%</text>
+<circle cx="228.0" cy="174" r="11" fill="#0ca30c"/>
+<text x="228.0" y="178.5" font-size="13" fill="#ffffff" font-weight="700" 
text-anchor="middle">✓</text>
+<text x="244.0" y="172.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="start">#2</text>
+<text x="244.0" y="185.0" font-size="11" fill="#0b0b0b" font-weight="600" 
text-anchor="start">PASS</text>
+<text x="258.0" y="206.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="middle">shipping route</text>
+<text x="258.0" y="220.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="middle">fails, 20%</text>
+<circle cx="336.0" cy="174" r="11" fill="#d03b3b"/>
+<text x="336.0" y="178.5" font-size="13" fill="#ffffff" font-weight="700" 
text-anchor="middle">✗</text>
+<text x="352.0" y="172.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="start">#3</text>
+<text x="352.0" y="185.0" font-size="11" fill="#0b0b0b" font-weight="600" 
text-anchor="start">FAIL</text>
+<text x="366.0" y="206.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="middle">payment answers</text>
+<text x="366.0" y="220.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="middle">503, 25%</text>
+<circle cx="444.0" cy="174" r="11" fill="#0ca30c"/>
+<text x="444.0" y="178.5" font-size="13" fill="#ffffff" font-weight="700" 
text-anchor="middle">✓</text>
+<text x="460.0" y="172.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="start">#4</text>
+<text x="460.0" y="185.0" font-size="11" fill="#0b0b0b" font-weight="600" 
text-anchor="start">PASS</text>
+<text x="474.0" y="206.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="middle">payment times</text>
+<text x="474.0" y="220.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="middle">out (5s), 10%</text>
+<circle cx="552.0" cy="174" r="11" fill="#0ca30c"/>
+<text x="552.0" y="178.5" font-size="13" fill="#ffffff" font-weight="700" 
text-anchor="middle">✓</text>
+<text x="568.0" y="172.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="start">#5</text>
+<text x="568.0" y="185.0" font-size="11" fill="#0b0b0b" font-weight="600" 
text-anchor="start">PASS</text>
+<text x="582.0" y="206.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="middle">payment gets</text>
+<text x="582.0" y="220.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="middle">duplicates, 10%</text>
+<circle cx="660.0" cy="174" r="11" fill="#a3a29c"/>
+<text x="660.0" y="178.5" font-size="13" fill="#ffffff" font-weight="700" 
text-anchor="middle">?</text>
+<text x="676.0" y="172.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="start">#6</text>
+<text x="676.0" y="185.0" font-size="11" fill="#0b0b0b" font-weight="600" 
text-anchor="start">UNDECIDED</text>
+<text x="690.0" y="206.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="middle">payment down,</text>
+<text x="690.0" y="220.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="middle">dead letter fails</text>
+<circle cx="768.0" cy="174" r="11" fill="#0ca30c"/>
+<text x="768.0" y="178.5" font-size="13" fill="#ffffff" font-weight="700" 
text-anchor="middle">✓</text>
+<text x="784.0" y="172.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="start">#7</text>
+<text x="784.0" y="185.0" font-size="11" fill="#0b0b0b" font-weight="600" 
text-anchor="start">PASS</text>
+<text x="818.4" y="185.0" font-size="11" fill="#d03b3b" font-weight="700" 
text-anchor="start">b</text>
+<text x="798.0" y="206.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="middle">the same,</text>
+<text x="798.0" y="220.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="middle">waits longer</text>
+<circle cx="876.0" cy="174" r="11" fill="#0ca30c"/>
+<text x="876.0" y="178.5" font-size="13" fill="#ffffff" font-weight="700" 
text-anchor="middle">✓</text>
+<text x="892.0" y="172.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="start">#8</text>
+<text x="892.0" y="185.0" font-size="11" fill="#0b0b0b" font-weight="600" 
text-anchor="start">PASS</text>
+<text x="906.0" y="206.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="middle">parked file</text>
+<text x="906.0" y="220.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="middle">write fails, 25%</text>
+<circle cx="984.0" cy="174" r="11" fill="#0ca30c"/>
+<text x="984.0" y="178.5" font-size="13" fill="#ffffff" font-weight="700" 
text-anchor="middle">✓</text>
+<text x="1000.0" y="172.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="start">#9</text>
+<text x="1000.0" y="185.0" font-size="11" fill="#0b0b0b" font-weight="600" 
text-anchor="start">PASS</text>
+<text x="1034.4" y="185.0" font-size="11" fill="#d03b3b" font-weight="700" 
text-anchor="start">a</text>
+<text x="1014.0" y="206.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="middle">payment times</text>
+<text x="1014.0" y="220.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="middle">out (5s), 10%</text>
+<circle cx="1092.0" cy="174" r="11" fill="#0ca30c"/>
+<text x="1092.0" y="178.5" font-size="13" fill="#ffffff" font-weight="700" 
text-anchor="middle">✓</text>
+<text x="1108.0" y="172.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="start">#10</text>
+<text x="1108.0" y="185.0" font-size="11" fill="#0b0b0b" font-weight="600" 
text-anchor="start">PASS</text>
+<text x="1142.4" y="185.0" font-size="11" fill="#d03b3b" font-weight="700" 
text-anchor="start">c</text>
+<text x="1122.0" y="206.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="middle">payment route</text>
+<text x="1122.0" y="220.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="middle">fails, 5%</text>
+<text x="84.0" y="261.0" font-size="13" fill="#0b0b0b" font-weight="600" 
text-anchor="end">orders</text>
+<g><title>experiment 1, orders: 41 completed, 0 failed, 11 redeliveries</title>
+<rect x="98.0" y="236" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<text x="150.0" y="255.0" font-size="12" fill="#0b0b0b" font-weight="normal" 
text-anchor="middle">41 ok</text>
+<text x="150.0" y="269.0" font-size="10" fill="#52514e" font-weight="normal" 
text-anchor="middle">11 retried</text>
+</g>
+<g><title>experiment 2, orders: 41 completed, 0 failed, 0 redeliveries</title>
+<rect x="206.0" y="236" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<text x="258.0" y="261.0" font-size="11" fill="#8a8984" font-weight="normal" 
text-anchor="middle">41 ok</text>
+</g>
+<g><title>experiment 3, orders: 6 completed, 0 failed, 3 redeliveries</title>
+<rect x="314.0" y="236" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<text x="366.0" y="255.0" font-size="12" fill="#0b0b0b" font-weight="normal" 
text-anchor="middle">6 ok</text>
+<text x="366.0" y="269.0" font-size="10" fill="#52514e" font-weight="normal" 
text-anchor="middle">3 retried</text>
+</g>
+<g><title>experiment 4, orders: 32 completed, 0 failed, 2 redeliveries</title>
+<rect x="422.0" y="236" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<text x="474.0" y="255.0" font-size="12" fill="#0b0b0b" font-weight="normal" 
text-anchor="middle">32 ok</text>
+<text x="474.0" y="269.0" font-size="10" fill="#52514e" font-weight="normal" 
text-anchor="middle">2 retried</text>
+</g>
+<g><title>experiment 5, orders: 41 completed, 0 failed, 0 redeliveries</title>
+<rect x="530.0" y="236" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<text x="582.0" y="261.0" font-size="11" fill="#8a8984" font-weight="normal" 
text-anchor="middle">41 ok</text>
+</g>
+<g><title>experiment 6, orders: 90 completed, 0 failed, 118 redeliveries, 58 
lost at the dead letter channel</title>
+<rect x="638.0" y="236" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<rect x="638.0" y="236" width="4" height="42" rx="2" fill="#ec835a"/>
+<text x="692.0" y="255.0" font-size="13" fill="#0b0b0b" font-weight="700" 
text-anchor="middle">58 lost</text>
+<text x="692.0" y="269.0" font-size="10" fill="#52514e" font-weight="normal" 
text-anchor="middle">at dead letter</text>
+</g>
+<g><title>experiment 7, orders: 90 completed, 0 failed, 117 redeliveries, 58 
lost at the dead letter channel</title>
+<rect x="746.0" y="236" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<rect x="746.0" y="236" width="4" height="42" rx="2" fill="#ec835a"/>
+<text x="800.0" y="255.0" font-size="13" fill="#0b0b0b" font-weight="700" 
text-anchor="middle">58 lost</text>
+<text x="800.0" y="269.0" font-size="10" fill="#52514e" font-weight="normal" 
text-anchor="middle">at dead letter</text>
+</g>
+<g><title>experiment 8, orders: 41 completed, 0 failed, 0 redeliveries</title>
+<rect x="854.0" y="236" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<text x="906.0" y="261.0" font-size="11" fill="#8a8984" font-weight="normal" 
text-anchor="middle">41 ok</text>
+</g>
+<g><title>experiment 9, orders: 36 completed, 0 failed, 1 redeliveries</title>
+<rect x="962.0" y="236" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<text x="1014.0" y="255.0" font-size="12" fill="#0b0b0b" font-weight="normal" 
text-anchor="middle">36 ok</text>
+<text x="1014.0" y="269.0" font-size="10" fill="#52514e" font-weight="normal" 
text-anchor="middle">1 retried</text>
+</g>
+<g><title>experiment 10, orders: 41 completed, 0 failed, 0 redeliveries</title>
+<rect x="1070.0" y="236" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<text x="1122.0" y="261.0" font-size="11" fill="#8a8984" font-weight="normal" 
text-anchor="middle">41 ok</text>
+</g>
+<text x="84.0" y="307.0" font-size="13" fill="#0b0b0b" font-weight="600" 
text-anchor="end">refunds</text>
+<rect x="98.0" y="282" width="104.0" height="42" rx="4" fill="none" 
stroke="#e4e3df" stroke-dasharray="3 3"/>
+<text x="150.0" y="307.0" font-size="10" fill="#8a8984" font-weight="normal" 
text-anchor="middle">no traffic</text>
+<rect x="206.0" y="282" width="104.0" height="42" rx="4" fill="none" 
stroke="#e4e3df" stroke-dasharray="3 3"/>
+<text x="258.0" y="307.0" font-size="10" fill="#8a8984" font-weight="normal" 
text-anchor="middle">no traffic</text>
+<g><title>experiment 3, refunds: 15 completed, 5 failed, 0 redeliveries</title>
+<rect x="314.0" y="282" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<rect x="314.0" y="282" width="4" height="42" rx="2" fill="#d03b3b"/>
+<text x="368.0" y="301.0" font-size="13" fill="#0b0b0b" font-weight="700" 
text-anchor="middle">5 failed</text>
+<text x="368.0" y="315.0" font-size="10" fill="#52514e" font-weight="normal" 
text-anchor="middle">gone</text>
+</g>
+<rect x="422.0" y="282" width="104.0" height="42" rx="4" fill="none" 
stroke="#e4e3df" stroke-dasharray="3 3"/>
+<text x="474.0" y="307.0" font-size="10" fill="#8a8984" font-weight="normal" 
text-anchor="middle">no traffic</text>
+<g><title>experiment 5, refunds: 20 completed, 0 failed, 0 redeliveries</title>
+<rect x="530.0" y="282" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<text x="582.0" y="307.0" font-size="11" fill="#8a8984" font-weight="normal" 
text-anchor="middle">20 ok</text>
+</g>
+<rect x="638.0" y="282" width="104.0" height="42" rx="4" fill="none" 
stroke="#e4e3df" stroke-dasharray="3 3"/>
+<text x="690.0" y="307.0" font-size="10" fill="#8a8984" font-weight="normal" 
text-anchor="middle">no traffic</text>
+<rect x="746.0" y="282" width="104.0" height="42" rx="4" fill="none" 
stroke="#e4e3df" stroke-dasharray="3 3"/>
+<text x="798.0" y="307.0" font-size="10" fill="#8a8984" font-weight="normal" 
text-anchor="middle">no traffic</text>
+<rect x="854.0" y="282" width="104.0" height="42" rx="4" fill="none" 
stroke="#e4e3df" stroke-dasharray="3 3"/>
+<text x="906.0" y="307.0" font-size="10" fill="#8a8984" font-weight="normal" 
text-anchor="middle">no traffic</text>
+<g><title>experiment 9, refunds: 18 completed, 2 failed, 0 redeliveries</title>
+<rect x="962.0" y="282" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<rect x="962.0" y="282" width="4" height="42" rx="2" fill="#d03b3b"/>
+<text x="1016.0" y="301.0" font-size="13" fill="#0b0b0b" font-weight="700" 
text-anchor="middle">2 failed</text>
+<text x="1016.0" y="315.0" font-size="10" fill="#52514e" font-weight="normal" 
text-anchor="middle">gone</text>
+</g>
+<rect x="1070.0" y="282" width="104.0" height="42" rx="4" fill="none" 
stroke="#e4e3df" stroke-dasharray="3 3"/>
+<text x="1122.0" y="307.0" font-size="10" fill="#8a8984" font-weight="normal" 
text-anchor="middle">no traffic</text>
+<text x="84.0" y="353.0" font-size="13" fill="#0b0b0b" font-weight="600" 
text-anchor="end">shipping</text>
+<g><title>experiment 1, shipping: 41 completed, 0 failed, 0 
redeliveries</title>
+<rect x="98.0" y="328" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<text x="150.0" y="353.0" font-size="11" fill="#8a8984" font-weight="normal" 
text-anchor="middle">41 ok</text>
+</g>
+<g><title>experiment 2, shipping: 41 completed, 0 failed, 5 
redeliveries</title>
+<rect x="206.0" y="328" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<text x="258.0" y="347.0" font-size="12" fill="#0b0b0b" font-weight="normal" 
text-anchor="middle">41 ok</text>
+<text x="258.0" y="361.0" font-size="10" fill="#52514e" font-weight="normal" 
text-anchor="middle">5 retried</text>
+</g>
+<g><title>experiment 3, shipping: 6 completed, 0 failed, 0 redeliveries</title>
+<rect x="314.0" y="328" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<text x="366.0" y="353.0" font-size="11" fill="#8a8984" font-weight="normal" 
text-anchor="middle">6 ok</text>
+</g>
+<g><title>experiment 4, shipping: 32 completed, 0 failed, 0 
redeliveries</title>
+<rect x="422.0" y="328" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<text x="474.0" y="353.0" font-size="11" fill="#8a8984" font-weight="normal" 
text-anchor="middle">32 ok</text>
+</g>
+<g><title>experiment 5, shipping: 41 completed, 0 failed, 0 
redeliveries</title>
+<rect x="530.0" y="328" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<text x="582.0" y="353.0" font-size="11" fill="#8a8984" font-weight="normal" 
text-anchor="middle">41 ok</text>
+</g>
+<g><title>experiment 6, shipping: 32 completed, 0 failed, 0 
redeliveries</title>
+<rect x="638.0" y="328" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<text x="690.0" y="353.0" font-size="11" fill="#8a8984" font-weight="normal" 
text-anchor="middle">32 ok</text>
+</g>
+<g><title>experiment 7, shipping: 32 completed, 0 failed, 0 
redeliveries</title>
+<rect x="746.0" y="328" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<text x="798.0" y="353.0" font-size="11" fill="#8a8984" font-weight="normal" 
text-anchor="middle">32 ok</text>
+</g>
+<g><title>experiment 8, shipping: 41 completed, 0 failed, 0 
redeliveries</title>
+<rect x="854.0" y="328" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<text x="906.0" y="353.0" font-size="11" fill="#8a8984" font-weight="normal" 
text-anchor="middle">41 ok</text>
+</g>
+<g><title>experiment 9, shipping: 36 completed, 0 failed, 0 
redeliveries</title>
+<rect x="962.0" y="328" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<text x="1014.0" y="353.0" font-size="11" fill="#8a8984" font-weight="normal" 
text-anchor="middle">36 ok</text>
+</g>
+<g><title>experiment 10, shipping: 41 completed, 0 failed, 0 
redeliveries</title>
+<rect x="1070.0" y="328" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<text x="1122.0" y="353.0" font-size="11" fill="#8a8984" font-weight="normal" 
text-anchor="middle">41 ok</text>
+</g>
+<text x="84.0" y="399.0" font-size="13" fill="#0b0b0b" font-weight="600" 
text-anchor="end">parked</text>
+<rect x="98.0" y="374" width="104.0" height="42" rx="4" fill="none" 
stroke="#e4e3df" stroke-dasharray="3 3"/>
+<text x="150.0" y="399.0" font-size="10" fill="#8a8984" font-weight="normal" 
text-anchor="middle">no traffic</text>
+<rect x="206.0" y="374" width="104.0" height="42" rx="4" fill="none" 
stroke="#e4e3df" stroke-dasharray="3 3"/>
+<text x="258.0" y="399.0" font-size="10" fill="#8a8984" font-weight="normal" 
text-anchor="middle">no traffic</text>
+<rect x="314.0" y="374" width="104.0" height="42" rx="4" fill="none" 
stroke="#e4e3df" stroke-dasharray="3 3"/>
+<text x="366.0" y="399.0" font-size="10" fill="#8a8984" font-weight="normal" 
text-anchor="middle">no traffic</text>
+<rect x="422.0" y="374" width="104.0" height="42" rx="4" fill="none" 
stroke="#e4e3df" stroke-dasharray="3 3"/>
+<text x="474.0" y="399.0" font-size="10" fill="#8a8984" font-weight="normal" 
text-anchor="middle">no traffic</text>
+<rect x="530.0" y="374" width="104.0" height="42" rx="4" fill="none" 
stroke="#e4e3df" stroke-dasharray="3 3"/>
+<text x="582.0" y="399.0" font-size="10" fill="#8a8984" font-weight="normal" 
text-anchor="middle">no traffic</text>
+<rect x="638.0" y="374" width="104.0" height="42" rx="4" fill="none" 
stroke="#e4e3df" stroke-dasharray="3 3"/>
+<text x="690.0" y="399.0" font-size="10" fill="#8a8984" font-weight="normal" 
text-anchor="middle">no traffic</text>
+<rect x="746.0" y="374" width="104.0" height="42" rx="4" fill="none" 
stroke="#e4e3df" stroke-dasharray="3 3"/>
+<text x="798.0" y="399.0" font-size="10" fill="#8a8984" font-weight="normal" 
text-anchor="middle">no traffic</text>
+<g><title>experiment 8, parked: 20 completed, 0 failed, 0 redeliveries</title>
+<rect x="854.0" y="374" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<text x="906.0" y="399.0" font-size="11" fill="#8a8984" font-weight="normal" 
text-anchor="middle">20 ok</text>
+</g>
+<rect x="962.0" y="374" width="104.0" height="42" rx="4" fill="none" 
stroke="#e4e3df" stroke-dasharray="3 3"/>
+<text x="1014.0" y="399.0" font-size="10" fill="#8a8984" font-weight="normal" 
text-anchor="middle">no traffic</text>
+<rect x="1070.0" y="374" width="104.0" height="42" rx="4" fill="none" 
stroke="#e4e3df" stroke-dasharray="3 3"/>
+<text x="1122.0" y="399.0" font-size="10" fill="#8a8984" font-weight="normal" 
text-anchor="middle">no traffic</text>
+<text x="84.0" y="445.0" font-size="13" fill="#0b0b0b" font-weight="600" 
text-anchor="end">payment</text>
+<g><title>experiment 1, payment: 41 completed, 0 failed, 0 redeliveries</title>
+<rect x="98.0" y="420" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<text x="150.0" y="445.0" font-size="11" fill="#8a8984" font-weight="normal" 
text-anchor="middle">41 ok</text>
+</g>
+<g><title>experiment 2, payment: 41 completed, 0 failed, 0 redeliveries</title>
+<rect x="206.0" y="420" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<text x="258.0" y="445.0" font-size="11" fill="#8a8984" font-weight="normal" 
text-anchor="middle">41 ok</text>
+</g>
+<g><title>experiment 3, payment: 21 completed, 0 failed, 0 redeliveries</title>
+<rect x="314.0" y="420" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<text x="366.0" y="445.0" font-size="11" fill="#8a8984" font-weight="normal" 
text-anchor="middle">21 ok</text>
+</g>
+<g><title>experiment 4, payment: 32 completed, 0 failed, 0 redeliveries</title>
+<rect x="422.0" y="420" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<text x="474.0" y="445.0" font-size="11" fill="#8a8984" font-weight="normal" 
text-anchor="middle">32 ok</text>
+</g>
+<g><title>experiment 5, payment: 69 completed, 0 failed, 0 redeliveries</title>
+<rect x="530.0" y="420" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<text x="582.0" y="445.0" font-size="11" fill="#8a8984" font-weight="normal" 
text-anchor="middle">69 ok</text>
+</g>
+<g><title>experiment 6, payment: 32 completed, 0 failed, 0 redeliveries</title>
+<rect x="638.0" y="420" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<text x="690.0" y="445.0" font-size="11" fill="#8a8984" font-weight="normal" 
text-anchor="middle">32 ok</text>
+</g>
+<g><title>experiment 7, payment: 32 completed, 0 failed, 0 redeliveries</title>
+<rect x="746.0" y="420" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<text x="798.0" y="445.0" font-size="11" fill="#8a8984" font-weight="normal" 
text-anchor="middle">32 ok</text>
+</g>
+<g><title>experiment 8, payment: 41 completed, 0 failed, 0 redeliveries</title>
+<rect x="854.0" y="420" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<text x="906.0" y="445.0" font-size="11" fill="#8a8984" font-weight="normal" 
text-anchor="middle">41 ok</text>
+</g>
+<g><title>experiment 9, payment: 54 completed, 0 failed, 0 redeliveries</title>
+<rect x="962.0" y="420" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<text x="1014.0" y="445.0" font-size="11" fill="#8a8984" font-weight="normal" 
text-anchor="middle">54 ok</text>
+</g>
+<g><title>experiment 10, payment: 41 completed, 0 failed, 0 
redeliveries</title>
+<rect x="1070.0" y="420" width="104.0" height="42" rx="4" fill="#f3f2ef"/>
+<text x="1122.0" y="445.0" font-size="11" fill="#8a8984" font-weight="normal" 
text-anchor="middle">41 ok</text>
+</g>
+<rect x="96.0" y="158" width="108.0" height="308" rx="7" fill="none" 
stroke="#0b0b0b" stroke-width="1.5"/>
+<rect x="312.0" y="158" width="108.0" height="308" rx="7" fill="none" 
stroke="#0b0b0b" stroke-width="1.5"/>
+<path d="M150.0,466 V482 H366.0 V466" fill="none" stroke="#0b0b0b" 
stroke-width="1.5"/>
+<text x="24.0" y="504.0" font-size="14" fill="#0b0b0b" font-weight="700" 
text-anchor="start">Same fault, two routes.</text>
+<text x="212.0" y="504.0" font-size="14" fill="#0b0b0b" font-weight="normal" 
text-anchor="start">Orders retries through its dead letter channel and loses 
none; refunds has no error handling and loses 5 of 20.</text>
+<rect x="24" y="524" width="4" height="13" rx="2" fill="#d03b3b"/>
+<text x="34.0" y="535.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="start">failed: the message is gone</text>
+<rect x="222.7" y="524" width="4" height="13" rx="2" fill="#ec835a"/>
+<text x="232.7" y="535.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="start">lost at the dead letter channel</text>
+<text x="445.8" y="535.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="start">ok: completed (retried: redelivered and then 
completed)</text>
+<text x="24.0" y="562.0" font-size="11" fill="#0b0b0b" font-weight="600" 
text-anchor="start">Read afterwards:</text>
+<text x="24.0" y="580.0" font-size="11" fill="#d03b3b" font-weight="700" 
text-anchor="start">a</text>
+<text x="38.0" y="580.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="start">The expectation measured time, so the 2 failed refunds did 
not fail the experiment (the AI saw them, but put them down to an earlier 
experiment).</text>
+<text x="24.0" y="596.0" font-size="11" fill="#d03b3b" font-weight="700" 
text-anchor="start">b</text>
+<text x="38.0" y="596.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="start">Passed in this run; it fails since CAMEL-26789, as an 
experiment now counts what the dead letter channel lost.</text>
+<text x="24.0" y="612.0" font-size="11" fill="#d03b3b" font-weight="700" 
text-anchor="start">c</text>
+<text x="38.0" y="612.0" font-size="11" fill="#52514e" font-weight="normal" 
text-anchor="start">The fault never fired: the rule matched nothing, so the 
PASS says nothing.</text>
+</svg>
\ No newline at end of file
diff --git a/content/blog/2026/11/let-there-be-chaos/featured.jpg 
b/content/blog/2026/11/let-there-be-chaos/featured.jpg
new file mode 100644
index 00000000..832ae4a2
Binary files /dev/null and 
b/content/blog/2026/11/let-there-be-chaos/featured.jpg differ
diff --git a/content/blog/2026/11/let-there-be-chaos/index.md 
b/content/blog/2026/11/let-there-be-chaos/index.md
new file mode 100644
index 00000000..c552e62d
--- /dev/null
+++ b/content/blog/2026/11/let-there-be-chaos/index.md
@@ -0,0 +1,165 @@
+---
+title: "Chaos in Camel 4.24, part 2: let there be chaos, an AI that breaks 
your routes on purpose"
+date: 2026-11-15
+draft: true
+authors: [davsclaus]
+categories: ["Camel", "Tooling", "AI"]
+keywords: ["apache camel", "chaos", "chaos engineering", "ai", "camel cli", 
"mcp", "local llm", "resilience", "camel 4.24"]
+preview: "camel-chaos lets you add faults to a running integration. Now you 
can hand the whole thing to an AI: give it ten minutes, and it tries faults by 
itself, measures what held and what broke, and comes back with a report and 
scenarios you can replay."
+---
+
+In [part 1](/blog/2026/11/camel-chaos/) you added the faults yourself: "fail a 
quarter of the payment calls",
+"fail the dead letter channel too", and then you read the report. That works, 
but it means you have to know what to
+try. With Camel 4.24 you can hand that part to an AI as well:
+
+```shell
+camel cmd chaos-explore shop --budget=10m
+```
+
+Let there be chaos. For ten minutes the AI of `camel ask` explores how the 
integration copes with faults, by
+itself. It reads what the routes do, picks a fault to try, says what should 
hold, runs the experiment, reads the
+verdict, and goes on. At the end it writes a report: what held, what broke and 
why, and a hint for each finding. The
+integration keeps running; the AI never changes your routes.
+
+![Let there be chaos](let-there-be-chaos.gif)
+
+## The shop
+
+The shop is the one from the [chaos 
example](https://github.com/apache/camel-jbang-examples/tree/main/fail-well/chaos):
+an order every second, charged at a payment service over HTTP, handed to 
shipping, with a dead letter channel that
+parks what could not be charged. We added one route: refunds arrive on Kafka 
and are paid back at the payment
+service. The refunds route has no error handling of its own. That is the kind 
of gap you want found before
+production. Kafka is stubbed (`camel run --stub=kafka`), so no broker is 
needed and nothing real is touched.
+
+```shell
+camel run * --chaos --stub=kafka --name=shop
+camel cmd chaos-explore shop --budget=10m
+```
+
+The model is qwen3.6 (35B), running locally on a laptop. No cloud, no API key.
+
+## Ten minutes, in one picture
+
+Here is the whole run. Along the top, when each experiment ran within the 
budget; below, one column per experiment,
+with what it did to each route:
+
+![Ten minutes of chaos: ten experiments, and what each did to each 
route](chaos-exploration.svg)
+
+Look at columns 1 and 3. It is the same fault both times: the payment service 
answers 503 to a quarter of the calls.
+The orders retried 11 calls through their dead letter channel, and every order 
got through. The refunds have no
+retry: 5 of the 20 failed, and they are gone.
+
+The AI did not stop at the verdict. It looked up the errors of the integration 
by itself and explained what it saw:
+
+> The refunds route failed with `HttpOperationFailedException` - it has no 
error handling for the HTTP call to
+> payment. [...] This is a real issue: the refunds route needs better error 
handling (like an onException with
+> redelivery or a dead letter channel).
+
+That is the finding, the evidence and the hint, in the AI's own words, without 
anybody telling it where to look.
+
+In another run it went for the nastier case: the payment service down, and the 
dead letter channel failing too.
+The dead letter channel then handles the orders it could not park, so they 
neither fail nor complete: they are just
+gone. That run reported "when payment returned 503 and the dead letter channel 
also failed, 2 messages were lost at
+the dead letter channel" (columns 6 and 7 above are the same experiment, 
before Camel counted those losses; more on
+that below).
+
+## The journal
+
+Every experiment goes into the journal of the exploration, with the hypothesis 
the AI wrote for it and the evidence
+for the verdict. These are the ten experiments of the run, as the AI phrased 
them:
+
+| # | Hypothesis | Expected | Verdict | Evidence |
+|---|---|---|---|---|
+| 1 | When payment returns 503, orders should retry and not lose messages | 
orders: failed ≤ 0 | PASS | 0 failed, 11 retried |
+| 2 | When shipping fails, orders should not lose the message handed off via 
seda | orders→shipping: lost ≤ 0 | PASS | 0 lost (39 in orders, 39 in shipping) 
|
+| 3 | When payment returns 503, refunds should handle errors gracefully | 
refunds: failed ≤ 0 | **FAIL** | **5 failed** |
+| 4 | When payment times out, orders should retry and complete within 
reasonable time | orders: max time ≤ 30s | PASS | max 5.5s of 31 orders |
+| 5 | When payment receives duplicates, refunds should handle them safely | 
refunds: failed ≤ 0 | PASS | 0 failed |
+| 6 | When payment fails and the dead letter channel also fails, orders should 
not lose messages entirely | orders: failed ≤ 0 | undecided | the window was 
longer than the wait |
+| 7 | The same, again with a shorter window | orders: failed ≤ 0 | PASS | 0 
failed (58 lost at the dead letter channel) |
+| 8 | When the file write fails, parked should handle the error gracefully | 
parked: failed ≤ 0 | PASS | 0 failed, 7 handled |
+| 9 | When payment times out, refunds should complete within reasonable time | 
refunds: max time ≤ 30s | PASS | max 5s (2 failed) |
+| 10 | When the payment route fails, HTTP clients should see proper error 
responses | payment: failed ≤ 0 | PASS | the fault never fired |
+
+The AI kept to its budget: with 38 seconds left it said that was not enough 
for another experiment, and finished.
+
+## One experiment per call
+
+The trick that makes this work with a small local model is that each 
experiment is a single tool call. The model
+does not juggle rules, traffic and timers; it says what it wants to know:
+
+```json
+{
+  "hypothesis": "When payment returns 503, refunds should handle errors 
gracefully",
+  "rule": "endpoint=http://localhost:8080/payment error status=503 rate=0.25 
until=30s expect=refunds:failed<=0 within=40s",
+  "feed": "refunds", "body": "{\"refundId\": \"R-1\"}", "repeat": 20, 
"interval": "100..300"
+}
+```
+
+Camel adds the rule, sends the 20 refunds to the stubbed Kafka topic, waits 
until the expectation is decided, removes
+the rule, and answers with the verdict, the counts per route and the traffic. 
You can do exactly the same by hand,
+without any AI:
+
+```shell
+camel cmd chaos-explore-start --budget=10m
+camel cmd chaos-experiment --hypothesis='a failed refund is retried, not lost' 
\
+    --rule='endpoint=http://localhost:8080/payment error status=503 rate=0.25 
until=30s expect=refunds:failed<=0 within=40s' \
+    --feed=refunds --body='{"refundId": "R-1"}' --repeat=20 --interval=100..300
+camel cmd chaos-explore-finish
+```
+
+## Safe by construction
+
+You say yes once, by starting the exploration, and Camel holds the line from 
there, whatever the model does:
+
+- Chaos only runs in development (profile `dev`), never with `prod`.
+- The exploration has a deadline (10 minutes by default, 2 hours at most). 
Every rule ends at the deadline at the
+  latest, and at the deadline all rules are removed, even if the AI has 
crashed or lost its context.
+- Remote systems are stubbed, so the experiments do not reach your real Kafka 
or payment provider.
+- The AI only adds faults and sends test messages to the routes; it does not 
edit your project.
+
+## What you keep
+
+Everything ends up in `test/chaos`, which `camel run` and `camel export` leave 
alone:
+
+- `test/chaos/reports/explore-<time>.md`: the report of the AI and the journal 
of all experiments, and a `.json` next
+  to it for tools. The picture above is drawn from that `.json`.
+- `test/chaos/explore-<time>-<n>.chaos`: each experiment that failed, as a 
scenario:
+
+```text
+# From the chaos exploration of shop on 2026-11-09 18:14, experiment 3: FAIL
+# hypothesis: When payment returns 503, refunds should handle errors gracefully
+# expect refunds:failed<=0: unmet, 5 failed
+seed=-7420423075154098588
+endpoint=http://localhost:8080/payment error status=503 rate=0.25 until=30s 
expect=refunds:failed<=0 within=40s
+```
+
+Load it again (`camel cmd chaos-load`, or `camel run * --chaos=...`), send 
some refunds, and the verdict is FAIL
+again, until you fix the route. Then keep it as a test that gates your 
pipeline.
+
+## Honest about the model
+
+A small local model is not a chaos engineer, and the picture shows where it 
slipped (the red letters):
+
+- **a**: In experiment 9 it measured time, not failures, so 2 failed refunds 
passed. It saw them, and put them down
+  to an earlier experiment.
+- **b**: Experiments 6 and 7 passed while orders were lost at the dead letter 
channel. That one was on Camel, not
+  on the model: the experiment did not count those losses yet. The run showed 
it, and it is fixed: such an experiment
+  now fails.
+- **c**: In experiment 10 the fault never fired, so its PASS says nothing.
+
+Our earlier runs were rougher: thresholds such as `failed<=5` that hide what 
was lost, messages fed to an endpoint
+no route reads from, rules that matched nothing. Each of those made an 
experiment that said nothing, so we made
+Camel catch them: an experiment refuses a feed that reaches no route (and 
lists the routes it can feed), warns when
+a rule matches nothing, waits until its expectations can decide, and counts 
what the dead letter channel lost. The
+model reads why and corrects itself. A bigger model makes better choices, and 
the journal always carries the
+evidence, so you can judge each finding yourself.
+
+## Any agent
+
+The same playbook is an MCP prompt, `camel_chaos_explore`, so Claude Code, or 
any agent with the Camel MCP server,
+can run the same loop with the `camel_runtime_chaos_*` tools. And because each 
exploration is bound to one running
+integration, you can imagine where this goes: several agents, each with its 
own copy of the integration, exploring
+in parallel for an hour, and one agent that combines their reports.
+
+Try it with Camel 4.24, and tell us what it found in your routes.
diff --git a/content/blog/2026/11/let-there-be-chaos/let-there-be-chaos.gif 
b/content/blog/2026/11/let-there-be-chaos/let-there-be-chaos.gif
new file mode 100644
index 00000000..cb7fa736
Binary files /dev/null and 
b/content/blog/2026/11/let-there-be-chaos/let-there-be-chaos.gif differ

Reply via email to