fix(dashboard): harden generation against common failures

This commit is contained in:
2026-08-24 11:10:39 +02:00
parent 12a0eca44a
commit f5b1ade48c
3 changed files with 263 additions and 418 deletions
+176 -402
View File
@@ -1,7 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1400" height="1850" viewBox="0 0 1400 1850" font-family="sans-serif"> <svg xmlns="http://www.w3.org/2000/svg" width="1400" height="1850" viewBox="0 0 1400 1850" font-family="sans-serif">
<rect width="1400" height="1850" fill="white"/> <rect width="1400" height="1850" fill="white"/>
<text x="700" y="32" text-anchor="middle" font-size="21" font-weight="bold">SAC-LSTM campaign dashboard - live run (current only)</text> <text x="700" y="32" text-anchor="middle" font-size="21" font-weight="bold">SAC-LSTM campaign dashboard - live run (current only)</text>
<text x="700" y="56" text-anchor="middle" font-size="12" fill="#555">generated 2026-08-24 10:18:35 - auto-reloads every 60 s (open this file in Chrome)</text> <text x="700" y="56" text-anchor="middle" font-size="12" fill="#555">generated 2026-08-24 11:10:31 - auto-reloads every 60 s (open this file in Chrome)</text>
<text x="70" y="100" font-size="15" font-weight="bold">Test matches - win % vs opponents</text> <text x="70" y="100" font-size="15" font-weight="bold">Test matches - win % vs opponents</text>
<text x="70" y="115" font-size="11" fill="#555">raw dots = single test matches, thick = rolling-mean-10</text> <text x="70" y="115" font-size="11" fill="#555">raw dots = single test matches, thick = rolling-mean-10</text>
<text x="70" y="133" font-size="12" font-style="italic" fill="#555">What: How often the bot wins against each opponent in test battles.</text> <text x="70" y="133" font-size="12" font-style="italic" fill="#555">What: How often the bot wins against each opponent in test battles.</text>
@@ -17,74 +17,14 @@
<line x1="70" y1="784" x2="70" y2="184" stroke="black"/> <line x1="70" y1="784" x2="70" y2="184" stroke="black"/>
<line x1="70.0" y1="784" x2="70.0" y2="788" stroke="black"/> <line x1="70.0" y1="784" x2="70.0" y2="788" stroke="black"/>
<text x="70.0" y="801" text-anchor="middle" font-size="11">1</text> <text x="70.0" y="801" text-anchor="middle" font-size="11">1</text>
<line x1="88.4" y1="784" x2="88.4" y2="788" stroke="black"/> <line x1="226.8" y1="784" x2="226.8" y2="788" stroke="black"/>
<text x="88.4" y="801" text-anchor="middle" font-size="11">2</text> <text x="226.8" y="801" text-anchor="middle" font-size="11">2</text>
<line x1="106.9" y1="784" x2="106.9" y2="788" stroke="black"/>
<text x="106.9" y="801" text-anchor="middle" font-size="11">3</text>
<line x1="125.3" y1="784" x2="125.3" y2="788" stroke="black"/>
<text x="125.3" y="801" text-anchor="middle" font-size="11">4</text>
<line x1="143.8" y1="784" x2="143.8" y2="788" stroke="black"/>
<text x="143.8" y="801" text-anchor="middle" font-size="11">5</text>
<line x1="162.2" y1="784" x2="162.2" y2="788" stroke="black"/>
<text x="162.2" y="801" text-anchor="middle" font-size="11">6</text>
<line x1="180.6" y1="784" x2="180.6" y2="788" stroke="black"/>
<text x="180.6" y="801" text-anchor="middle" font-size="11">7</text>
<line x1="199.1" y1="784" x2="199.1" y2="788" stroke="black"/>
<text x="199.1" y="801" text-anchor="middle" font-size="11">8</text>
<line x1="217.5" y1="784" x2="217.5" y2="788" stroke="black"/>
<text x="217.5" y="801" text-anchor="middle" font-size="11">9</text>
<line x1="236.0" y1="784" x2="236.0" y2="788" stroke="black"/>
<text x="236.0" y="801" text-anchor="middle" font-size="11">10</text>
<line x1="254.4" y1="784" x2="254.4" y2="788" stroke="black"/>
<text x="254.4" y="801" text-anchor="middle" font-size="11">11</text>
<line x1="272.9" y1="784" x2="272.9" y2="788" stroke="black"/>
<text x="272.9" y="801" text-anchor="middle" font-size="11">12</text>
<line x1="291.3" y1="784" x2="291.3" y2="788" stroke="black"/>
<text x="291.3" y="801" text-anchor="middle" font-size="11">13</text>
<line x1="309.7" y1="784" x2="309.7" y2="788" stroke="black"/>
<text x="309.7" y="801" text-anchor="middle" font-size="11">14</text>
<line x1="328.2" y1="784" x2="328.2" y2="788" stroke="black"/>
<text x="328.2" y="801" text-anchor="middle" font-size="11">15</text>
<line x1="346.6" y1="784" x2="346.6" y2="788" stroke="black"/>
<text x="346.6" y="801" text-anchor="middle" font-size="11">16</text>
<line x1="365.1" y1="784" x2="365.1" y2="788" stroke="black"/>
<text x="365.1" y="801" text-anchor="middle" font-size="11">17</text>
<line x1="383.5" y1="784" x2="383.5" y2="788" stroke="black"/> <line x1="383.5" y1="784" x2="383.5" y2="788" stroke="black"/>
<text x="383.5" y="801" text-anchor="middle" font-size="11">18</text> <text x="383.5" y="801" text-anchor="middle" font-size="11">3</text>
<line x1="401.9" y1="784" x2="401.9" y2="788" stroke="black"/> <line x1="540.2" y1="784" x2="540.2" y2="788" stroke="black"/>
<text x="401.9" y="801" text-anchor="middle" font-size="11">19</text> <text x="540.2" y="801" text-anchor="middle" font-size="11">4</text>
<line x1="420.4" y1="784" x2="420.4" y2="788" stroke="black"/>
<text x="420.4" y="801" text-anchor="middle" font-size="11">20</text>
<line x1="438.8" y1="784" x2="438.8" y2="788" stroke="black"/>
<text x="438.8" y="801" text-anchor="middle" font-size="11">21</text>
<line x1="457.3" y1="784" x2="457.3" y2="788" stroke="black"/>
<text x="457.3" y="801" text-anchor="middle" font-size="11">22</text>
<line x1="475.7" y1="784" x2="475.7" y2="788" stroke="black"/>
<text x="475.7" y="801" text-anchor="middle" font-size="11">23</text>
<line x1="494.1" y1="784" x2="494.1" y2="788" stroke="black"/>
<text x="494.1" y="801" text-anchor="middle" font-size="11">24</text>
<line x1="512.6" y1="784" x2="512.6" y2="788" stroke="black"/>
<text x="512.6" y="801" text-anchor="middle" font-size="11">25</text>
<line x1="531.0" y1="784" x2="531.0" y2="788" stroke="black"/>
<text x="531.0" y="801" text-anchor="middle" font-size="11">26</text>
<line x1="549.5" y1="784" x2="549.5" y2="788" stroke="black"/>
<text x="549.5" y="801" text-anchor="middle" font-size="11">27</text>
<line x1="567.9" y1="784" x2="567.9" y2="788" stroke="black"/>
<text x="567.9" y="801" text-anchor="middle" font-size="11">28</text>
<line x1="586.4" y1="784" x2="586.4" y2="788" stroke="black"/>
<text x="586.4" y="801" text-anchor="middle" font-size="11">29</text>
<line x1="604.8" y1="784" x2="604.8" y2="788" stroke="black"/>
<text x="604.8" y="801" text-anchor="middle" font-size="11">30</text>
<line x1="623.2" y1="784" x2="623.2" y2="788" stroke="black"/>
<text x="623.2" y="801" text-anchor="middle" font-size="11">31</text>
<line x1="641.7" y1="784" x2="641.7" y2="788" stroke="black"/>
<text x="641.7" y="801" text-anchor="middle" font-size="11">32</text>
<line x1="660.1" y1="784" x2="660.1" y2="788" stroke="black"/>
<text x="660.1" y="801" text-anchor="middle" font-size="11">33</text>
<line x1="678.6" y1="784" x2="678.6" y2="788" stroke="black"/>
<text x="678.6" y="801" text-anchor="middle" font-size="11">34</text>
<line x1="697.0" y1="784" x2="697.0" y2="788" stroke="black"/> <line x1="697.0" y1="784" x2="697.0" y2="788" stroke="black"/>
<text x="697.0" y="801" text-anchor="middle" font-size="11">35</text> <text x="697.0" y="801" text-anchor="middle" font-size="11">5</text>
<line x1="66" y1="784.0" x2="70" y2="784.0" stroke="black"/> <line x1="66" y1="784.0" x2="70" y2="784.0" stroke="black"/>
<text x="63" y="788.0" text-anchor="end" font-size="11">0</text> <text x="63" y="788.0" text-anchor="end" font-size="11">0</text>
<line x1="66" y1="664.0" x2="70" y2="664.0" stroke="black"/> <line x1="66" y1="664.0" x2="70" y2="664.0" stroke="black"/>
@@ -100,119 +40,29 @@
<text x="383" y="817" text-anchor="middle" font-size="12">test match number (each opponent)</text> <text x="383" y="817" text-anchor="middle" font-size="12">test match number (each opponent)</text>
<text x="16" y="484" text-anchor="middle" font-size="12" transform="rotate(-90 16 484)">win rate (%)</text> <text x="16" y="484" text-anchor="middle" font-size="12" transform="rotate(-90 16 484)">win rate (%)</text>
<circle cx="70.0" cy="784.0" r="2" fill="#d62728" opacity="0.25"/> <circle cx="70.0" cy="784.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="88.4" cy="784.0" r="2" fill="#d62728" opacity="0.25"/> <circle cx="226.8" cy="784.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="106.9" cy="784.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="125.3" cy="784.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="143.8" cy="784.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="162.2" cy="784.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="180.6" cy="784.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="199.1" cy="784.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="217.5" cy="784.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="236.0" cy="784.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="254.4" cy="784.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="272.9" cy="724.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="291.3" cy="784.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="309.7" cy="784.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="328.2" cy="784.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="346.6" cy="724.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="365.1" cy="784.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="383.5" cy="784.0" r="2" fill="#d62728" opacity="0.25"/> <circle cx="383.5" cy="784.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="401.9" cy="784.0" r="2" fill="#d62728" opacity="0.25"/> <circle cx="540.2" cy="724.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="420.4" cy="784.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="438.8" cy="784.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="457.3" cy="784.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="475.7" cy="724.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="494.1" cy="784.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="512.6" cy="784.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="531.0" cy="604.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="549.5" cy="784.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="567.9" cy="784.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="586.4" cy="784.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="604.8" cy="784.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="623.2" cy="604.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="641.7" cy="784.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="660.1" cy="784.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="678.6" cy="784.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="697.0" cy="784.0" r="2" fill="#d62728" opacity="0.25"/> <circle cx="697.0" cy="784.0" r="2" fill="#d62728" opacity="0.25"/>
<polyline points="70.0,784.0 88.4,784.0 106.9,784.0 125.3,784.0 143.8,784.0 162.2,784.0 180.6,784.0 199.1,784.0 217.5,784.0 236.0,784.0 254.4,784.0 272.9,778.0 291.3,778.0 309.7,778.0 328.2,778.0 346.6,772.0 365.1,772.0 383.5,772.0 401.9,772.0 420.4,772.0 438.8,772.0 457.3,778.0 475.7,772.0 494.1,772.0 512.6,772.0 531.0,760.0 549.5,760.0 567.9,760.0 586.4,760.0 604.8,760.0 623.2,742.0 641.7,742.0 660.1,748.0 678.6,748.0 697.0,748.0" fill="none" stroke="#d62728" stroke-width="3.5" opacity="1.0"/> <polyline points="70.0,784.0 226.8,784.0 383.5,784.0 540.2,769.0 697.0,772.0" fill="none" stroke="#d62728" stroke-width="3.5" opacity="1.0"/>
<circle cx="70.0" cy="784.0" r="2" fill="#1f77b4" opacity="0.25"/> <circle cx="70.0" cy="664.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="88.4" cy="784.0" r="2" fill="#1f77b4" opacity="0.25"/> <circle cx="226.8" cy="784.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="106.9" cy="784.0" r="2" fill="#1f77b4" opacity="0.25"/> <circle cx="383.5" cy="724.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="125.3" cy="784.0" r="2" fill="#1f77b4" opacity="0.25"/> <circle cx="540.2" cy="184.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="143.8" cy="784.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="162.2" cy="784.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="180.6" cy="784.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="199.1" cy="784.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="217.5" cy="784.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="236.0" cy="784.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="254.4" cy="784.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="272.9" cy="544.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="291.3" cy="304.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="309.7" cy="724.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="328.2" cy="364.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="346.6" cy="184.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="365.1" cy="784.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="383.5" cy="784.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="401.9" cy="784.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="420.4" cy="724.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="438.8" cy="364.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="457.3" cy="784.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="475.7" cy="184.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="494.1" cy="664.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="512.6" cy="544.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="531.0" cy="304.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="549.5" cy="304.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="567.9" cy="484.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="586.4" cy="664.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="604.8" cy="784.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="623.2" cy="724.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="641.7" cy="784.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="660.1" cy="784.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="678.6" cy="364.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="697.0" cy="784.0" r="2" fill="#1f77b4" opacity="0.25"/> <circle cx="697.0" cy="784.0" r="2" fill="#1f77b4" opacity="0.25"/>
<polyline points="70.0,784.0 88.4,784.0 106.9,784.0 125.3,784.0 143.8,784.0 162.2,784.0 180.6,784.0 199.1,784.0 217.5,784.0 236.0,784.0 254.4,784.0 272.9,760.0 291.3,712.0 309.7,706.0 328.2,664.0 346.6,604.0 365.1,604.0 383.5,604.0 401.9,604.0 420.4,598.0 438.8,556.0 457.3,580.0 475.7,568.0 494.1,562.0 512.6,580.0 531.0,592.0 549.5,544.0 567.9,514.0 586.4,502.0 604.8,508.0 623.2,544.0 641.7,544.0 660.1,604.0 678.6,574.0 697.0,598.0" fill="none" stroke="#1f77b4" stroke-width="3.5" opacity="1.0"/> <polyline points="70.0,664.0 226.8,724.0 383.5,724.0 540.2,589.0 697.0,628.0" fill="none" stroke="#1f77b4" stroke-width="3.5" opacity="1.0"/>
<circle cx="70.0" cy="784.0" r="2" fill="#2ca02c" opacity="0.25"/> <circle cx="70.0" cy="784.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="88.4" cy="784.0" r="2" fill="#2ca02c" opacity="0.25"/> <circle cx="226.8" cy="784.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="106.9" cy="784.0" r="2" fill="#2ca02c" opacity="0.25"/> <circle cx="383.5" cy="784.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="125.3" cy="784.0" r="2" fill="#2ca02c" opacity="0.25"/> <circle cx="540.2" cy="784.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="143.8" cy="784.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="162.2" cy="784.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="180.6" cy="784.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="199.1" cy="784.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="217.5" cy="784.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="236.0" cy="784.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="254.4" cy="784.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="272.9" cy="784.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="291.3" cy="784.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="309.7" cy="724.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="328.2" cy="544.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="346.6" cy="784.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="365.1" cy="244.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="383.5" cy="604.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="401.9" cy="784.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="420.4" cy="784.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="438.8" cy="724.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="457.3" cy="784.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="475.7" cy="784.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="494.1" cy="184.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="512.6" cy="784.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="531.0" cy="544.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="549.5" cy="784.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="567.9" cy="784.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="586.4" cy="784.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="604.8" cy="364.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="623.2" cy="784.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="641.7" cy="604.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="660.1" cy="784.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="678.6" cy="724.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="697.0" cy="784.0" r="2" fill="#2ca02c" opacity="0.25"/> <circle cx="697.0" cy="784.0" r="2" fill="#2ca02c" opacity="0.25"/>
<polyline points="70.0,784.0 88.4,784.0 106.9,784.0 125.3,784.0 143.8,784.0 162.2,784.0 180.6,784.0 199.1,784.0 217.5,784.0 236.0,784.0 254.4,784.0 272.9,784.0 291.3,784.0 309.7,778.0 328.2,754.0 346.6,754.0 365.1,700.0 383.5,682.0 401.9,682.0 420.4,682.0 438.8,676.0 457.3,676.0 475.7,676.0 494.1,622.0 512.6,646.0 531.0,622.0 549.5,676.0 567.9,694.0 586.4,694.0 604.8,652.0 623.2,658.0 641.7,640.0 660.1,640.0 678.6,694.0 697.0,694.0" fill="none" stroke="#2ca02c" stroke-width="3.5" opacity="1.0"/> <polyline points="70.0,784.0 226.8,784.0 383.5,784.0 540.2,784.0 697.0,784.0" fill="none" stroke="#2ca02c" stroke-width="3.5" opacity="1.0"/>
<line x1="82" y1="836" x2="110" y2="836" stroke="#d62728" stroke-width="3"/> <line x1="82" y1="836" x2="110" y2="836" stroke="#d62728" stroke-width="3"/>
<text x="116" y="840" font-size="12">Corners - 35 evals</text> <text x="116" y="840" font-size="12">Corners - 5 evals</text>
<line x1="82" y1="854" x2="110" y2="854" stroke="#1f77b4" stroke-width="3"/> <line x1="82" y1="854" x2="110" y2="854" stroke="#1f77b4" stroke-width="3"/>
<text x="116" y="858" font-size="12">Crazy - 35 evals</text> <text x="116" y="858" font-size="12">Crazy - 5 evals</text>
<line x1="82" y1="872" x2="110" y2="872" stroke="#2ca02c" stroke-width="3"/> <line x1="82" y1="872" x2="110" y2="872" stroke="#2ca02c" stroke-width="3"/>
<text x="116" y="876" font-size="12">Target - 35 evals</text> <text x="116" y="876" font-size="12">Target - 5 evals</text>
<text x="747" y="100" font-size="15" font-weight="bold">Training losses (log) &amp; alpha (linear)</text> <text x="747" y="100" font-size="15" font-weight="bold">Training losses (log) &amp; alpha (linear)</text>
<text x="747" y="115" font-size="11" fill="#555">training_metrics.jsonl - big early spikes are normal</text> <text x="747" y="115" font-size="11" fill="#555">training_metrics.jsonl - big early spikes are normal</text>
<text x="747" y="133" font-size="12" font-style="italic" fill="#555">What: How well the brain is learning: losses should fall; alpha sets explore/exploit.</text> <text x="747" y="133" font-size="12" font-style="italic" fill="#555">What: How well the brain is learning: losses should fall; alpha sets explore/exploit.</text>
@@ -228,13 +78,13 @@
<line x1="747.0" y1="784" x2="747.0" y2="788" stroke="black"/> <line x1="747.0" y1="784" x2="747.0" y2="788" stroke="black"/>
<text x="747.0" y="801" text-anchor="middle" font-size="11">1</text> <text x="747.0" y="801" text-anchor="middle" font-size="11">1</text>
<line x1="892.5" y1="784" x2="892.5" y2="788" stroke="black"/> <line x1="892.5" y1="784" x2="892.5" y2="788" stroke="black"/>
<text x="892.5" y="801" text-anchor="middle" font-size="11">19</text> <text x="892.5" y="801" text-anchor="middle" font-size="11">24</text>
<line x1="1038.0" y1="784" x2="1038.0" y2="788" stroke="black"/> <line x1="1038.0" y1="784" x2="1038.0" y2="788" stroke="black"/>
<text x="1038.0" y="801" text-anchor="middle" font-size="11">36</text> <text x="1038.0" y="801" text-anchor="middle" font-size="11">46</text>
<line x1="1183.5" y1="784" x2="1183.5" y2="788" stroke="black"/> <line x1="1183.5" y1="784" x2="1183.5" y2="788" stroke="black"/>
<text x="1183.5" y="801" text-anchor="middle" font-size="11">54</text> <text x="1183.5" y="801" text-anchor="middle" font-size="11">69</text>
<line x1="1329.0" y1="784" x2="1329.0" y2="788" stroke="black"/> <line x1="1329.0" y1="784" x2="1329.0" y2="788" stroke="black"/>
<text x="1329.0" y="801" text-anchor="middle" font-size="11">72</text> <text x="1329.0" y="801" text-anchor="middle" font-size="11">92</text>
<line x1="743" y1="784.0" x2="747" y2="784.0" stroke="black"/> <line x1="743" y1="784.0" x2="747" y2="784.0" stroke="black"/>
<text x="740" y="788.0" text-anchor="end" font-size="11">0.01</text> <text x="740" y="788.0" text-anchor="end" font-size="11">0.01</text>
<line x1="743" y1="634.0" x2="747" y2="634.0" stroke="black"/> <line x1="743" y1="634.0" x2="747" y2="634.0" stroke="black"/>
@@ -247,8 +97,8 @@
<text x="740" y="188.0" text-anchor="end" font-size="11">100</text> <text x="740" y="188.0" text-anchor="end" font-size="11">100</text>
<text x="1038" y="817" text-anchor="middle" font-size="12">metric line number</text> <text x="1038" y="817" text-anchor="middle" font-size="12">metric line number</text>
<text x="16" y="484" text-anchor="middle" font-size="12" transform="rotate(-90 16 484)">loss (log)</text> <text x="16" y="484" text-anchor="middle" font-size="12" transform="rotate(-90 16 484)">loss (log)</text>
<polyline points="747.0,345.9 755.2,317.6 763.4,307.9 771.6,277.5 779.8,271.6 788.0,450.8 796.2,488.4 804.4,371.1 812.6,357.6 820.8,346.6 829.0,306.7 837.2,235.4 845.4,222.6 853.6,233.7 861.8,255.2 870.0,317.6 878.2,391.8 886.4,689.2 894.5,570.4 902.7,438.2 910.9,489.9 919.1,415.1 927.3,421.9 935.5,394.0 943.7,315.4 951.9,403.4 960.1,395.4 968.3,347.3 976.5,384.4 984.7,403.4 992.9,359.6 1001.1,281.5 1009.3,479.1 1017.5,530.4 1025.7,598.4 1033.9,352.1 1042.1,326.5 1050.3,473.0 1058.5,506.0 1066.7,331.4 1074.9,746.1 1083.1,663.4 1091.3,420.9 1099.5,617.1 1107.7,361.8 1115.9,514.9 1124.1,377.6 1132.3,387.0 1140.5,361.7 1148.7,357.1 1156.9,327.5 1165.1,392.5 1173.3,519.5 1181.5,436.0 1189.6,399.4 1197.8,385.9 1206.0,493.5 1214.2,483.4 1222.4,456.3 1230.6,575.1 1238.8,672.1 1247.0,312.5 1255.2,463.3 1263.4,745.8 1271.6,554.2 1279.8,381.5 1288.0,301.5 1296.2,292.7 1304.4,241.6 1312.6,212.1 1320.8,234.2 1329.0,302.6" fill="none" stroke="#1f77b4" stroke-width="1.8" opacity="1.0"/> <polyline points="747.0,345.9 753.4,317.6 759.8,307.9 766.2,277.5 772.6,271.6 779.0,450.8 785.4,488.4 791.8,371.1 798.2,357.6 804.6,346.6 811.0,306.7 817.4,235.4 823.7,222.6 830.1,233.7 836.5,255.2 842.9,317.6 849.3,391.8 855.7,689.2 862.1,570.4 868.5,438.2 874.9,489.9 881.3,415.1 887.7,421.9 894.1,394.0 900.5,315.4 906.9,403.4 913.3,395.4 919.7,347.3 926.1,384.4 932.5,403.4 938.9,359.6 945.3,281.5 951.7,479.1 958.1,530.4 964.5,598.4 970.8,352.1 977.2,326.5 983.6,473.0 990.0,506.0 996.4,331.4 1002.8,746.1 1009.2,663.4 1015.6,420.9 1022.0,617.1 1028.4,361.8 1034.8,514.9 1041.2,377.6 1047.6,387.0 1054.0,361.7 1060.4,357.1 1066.8,327.5 1073.2,392.5 1079.6,519.5 1086.0,436.0 1092.4,399.4 1098.8,385.9 1105.2,493.5 1111.5,483.4 1117.9,456.3 1124.3,575.1 1130.7,672.1 1137.1,312.5 1143.5,463.3 1149.9,745.8 1156.3,554.2 1162.7,381.5 1169.1,301.5 1175.5,292.7 1181.9,241.6 1188.3,212.1 1194.7,234.2 1201.1,302.6 1207.5,437.6 1213.9,427.3 1220.3,503.0 1226.7,325.5 1233.1,327.0 1239.5,312.9 1245.9,448.6 1252.3,311.7 1258.6,417.9 1265.0,596.5 1271.4,396.9 1277.8,422.4 1284.2,371.0 1290.6,343.4 1297.0,374.0 1303.4,447.6 1309.8,640.0 1316.2,449.0 1322.6,514.0 1329.0,403.2" fill="none" stroke="#1f77b4" stroke-width="1.8" opacity="1.0"/>
<polyline points="747.0,412.9 755.2,371.9 763.4,348.5 771.6,325.3 779.8,308.2 788.0,299.2 796.2,300.5 804.4,305.4 812.6,334.7 820.8,356.4 829.0,442.9 837.2,366.9 845.4,341.7 853.6,328.4 861.8,318.8 870.0,310.5 878.2,306.0 886.4,315.8 894.5,326.0 902.7,337.4 910.9,359.3 919.1,391.5 927.3,399.9 935.5,502.0 943.7,464.5 951.9,564.9 960.1,454.5 968.3,393.2 976.5,380.2 984.7,375.3 992.9,353.3 1001.1,352.2 1009.3,342.8 1017.5,351.9 1025.7,358.7 1033.9,379.5 1042.1,402.3 1050.3,418.8 1058.5,438.0 1066.7,431.7 1074.9,426.7 1083.1,406.5 1091.3,442.8 1099.5,458.7 1107.7,415.4 1115.9,407.0 1124.1,581.8 1132.3,551.6 1140.5,459.8 1148.7,385.5 1156.9,362.4 1165.1,365.9 1173.3,376.3 1181.5,404.8 1189.6,450.3 1197.8,486.9 1206.0,443.9 1214.2,409.7 1222.4,397.8 1230.6,393.6 1238.8,374.2 1247.0,374.4 1255.2,379.7 1263.4,396.1 1271.6,477.0 1279.8,386.3 1288.0,351.8 1296.2,344.7 1304.4,319.0 1312.6,303.7 1320.8,292.7 1329.0,291.1" fill="none" stroke="#ff7f0e" stroke-width="1.8" opacity="1.0"/> <polyline points="747.0,412.9 753.4,371.9 759.8,348.5 766.2,325.3 772.6,308.2 779.0,299.2 785.4,300.5 791.8,305.4 798.2,334.7 804.6,356.4 811.0,442.9 817.4,366.9 823.7,341.7 830.1,328.4 836.5,318.8 842.9,310.5 849.3,306.0 855.7,315.8 862.1,326.0 868.5,337.4 874.9,359.3 881.3,391.5 887.7,399.9 894.1,502.0 900.5,464.5 906.9,564.9 913.3,454.5 919.7,393.2 926.1,380.2 932.5,375.3 938.9,353.3 945.3,352.2 951.7,342.8 958.1,351.9 964.5,358.7 970.8,379.5 977.2,402.3 983.6,418.8 990.0,438.0 996.4,431.7 1002.8,426.7 1009.2,406.5 1015.6,442.8 1022.0,458.7 1028.4,415.4 1034.8,407.0 1041.2,581.8 1047.6,551.6 1054.0,459.8 1060.4,385.5 1066.8,362.4 1073.2,365.9 1079.6,376.3 1086.0,404.8 1092.4,450.3 1098.8,486.9 1105.2,443.9 1111.5,409.7 1117.9,397.8 1124.3,393.6 1130.7,374.2 1137.1,374.4 1143.5,379.7 1149.9,396.1 1156.3,477.0 1162.7,386.3 1169.1,351.8 1175.5,344.7 1181.9,319.0 1188.3,303.7 1194.7,292.7 1201.1,291.1 1207.5,290.5 1213.9,293.6 1220.3,304.0 1226.7,333.0 1233.1,342.4 1239.5,379.0 1245.9,388.7 1252.3,338.6 1258.6,333.8 1265.0,322.4 1271.4,337.6 1277.8,334.1 1284.2,317.2 1290.6,288.4 1297.0,281.6 1303.4,274.9 1309.8,274.5 1316.2,285.3 1322.6,294.5 1329.0,304.4" fill="none" stroke="#ff7f0e" stroke-width="1.8" opacity="1.0"/>
<line x1="747" y1="784.0" x2="1329" y2="784.0" stroke="#e9dcf5"/> <line x1="747" y1="784.0" x2="1329" y2="784.0" stroke="#e9dcf5"/>
<line x1="747" y1="634.0" x2="1329" y2="634.0" stroke="#e9dcf5"/> <line x1="747" y1="634.0" x2="1329" y2="634.0" stroke="#e9dcf5"/>
<line x1="747" y1="484.0" x2="1329" y2="484.0" stroke="#e9dcf5"/> <line x1="747" y1="484.0" x2="1329" y2="484.0" stroke="#e9dcf5"/>
@@ -266,7 +116,7 @@
<line x1="1329" y1="184.0" x2="1333" y2="184.0" stroke="#9467bd"/> <line x1="1329" y1="184.0" x2="1333" y2="184.0" stroke="#9467bd"/>
<text x="1336" y="188.0" font-size="11" fill="#9467bd">1</text> <text x="1336" y="188.0" font-size="11" fill="#9467bd">1</text>
<text x="1346" y="484" text-anchor="middle" font-size="12" fill="#9467bd" transform="rotate(90 1346 484)">alpha</text> <text x="1346" y="484" text-anchor="middle" font-size="12" fill="#9467bd" transform="rotate(90 1346 484)">alpha</text>
<polyline points="747.0,184.2 755.2,184.9 763.4,185.6 771.6,186.3 779.8,187.1 788.0,187.8 796.2,188.1 804.4,188.5 812.6,189.2 820.8,189.6 829.0,190.3 837.2,190.9 845.4,190.1 853.6,189.4 861.8,188.7 870.0,188.0 878.2,187.3 886.4,186.6 894.5,185.9 902.7,185.2 910.9,185.7 919.1,186.4 927.3,187.2 935.5,187.9 943.7,188.6 951.9,190.0 960.1,190.7 968.3,191.4 976.5,192.1 984.7,192.5 992.9,192.4 1001.1,192.1 1009.3,191.7 1017.5,191.6 1025.7,192.4 1033.9,193.1 1042.1,193.4 1050.3,194.1 1058.5,194.5 1066.7,195.0 1074.9,195.4 1083.1,196.1 1091.3,196.4 1099.5,197.1 1107.7,197.8 1115.9,198.2 1124.1,198.9 1132.3,199.2 1140.5,199.9 1148.7,200.6 1156.9,200.6 1165.1,200.3 1173.3,200.8 1181.5,201.2 1189.6,201.9 1197.8,202.6 1206.0,203.3 1214.2,204.0 1222.4,204.7 1230.6,205.4 1238.8,206.1 1247.0,206.4 1255.2,207.1 1263.4,207.8 1271.6,208.7 1279.8,209.8 1288.0,209.8 1296.2,209.5 1304.4,208.8 1312.6,208.3 1320.8,207.3 1329.0,206.6" fill="none" stroke="#9467bd" stroke-width="1.8" opacity="1.0"/> <polyline points="747.0,184.2 753.4,184.9 759.8,185.6 766.2,186.3 772.6,187.1 779.0,187.8 785.4,188.1 791.8,188.5 798.2,189.2 804.6,189.6 811.0,190.3 817.4,190.9 823.7,190.1 830.1,189.4 836.5,188.7 842.9,188.0 849.3,187.3 855.7,186.6 862.1,185.9 868.5,185.2 874.9,185.7 881.3,186.4 887.7,187.2 894.1,187.9 900.5,188.6 906.9,190.0 913.3,190.7 919.7,191.4 926.1,192.1 932.5,192.5 938.9,192.4 945.3,192.1 951.7,191.7 958.1,191.6 964.5,192.4 970.8,193.1 977.2,193.4 983.6,194.1 990.0,194.5 996.4,195.0 1002.8,195.4 1009.2,196.1 1015.6,196.4 1022.0,197.1 1028.4,197.8 1034.8,198.2 1041.2,198.9 1047.6,199.2 1054.0,199.9 1060.4,200.6 1066.8,200.6 1073.2,200.3 1079.6,200.8 1086.0,201.2 1092.4,201.9 1098.8,202.6 1105.2,203.3 1111.5,204.0 1117.9,204.7 1124.3,205.4 1130.7,206.1 1137.1,206.4 1143.5,207.1 1149.9,207.8 1156.3,208.7 1162.7,209.8 1169.1,209.8 1175.5,209.5 1181.9,208.8 1188.3,208.3 1194.7,207.3 1201.1,206.6 1207.5,205.9 1213.9,205.5 1220.3,204.8 1226.7,204.6 1233.1,205.0 1239.5,205.6 1245.9,206.9 1252.3,207.3 1258.6,206.5 1265.0,205.7 1271.4,205.5 1277.8,205.5 1284.2,204.9 1290.6,203.3 1297.0,202.6 1303.4,201.9 1309.8,201.5 1316.2,200.3 1322.6,199.5 1329.0,198.8" fill="none" stroke="#9467bd" stroke-width="1.8" opacity="1.0"/>
<line x1="759" y1="836" x2="787" y2="836" stroke="#1f77b4" stroke-width="3"/> <line x1="759" y1="836" x2="787" y2="836" stroke="#1f77b4" stroke-width="3"/>
<text x="793" y="840" font-size="12">critic_loss</text> <text x="793" y="840" font-size="12">critic_loss</text>
<line x1="759" y1="854" x2="787" y2="854" stroke="#ff7f0e" stroke-width="3"/> <line x1="759" y1="854" x2="787" y2="854" stroke="#ff7f0e" stroke-width="3"/>
@@ -285,26 +135,26 @@
<line x1="70" y1="1024.0" x2="697" y2="1024.0" stroke="#dddddd"/> <line x1="70" y1="1024.0" x2="697" y2="1024.0" stroke="#dddddd"/>
<line x1="70" y1="1494" x2="697" y2="1494" stroke="black"/> <line x1="70" y1="1494" x2="697" y2="1494" stroke="black"/>
<line x1="70" y1="1494" x2="70" y2="1024" stroke="black"/> <line x1="70" y1="1494" x2="70" y2="1024" stroke="black"/>
<line x1="123.7" y1="1494" x2="123.7" y2="1498" stroke="black"/> <line x1="125.7" y1="1494" x2="125.7" y2="1498" stroke="black"/>
<text x="123.7" y="1511" text-anchor="middle" font-size="11">7</text> <text x="125.7" y="1511" text-anchor="middle" font-size="11">9</text>
<line x1="186.4" y1="1494" x2="186.4" y2="1498" stroke="black"/> <line x1="188.4" y1="1494" x2="188.4" y2="1498" stroke="black"/>
<text x="186.4" y="1511" text-anchor="middle" font-size="11">14</text> <text x="188.4" y="1511" text-anchor="middle" font-size="11">18</text>
<line x1="249.1" y1="1494" x2="249.1" y2="1498" stroke="black"/> <line x1="251.1" y1="1494" x2="251.1" y2="1498" stroke="black"/>
<text x="249.1" y="1511" text-anchor="middle" font-size="11">21</text> <text x="251.1" y="1511" text-anchor="middle" font-size="11">27</text>
<line x1="311.8" y1="1494" x2="311.8" y2="1498" stroke="black"/> <line x1="313.8" y1="1494" x2="313.8" y2="1498" stroke="black"/>
<text x="311.8" y="1511" text-anchor="middle" font-size="11">28</text> <text x="313.8" y="1511" text-anchor="middle" font-size="11">36</text>
<line x1="374.5" y1="1494" x2="374.5" y2="1498" stroke="black"/> <line x1="376.5" y1="1494" x2="376.5" y2="1498" stroke="black"/>
<text x="374.5" y="1511" text-anchor="middle" font-size="11">35</text> <text x="376.5" y="1511" text-anchor="middle" font-size="11">45</text>
<line x1="437.2" y1="1494" x2="437.2" y2="1498" stroke="black"/> <line x1="439.2" y1="1494" x2="439.2" y2="1498" stroke="black"/>
<text x="437.2" y="1511" text-anchor="middle" font-size="11">42</text> <text x="439.2" y="1511" text-anchor="middle" font-size="11">54</text>
<line x1="499.9" y1="1494" x2="499.9" y2="1498" stroke="black"/> <line x1="501.9" y1="1494" x2="501.9" y2="1498" stroke="black"/>
<text x="499.9" y="1511" text-anchor="middle" font-size="11">49</text> <text x="501.9" y="1511" text-anchor="middle" font-size="11">63</text>
<line x1="562.6" y1="1494" x2="562.6" y2="1498" stroke="black"/> <line x1="564.6" y1="1494" x2="564.6" y2="1498" stroke="black"/>
<text x="562.6" y="1511" text-anchor="middle" font-size="11">56</text> <text x="564.6" y="1511" text-anchor="middle" font-size="11">72</text>
<line x1="625.3" y1="1494" x2="625.3" y2="1498" stroke="black"/> <line x1="627.3" y1="1494" x2="627.3" y2="1498" stroke="black"/>
<text x="625.3" y="1511" text-anchor="middle" font-size="11">63</text> <text x="627.3" y="1511" text-anchor="middle" font-size="11">81</text>
<line x1="688.0" y1="1494" x2="688.0" y2="1498" stroke="black"/> <line x1="690.0" y1="1494" x2="690.0" y2="1498" stroke="black"/>
<text x="688.0" y="1511" text-anchor="middle" font-size="11">70</text> <text x="690.0" y="1511" text-anchor="middle" font-size="11">90</text>
<line x1="66" y1="1494.0" x2="70" y2="1494.0" stroke="black"/> <line x1="66" y1="1494.0" x2="70" y2="1494.0" stroke="black"/>
<text x="63" y="1498.0" text-anchor="end" font-size="11">0</text> <text x="63" y="1498.0" text-anchor="end" font-size="11">0</text>
<line x1="66" y1="1376.5" x2="70" y2="1376.5" stroke="black"/> <line x1="66" y1="1376.5" x2="70" y2="1376.5" stroke="black"/>
@@ -318,77 +168,97 @@
<text x="383" y="1527" text-anchor="middle" font-size="12">chunk interval (10-game chunks)</text> <text x="383" y="1527" text-anchor="middle" font-size="12">chunk interval (10-game chunks)</text>
<text x="16" y="1259" text-anchor="middle" font-size="12" transform="rotate(-90 16 1259)">games / hour</text> <text x="16" y="1259" text-anchor="middle" font-size="12" transform="rotate(-90 16 1259)">games / hour</text>
<circle cx="70.0" cy="1225.8" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="70.0" cy="1225.8" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="79.0" cy="1479.4" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="77.0" cy="1479.4" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="87.9" cy="1214.0" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="83.9" cy="1214.0" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="96.9" cy="1470.7" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="90.9" cy="1470.7" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="105.8" cy="1219.6" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="97.9" cy="1219.6" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="114.8" cy="1465.6" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="104.8" cy="1465.6" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="123.7" cy="1066.7" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="111.8" cy="1066.7" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="132.7" cy="1465.5" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="118.8" cy="1465.5" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="141.7" cy="1087.4" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="125.7" cy="1087.4" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="150.6" cy="1460.8" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="132.7" cy="1460.8" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="159.6" cy="1442.2" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="139.7" cy="1442.2" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="168.5" cy="1460.4" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="146.6" cy="1460.4" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="177.5" cy="1196.1" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="153.6" cy="1196.1" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="186.4" cy="1465.7" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="160.6" cy="1465.7" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="195.4" cy="1242.5" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="167.5" cy="1242.5" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="204.4" cy="1468.0" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="174.5" cy="1468.0" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="213.3" cy="1224.0" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="181.5" cy="1224.0" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="222.3" cy="1466.0" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="188.4" cy="1466.0" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="231.2" cy="1215.2" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="195.4" cy="1215.2" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="240.2" cy="1466.6" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="202.4" cy="1466.6" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="249.1" cy="1237.7" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="209.3" cy="1237.7" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="258.1" cy="1471.2" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="216.3" cy="1471.2" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="267.1" cy="1228.2" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="223.3" cy="1228.2" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="276.0" cy="1482.5" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="230.2" cy="1482.5" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="285.0" cy="1441.5" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="237.2" cy="1441.5" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="293.9" cy="1481.7" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="244.2" cy="1481.7" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="302.9" cy="1228.0" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="251.1" cy="1228.0" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="311.8" cy="1481.1" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="258.1" cy="1481.1" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="320.8" cy="1141.1" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="265.1" cy="1141.1" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="329.8" cy="1481.6" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="272.0" cy="1481.6" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="338.7" cy="1141.2" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="279.0" cy="1141.2" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="347.7" cy="1480.7" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="286.0" cy="1480.7" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="356.6" cy="1164.6" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="292.9" cy="1164.6" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="365.6" cy="1483.5" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="299.9" cy="1483.5" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="374.5" cy="1222.4" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="306.9" cy="1222.4" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="383.5" cy="1474.3" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="313.8" cy="1474.3" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="392.5" cy="1196.9" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="320.8" cy="1196.9" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="401.4" cy="1474.3" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="327.8" cy="1474.3" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="410.4" cy="1176.4" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="334.7" cy="1176.4" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="419.3" cy="1477.7" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="341.7" cy="1477.7" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="428.3" cy="1206.4" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="348.7" cy="1206.4" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="437.2" cy="1475.0" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="355.6" cy="1475.0" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="446.2" cy="1197.3" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="362.6" cy="1197.3" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="455.2" cy="1474.8" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="369.6" cy="1474.8" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="464.1" cy="1109.7" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="376.5" cy="1109.7" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="473.1" cy="1474.6" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="383.5" cy="1474.6" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="482.0" cy="1091.4" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="390.5" cy="1091.4" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="491.0" cy="1477.1" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="397.4" cy="1477.1" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="499.9" cy="1214.9" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="404.4" cy="1214.9" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="508.9" cy="1474.6" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="411.4" cy="1474.6" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="517.9" cy="1106.2" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="418.3" cy="1106.2" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="526.8" cy="1474.3" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="425.3" cy="1474.3" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="535.8" cy="1082.3" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="432.3" cy="1082.3" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="544.7" cy="1474.6" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="439.2" cy="1474.6" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="553.7" cy="1206.8" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="446.2" cy="1206.8" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="562.6" cy="1474.5" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="453.2" cy="1474.5" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="571.6" cy="1226.8" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="460.1" cy="1226.8" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="580.6" cy="1474.7" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="467.1" cy="1474.7" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="589.5" cy="1217.6" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="474.1" cy="1217.6" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="598.5" cy="1479.7" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="481.0" cy="1479.7" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="607.4" cy="1087.7" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="488.0" cy="1087.7" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="616.4" cy="1474.3" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="495.0" cy="1474.3" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="625.3" cy="1209.8" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="501.9" cy="1209.8" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="634.3" cy="1475.8" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="508.9" cy="1475.8" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="643.3" cy="1444.9" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="515.9" cy="1444.9" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="652.2" cy="1476.3" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="522.8" cy="1476.3" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="661.2" cy="1077.6" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="529.8" cy="1077.6" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="670.1" cy="1476.0" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="536.8" cy="1476.0" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="679.1" cy="1151.6" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="543.7" cy="1151.6" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="688.0" cy="1483.9" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="550.7" cy="1483.9" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="697.0" cy="1236.2" r="1.6" fill="#7f7f7f" opacity="0.25"/> <circle cx="557.7" cy="1236.2" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<polyline points="79.0,1347.5 105.8,1304.4 141.7,1362.7 168.5,1343.1 204.4,1342.9 240.2,1354.9 267.1,1408.1 302.9,1311.1 329.8,1336.2 365.6,1331.3 392.5,1338.4 428.3,1225.2 455.2,1388.9 491.0,1220.9 517.9,1385.3 553.7,1306.4 589.5,1347.2 616.4,1376.8 652.2,1343.3 679.1,1290.6" fill="none" stroke="#2ca02c" stroke-width="3.5" opacity="1.0"/> <circle cx="564.6" cy="1477.1" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="571.6" cy="1096.1" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="578.6" cy="1474.3" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="585.5" cy="1241.5" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="592.5" cy="1474.5" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="599.5" cy="1245.3" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="606.4" cy="1481.9" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="613.4" cy="1260.9" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="620.4" cy="1474.4" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="627.3" cy="1242.0" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="634.3" cy="1491.8" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="641.3" cy="1088.6" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="648.2" cy="1478.0" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="655.2" cy="1449.8" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="662.2" cy="1477.5" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="669.1" cy="1227.7" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="676.1" cy="1471.1" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="683.1" cy="1441.4" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="690.0" cy="1479.1" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<circle cx="697.0" cy="1230.5" r="1.6" fill="#7f7f7f" opacity="0.25"/>
<polyline points="77.0,1321.9 111.8,1309.2 139.7,1361.4 174.5,1367.9 202.4,1372.2 237.2,1362.7 272.0,1298.5 299.9,1359.9 334.7,1292.6 362.6,1346.5 397.4,1268.8 425.3,1348.4 460.1,1312.9 488.0,1368.7 522.8,1336.9 557.7,1322.2 585.5,1365.7 620.4,1324.2 648.2,1408.2 683.1,1405.5" fill="none" stroke="#2ca02c" stroke-width="3.5" opacity="1.0"/>
<text x="747" y="940" font-size="15" font-weight="bold">Max score per eval cycle</text> <text x="747" y="940" font-size="15" font-weight="bold">Max score per eval cycle</text>
<text x="747" y="955" font-size="11" fill="#555">campaign_v4_stdout.log - max of the 10 deterministic round scores per eval</text> <text x="747" y="955" font-size="11" fill="#555">campaign_v4_stdout.log - max of the 10 deterministic round scores per eval</text>
<text x="747" y="973" font-size="12" font-style="italic" fill="#555">What: Best single-round score the bot managed in each test cycle.</text> <text x="747" y="973" font-size="12" font-style="italic" fill="#555">What: Best single-round score the bot managed in each test cycle.</text>
@@ -401,149 +271,53 @@
<line x1="747" y1="1024.0" x2="1375" y2="1024.0" stroke="#dddddd"/> <line x1="747" y1="1024.0" x2="1375" y2="1024.0" stroke="#dddddd"/>
<line x1="747" y1="1494" x2="1375" y2="1494" stroke="black"/> <line x1="747" y1="1494" x2="1375" y2="1494" stroke="black"/>
<line x1="747" y1="1494" x2="747" y2="1024" stroke="black"/> <line x1="747" y1="1494" x2="747" y2="1024" stroke="black"/>
<line x1="802.4" y1="1494" x2="802.4" y2="1498" stroke="black"/> <line x1="747.0" y1="1494" x2="747.0" y2="1498" stroke="black"/>
<text x="802.4" y="1511" text-anchor="middle" font-size="11">4</text> <text x="747.0" y="1511" text-anchor="middle" font-size="11">1</text>
<line x1="876.3" y1="1494" x2="876.3" y2="1498" stroke="black"/> <line x1="904.0" y1="1494" x2="904.0" y2="1498" stroke="black"/>
<text x="876.3" y="1511" text-anchor="middle" font-size="11">8</text> <text x="904.0" y="1511" text-anchor="middle" font-size="11">2</text>
<line x1="950.2" y1="1494" x2="950.2" y2="1498" stroke="black"/> <line x1="1061.0" y1="1494" x2="1061.0" y2="1498" stroke="black"/>
<text x="950.2" y="1511" text-anchor="middle" font-size="11">12</text> <text x="1061.0" y="1511" text-anchor="middle" font-size="11">3</text>
<line x1="1024.1" y1="1494" x2="1024.1" y2="1498" stroke="black"/> <line x1="1218.0" y1="1494" x2="1218.0" y2="1498" stroke="black"/>
<text x="1024.1" y="1511" text-anchor="middle" font-size="11">16</text> <text x="1218.0" y="1511" text-anchor="middle" font-size="11">4</text>
<line x1="1097.9" y1="1494" x2="1097.9" y2="1498" stroke="black"/> <line x1="1375.0" y1="1494" x2="1375.0" y2="1498" stroke="black"/>
<text x="1097.9" y="1511" text-anchor="middle" font-size="11">20</text> <text x="1375.0" y="1511" text-anchor="middle" font-size="11">5</text>
<line x1="1171.8" y1="1494" x2="1171.8" y2="1498" stroke="black"/>
<text x="1171.8" y="1511" text-anchor="middle" font-size="11">24</text>
<line x1="1245.7" y1="1494" x2="1245.7" y2="1498" stroke="black"/>
<text x="1245.7" y="1511" text-anchor="middle" font-size="11">28</text>
<line x1="1319.6" y1="1494" x2="1319.6" y2="1498" stroke="black"/>
<text x="1319.6" y="1511" text-anchor="middle" font-size="11">32</text>
<line x1="743" y1="1494.0" x2="747" y2="1494.0" stroke="black"/> <line x1="743" y1="1494.0" x2="747" y2="1494.0" stroke="black"/>
<text x="740" y="1498.0" text-anchor="end" font-size="11">0</text> <text x="740" y="1498.0" text-anchor="end" font-size="11">0</text>
<line x1="743" y1="1376.5" x2="747" y2="1376.5" stroke="black"/> <line x1="743" y1="1376.5" x2="747" y2="1376.5" stroke="black"/>
<text x="740" y="1380.5" text-anchor="end" font-size="11">52</text> <text x="740" y="1380.5" text-anchor="end" font-size="11">46</text>
<line x1="743" y1="1259.0" x2="747" y2="1259.0" stroke="black"/> <line x1="743" y1="1259.0" x2="747" y2="1259.0" stroke="black"/>
<text x="740" y="1263.0" text-anchor="end" font-size="11">103</text> <text x="740" y="1263.0" text-anchor="end" font-size="11">92</text>
<line x1="743" y1="1141.5" x2="747" y2="1141.5" stroke="black"/> <line x1="743" y1="1141.5" x2="747" y2="1141.5" stroke="black"/>
<text x="740" y="1145.5" text-anchor="end" font-size="11">155</text> <text x="740" y="1145.5" text-anchor="end" font-size="11">138</text>
<line x1="743" y1="1024.0" x2="747" y2="1024.0" stroke="black"/> <line x1="743" y1="1024.0" x2="747" y2="1024.0" stroke="black"/>
<text x="740" y="1028.0" text-anchor="end" font-size="11">207</text> <text x="740" y="1028.0" text-anchor="end" font-size="11">184</text>
<text x="1061" y="1527" text-anchor="middle" font-size="12">eval cycle number</text> <text x="1061" y="1527" text-anchor="middle" font-size="12">eval cycle number</text>
<text x="16" y="1259" text-anchor="middle" font-size="12" transform="rotate(-90 16 1259)">best single-round score</text> <text x="16" y="1259" text-anchor="middle" font-size="12" transform="rotate(-90 16 1259)">best single-round score</text>
<circle cx="747.0" cy="1325.8" r="2" fill="#d62728" opacity="0.25"/> <circle cx="747.0" cy="1340.5" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="765.5" cy="1266.7" r="2" fill="#d62728" opacity="0.25"/> <circle cx="904.0" cy="1481.2" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="783.9" cy="1425.8" r="2" fill="#d62728" opacity="0.25"/> <circle cx="1061.0" cy="1207.4" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="802.4" cy="1462.2" r="2" fill="#d62728" opacity="0.25"/> <circle cx="1218.0" cy="1340.5" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="820.9" cy="1464.5" r="2" fill="#d62728" opacity="0.25"/> <circle cx="1375.0" cy="1066.7" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="839.4" cy="1423.5" r="2" fill="#d62728" opacity="0.25"/> <polyline points="747.0,1340.5 904.0,1481.2 1061.0,1207.4 1218.0,1340.5 1375.0,1066.7" fill="none" stroke="#d62728" stroke-width="2.5" opacity="1.0"/>
<circle cx="857.8" cy="1457.6" r="2" fill="#d62728" opacity="0.25"/> <circle cx="747.0" cy="1325.1" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="876.3" cy="1423.5" r="2" fill="#d62728" opacity="0.25"/> <circle cx="904.0" cy="1256.1" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="894.8" cy="1457.6" r="2" fill="#d62728" opacity="0.25"/> <circle cx="1061.0" cy="1320.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="913.2" cy="1444.0" r="2" fill="#d62728" opacity="0.25"/> <circle cx="1218.0" cy="1312.3" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="931.7" cy="1428.1" r="2" fill="#d62728" opacity="0.25"/> <circle cx="1375.0" cy="1463.3" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="950.2" cy="1344.0" r="2" fill="#d62728" opacity="0.25"/> <polyline points="747.0,1325.1 904.0,1256.1 1061.0,1320.0 1218.0,1312.3 1375.0,1463.3" fill="none" stroke="#1f77b4" stroke-width="2.5" opacity="1.0"/>
<circle cx="968.6" cy="1357.6" r="2" fill="#d62728" opacity="0.25"/> <circle cx="747.0" cy="1353.3" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="987.1" cy="1491.7" r="2" fill="#d62728" opacity="0.25"/> <circle cx="904.0" cy="1312.3" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="1005.6" cy="1357.6" r="2" fill="#d62728" opacity="0.25"/> <circle cx="1061.0" cy="1207.4" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="1024.1" cy="1357.6" r="2" fill="#d62728" opacity="0.25"/> <circle cx="1218.0" cy="1376.3" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="1042.5" cy="1453.1" r="2" fill="#d62728" opacity="0.25"/> <circle cx="1375.0" cy="1309.8" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="1061.0" cy="1257.6" r="2" fill="#d62728" opacity="0.25"/> <polyline points="747.0,1353.3 904.0,1312.3 1061.0,1207.4 1218.0,1376.3 1375.0,1309.8" fill="none" stroke="#2ca02c" stroke-width="2.5" opacity="1.0"/>
<circle cx="1079.5" cy="1494.0" r="2" fill="#d62728" opacity="0.25"/> <polyline points="747.0,1325.1 904.0,1256.1 1061.0,1207.4 1218.0,1312.3 1375.0,1066.7" fill="none" stroke="#555555" stroke-width="2.5" opacity="1.0" stroke-dasharray="6 4"/>
<circle cx="1097.9" cy="1494.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="1116.4" cy="1448.5" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="1134.9" cy="1494.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="1153.4" cy="1357.6" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="1171.8" cy="1357.6" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="1190.3" cy="1350.8" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="1208.8" cy="1357.6" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="1227.2" cy="1357.6" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="1245.7" cy="1357.6" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="1264.2" cy="1444.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="1282.6" cy="1346.3" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="1301.1" cy="1357.6" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="1319.6" cy="1200.8" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="1338.1" cy="1494.0" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="1356.5" cy="1357.6" r="2" fill="#d62728" opacity="0.25"/>
<circle cx="1375.0" cy="1357.6" r="2" fill="#d62728" opacity="0.25"/>
<polyline points="747.0,1325.8 765.5,1266.7 783.9,1425.8 802.4,1462.2 820.9,1464.5 839.4,1423.5 857.8,1457.6 876.3,1423.5 894.8,1457.6 913.2,1444.0 931.7,1428.1 950.2,1344.0 968.6,1357.6 987.1,1491.7 1005.6,1357.6 1024.1,1357.6 1042.5,1453.1 1061.0,1257.6 1079.5,1494.0 1097.9,1494.0 1116.4,1448.5 1134.9,1494.0 1153.4,1357.6 1171.8,1357.6 1190.3,1350.8 1208.8,1357.6 1227.2,1357.6 1245.7,1357.6 1264.2,1444.0 1282.6,1346.3 1301.1,1357.6 1319.6,1200.8 1338.1,1494.0 1356.5,1357.6 1375.0,1357.6" fill="none" stroke="#d62728" stroke-width="2.5" opacity="1.0"/>
<circle cx="747.0" cy="1469.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="765.5" cy="1473.5" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="783.9" cy="1444.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="802.4" cy="1430.4" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="820.9" cy="1439.5" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="839.4" cy="1350.8" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="857.8" cy="1396.3" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="876.3" cy="1384.9" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="894.8" cy="1391.7" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="913.2" cy="1221.3" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="931.7" cy="1425.8" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="950.2" cy="1334.9" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="968.6" cy="1337.2" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="987.1" cy="1339.5" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="1005.6" cy="1341.7" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="1024.1" cy="1323.5" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="1042.5" cy="1348.5" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="1061.0" cy="1346.3" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="1079.5" cy="1444.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="1097.9" cy="1341.7" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="1116.4" cy="1337.2" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="1134.9" cy="1348.5" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="1153.4" cy="1344.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="1171.8" cy="1353.1" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="1190.3" cy="1350.8" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="1208.8" cy="1348.5" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="1227.2" cy="1344.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="1245.7" cy="1344.0" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="1264.2" cy="1332.6" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="1282.6" cy="1353.1" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="1301.1" cy="1348.5" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="1319.6" cy="1353.1" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="1338.1" cy="1357.6" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="1356.5" cy="1339.5" r="2" fill="#1f77b4" opacity="0.25"/>
<circle cx="1375.0" cy="1323.5" r="2" fill="#1f77b4" opacity="0.25"/>
<polyline points="747.0,1469.0 765.5,1473.5 783.9,1444.0 802.4,1430.4 820.9,1439.5 839.4,1350.8 857.8,1396.3 876.3,1384.9 894.8,1391.7 913.2,1221.3 931.7,1425.8 950.2,1334.9 968.6,1337.2 987.1,1339.5 1005.6,1341.7 1024.1,1323.5 1042.5,1348.5 1061.0,1346.3 1079.5,1444.0 1097.9,1341.7 1116.4,1337.2 1134.9,1348.5 1153.4,1344.0 1171.8,1353.1 1190.3,1350.8 1208.8,1348.5 1227.2,1344.0 1245.7,1344.0 1264.2,1332.6 1282.6,1353.1 1301.1,1348.5 1319.6,1353.1 1338.1,1357.6 1356.5,1339.5 1375.0,1323.5" fill="none" stroke="#1f77b4" stroke-width="2.5" opacity="1.0"/>
<circle cx="747.0" cy="1284.9" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="765.5" cy="1289.5" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="783.9" cy="1284.9" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="802.4" cy="1414.5" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="820.9" cy="1466.7" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="839.4" cy="1425.8" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="857.8" cy="1066.7" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="876.3" cy="1421.3" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="894.8" cy="1434.9" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="913.2" cy="1344.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="931.7" cy="1373.5" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="950.2" cy="1375.8" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="968.6" cy="1357.6" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="987.1" cy="1264.5" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="1005.6" cy="1357.6" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="1024.1" cy="1291.7" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="1042.5" cy="1355.4" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="1061.0" cy="1169.0" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="1079.5" cy="1105.4" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="1097.9" cy="1287.2" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="1116.4" cy="1291.7" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="1134.9" cy="1353.1" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="1153.4" cy="1303.1" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="1171.8" cy="1334.9" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="1190.3" cy="1412.2" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="1208.8" cy="1357.6" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="1227.2" cy="1421.3" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="1245.7" cy="1366.7" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="1264.2" cy="1382.6" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="1282.6" cy="1216.7" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="1301.1" cy="1357.6" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="1319.6" cy="1146.3" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="1338.1" cy="1307.6" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="1356.5" cy="1357.6" r="2" fill="#2ca02c" opacity="0.25"/>
<circle cx="1375.0" cy="1405.4" r="2" fill="#2ca02c" opacity="0.25"/>
<polyline points="747.0,1284.9 765.5,1289.5 783.9,1284.9 802.4,1414.5 820.9,1466.7 839.4,1425.8 857.8,1066.7 876.3,1421.3 894.8,1434.9 913.2,1344.0 931.7,1373.5 950.2,1375.8 968.6,1357.6 987.1,1264.5 1005.6,1357.6 1024.1,1291.7 1042.5,1355.4 1061.0,1169.0 1079.5,1105.4 1097.9,1287.2 1116.4,1291.7 1134.9,1353.1 1153.4,1303.1 1171.8,1334.9 1190.3,1412.2 1208.8,1357.6 1227.2,1421.3 1245.7,1366.7 1264.2,1382.6 1282.6,1216.7 1301.1,1357.6 1319.6,1146.3 1338.1,1307.6 1356.5,1357.6 1375.0,1405.4" fill="none" stroke="#2ca02c" stroke-width="2.5" opacity="1.0"/>
<polyline points="747.0,1284.9 765.5,1266.7 783.9,1284.9 802.4,1414.5 820.9,1439.5 839.4,1350.8 857.8,1066.7 876.3,1384.9 894.8,1391.7 913.2,1221.3 931.7,1373.5 950.2,1334.9 968.6,1337.2 987.1,1264.5 1005.6,1341.7 1024.1,1291.7 1042.5,1348.5 1061.0,1169.0 1079.5,1105.4 1097.9,1287.2 1116.4,1291.7 1134.9,1348.5 1153.4,1303.1 1171.8,1334.9 1190.3,1350.8 1208.8,1348.5 1227.2,1344.0 1245.7,1344.0 1264.2,1332.6 1282.6,1216.7 1301.1,1348.5 1319.6,1146.3 1338.1,1307.6 1356.5,1339.5 1375.0,1323.5" fill="none" stroke="#555555" stroke-width="2.5" opacity="1.0" stroke-dasharray="6 4"/>
<line x1="759" y1="1546" x2="787" y2="1546" stroke="#d62728" stroke-width="3"/> <line x1="759" y1="1546" x2="787" y2="1546" stroke="#d62728" stroke-width="3"/>
<text x="793" y="1550" font-size="12">Corners - 35 evals</text> <text x="793" y="1550" font-size="12">Corners - 5 evals</text>
<line x1="759" y1="1564" x2="787" y2="1564" stroke="#1f77b4" stroke-width="3"/> <line x1="759" y1="1564" x2="787" y2="1564" stroke="#1f77b4" stroke-width="3"/>
<text x="793" y="1568" font-size="12">Crazy - 35 evals</text> <text x="793" y="1568" font-size="12">Crazy - 5 evals</text>
<line x1="759" y1="1582" x2="787" y2="1582" stroke="#2ca02c" stroke-width="3"/> <line x1="759" y1="1582" x2="787" y2="1582" stroke="#2ca02c" stroke-width="3"/>
<text x="793" y="1586" font-size="12">Target - 35 evals</text> <text x="793" y="1586" font-size="12">Target - 5 evals</text>
<line x1="759" y1="1600" x2="787" y2="1600" stroke="#555555" stroke-width="3"/> <line x1="759" y1="1600" x2="787" y2="1600" stroke="#555555" stroke-width="3"/>
<text x="793" y="1604" font-size="12">combined max</text> <text x="793" y="1604" font-size="12">combined max</text>
<rect x="0" y="1645" width="1400" height="205" fill="#f2f2f2"/> <rect x="0" y="1645" width="1400" height="205" fill="#f2f2f2"/>

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 30 KiB

+71 -13
View File
@@ -28,11 +28,25 @@ import os
import re import re
import sys import sys
import tempfile import tempfile
import traceback
from datetime import datetime from datetime import datetime
from pathlib import Path from pathlib import Path
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
ROOT = Path(__file__).resolve().parent.parent ROOT = Path(__file__).resolve().parent.parent
LOG_FILE = ROOT / "tools" / "plot_progress.log"
def log(msg):
"""Timestamped line to stderr AND tools/plot_progress.log (survives reboots;
the watcher has no terminal to read errors from)."""
line = f"{datetime.now():%F %T} {msg}"
print(line)
try:
with open(LOG_FILE, "a") as fh:
fh.write(line + "\n")
except OSError:
pass
EVAL_RE = re.compile(r">>> \[eval\] win rate: (\d+)/(\d+) \(([\d.]+)%\) vs (\S+)") EVAL_RE = re.compile(r">>> \[eval\] win rate: (\d+)/(\d+) \(([\d.]+)%\) vs (\S+)")
EVAL_BLOCK_RE = re.compile(r">>> \[eval\] \d+ deterministic rounds vs (\S+)") EVAL_BLOCK_RE = re.compile(r">>> \[eval\] \d+ deterministic rounds vs (\S+)")
ROUND_RE = re.compile(r"Round \d+/\d+\D+ticks:\d+ score:(\d+) win:") ROUND_RE = re.compile(r"Round \d+/\d+\D+ticks:\d+ score:(\d+) win:")
@@ -235,8 +249,8 @@ def write_svg(path, text):
except ET.ParseError as e: except ET.ParseError as e:
print(f"[error] {path.name}: generated SVG invalid, keeping old file ({e})") print(f"[error] {path.name}: generated SVG invalid, keeping old file ({e})")
return False return False
tmp = path.with_name(path.name + ".tmp") tmp = path.with_name(f"{path.name}.{os.getpid()}.tmp") # unique: a manual
tmp.write_text(text) tmp.write_text(text) # run + watcher can race
os.replace(tmp, path) os.replace(tmp, path)
return True return True
@@ -302,7 +316,8 @@ def legend(items, x, y):
def map_fn(p0, p1, vmin, vmax, log=False): def map_fn(p0, p1, vmin, vmax, log=False):
def f(v): def f(v):
t = (math.log10(v) - vmin) / (vmax - vmin) if log else (v - vmin) / (vmax - vmin) span = (vmax - vmin) or 1 # single-point series -> degenerate range
t = (math.log10(v) - vmin) / span if log else (v - vmin) / span
return p0 + max(0.0, min(1.0, t)) * (p1 - p0) return p0 + max(0.0, min(1.0, t)) * (p1 - p0)
return f return f
@@ -354,7 +369,7 @@ def panel_test_matches(series, geo):
if not series: if not series:
s += f'<text x="{x0 + 10}" y="{pt + 40}" font-size="12" fill="#a00">' \ s += f'<text x="{x0 + 10}" y="{pt + 40}" font-size="12" fill="#a00">' \
"no eval lines found</text>\n" "no eval lines found</text>\n"
return return s
xmax = max(max(len(v) for v in series.values()), 2) xmax = max(max(len(v) for v in series.values()), 2)
xm, ym = map_fn(x0, x1, 1, xmax), map_fn(pb, pt, 0, 100) xm, ym = map_fn(x0, x1, 1, xmax), map_fn(pb, pt, 0, 100)
s += hgrid(x0, x1, [ym(v) for v in range(0, 101, 20)]) s += hgrid(x0, x1, [ym(v) for v in range(0, 101, 20)])
@@ -381,7 +396,7 @@ def panel_max_score(maxes, geo):
if not maxes: if not maxes:
s += f'<text x="{x0 + 10}" y="{pt + 40}" font-size="12" fill="#a00">' \ s += f'<text x="{x0 + 10}" y="{pt + 40}" font-size="12" fill="#a00">' \
"no eval lines found</text>\n" "no eval lines found</text>\n"
return return s
ncyc = max(len(v) for v in maxes.values()) ncyc = max(len(v) for v in maxes.values())
xmax = max(ncyc, 2) xmax = max(ncyc, 2)
hi = max(1, max(v for vals in maxes.values() for v in vals)) * 1.1 hi = max(1, max(v for vals in maxes.values() for v in vals)) * 1.1
@@ -421,11 +436,18 @@ def panel_losses(rows, geo):
if not (critic or actor or alpha): if not (critic or actor or alpha):
s += f'<text x="{x0 + 10}" y="{pt + 40}" font-size="12" fill="#a00">' \ s += f'<text x="{x0 + 10}" y="{pt + 40}" font-size="12" fill="#a00">' \
"no valid loss points</text>\n" "no valid loss points</text>\n"
return return s
x1 -= 46 # room on the right for the twin alpha axis labels x1 -= 46 # room on the right for the twin alpha axis labels
n = len(rows) n = len(rows)
xm = lambda i: x0 + (x1 - x0) * i / max(n - 1, 1) xm = lambda i: x0 + (x1 - x0) * i / max(n - 1, 1)
base = critic + actor or alpha # log-domain source (losses in practice) # log-domain source (losses in practice); drop non-positive values so a
# run of alpha==0 rows can't raise math domain error and kill the build
base = [(i, v) for i, v in critic + actor if v > 0] or \
[(i, v) for i, v in alpha if v > 0]
if not base:
s += f'<text x="{x0 + 10}" y="{pt + 40}" font-size="12" fill="#a00">' \
"no valid loss points</text>\n"
return s
lo = math.floor(math.log10(min(v for _, v in base))) lo = math.floor(math.log10(min(v for _, v in base)))
hi = math.ceil(math.log10(max(v for _, v in base))) hi = math.ceil(math.log10(max(v for _, v in base)))
if lo == hi: if lo == hi:
@@ -473,7 +495,7 @@ def panel_throughput(rows, geo):
if not rates: if not rates:
s += f'<text x="{x0 + 10}" y="{pt + 40}" font-size="12" fill="#a00">' \ s += f'<text x="{x0 + 10}" y="{pt + 40}" font-size="12" fill="#a00">' \
"no usable epoch timestamps</text>\n" "no usable epoch timestamps</text>\n"
return return s
bm = bucket_means(rates, RATE_BUCKET) bm = bucket_means(rates, RATE_BUCKET)
xm = map_fn(x0, x1, 1, len(rates)) xm = map_fn(x0, x1, 1, len(rates))
ymax = max(max(rates), max(bm)) * 1.1 ymax = max(max(rates), max(bm)) * 1.1
@@ -528,7 +550,13 @@ def build_dashboard(campaign, metrics_f, out):
for geo, title, guide, sub, drawer in drawers: for geo, title, guide, sub, drawer in drawers:
s += header(geo[3], geo[0], title, sub) s += header(geo[3], geo[0], title, sub)
s += panel_guide(geo[3], geo[0] + 33, guide) s += panel_guide(geo[3], geo[0] + 33, guide)
s += drawer() or "" # panels bare-return None on their no-data path try:
body = drawer()
except Exception as e: # one bad panel must not kill the whole page
log(f"[warn] panel '{title}' failed, rendering placeholder: {e}")
body = (f'<text x="{geo[3] + 10}" y="{geo[1] + 40}" font-size="12" '
f'fill="#a00">panel error: {esc(e)}</text>')
s += body or "" # panels bare-return None on their no-data path
s += signs_block() s += signs_block()
s += RELOAD_JS + "\n" s += RELOAD_JS + "\n"
@@ -625,6 +653,32 @@ def selftest():
(xa, ya), (xb, yb) = pts (xa, ya), (xb, yb) = pts
assert yb < ya, f"y-axis inverted: win % rose 10->90 but ink moved down ({ya} -> {yb})" assert yb < ya, f"y-axis inverted: win % rose 10->90 but ink moved down ({ya} -> {yb})"
assert xb > xa, f"x-axis reversed: newer eval plotted left ({xa} -> {xb})" assert xb > xa, f"x-axis reversed: newer eval plotted left ({xa} -> {xb})"
# resilience: missing/empty inputs render placeholders, never crash
empty_dash = td / "empty.svg"
assert build_dashboard(td / "nope.log", td / "nope.jsonl", empty_dash)
etext = empty_dash.read_text()
assert etext.count("no eval lines found") == 2, etext.count("no eval lines found")
assert "no valid loss points" in etext
assert "no usable epoch timestamps" in etext
# all-zero alpha rows (post-crash trainer state) must not raise in the
# losses panel's log-domain math -> placeholder instead of dead build
(td / "zero.jsonl").write_text(
'{"epoch": 1000.0, "alpha": 0}\n{"epoch": 1060.0, "alpha": 0}\n')
zero_dash = td / "zero.svg"
assert build_dashboard(td / "log", td / "zero.jsonl", zero_dash)
assert "no valid loss points" in zero_dash.read_text()
# single throughput interval (fresh 2-row metrics file right after a
# restart) used to divide by zero in map_fn and kill the whole build
(td / "one.jsonl").write_text(
'{"epoch": 1000.0, "critic_loss": 10, "alpha": 0.5}\n'
'{"epoch": 1060.0, "critic_loss": 5, "alpha": 0.4}\n')
one_dash = td / "one.svg"
assert build_dashboard(td / "log", td / "one.jsonl", one_dash)
assert "panel error" not in one_dash.read_text()
assert "<polyline" in one_dash.read_text()
print("selftest OK") print("selftest OK")
@@ -636,17 +690,21 @@ def main():
campaign = Path(args[0]) if len(args) > 0 else ROOT / "campaign_v4_stdout.log" campaign = Path(args[0]) if len(args) > 0 else ROOT / "campaign_v4_stdout.log"
metrics = Path(args[1]) if len(args) > 1 else ROOT / "training_metrics.jsonl" metrics = Path(args[1]) if len(args) > 1 else ROOT / "training_metrics.jsonl"
outdir = Path(args[2]) if len(args) > 2 else ROOT / "docs" outdir = Path(args[2]) if len(args) > 2 else ROOT / "docs"
outdir.mkdir(parents=True, exist_ok=True)
try: try:
outdir.mkdir(parents=True, exist_ok=True)
for p in (campaign, metrics):
if not p.is_file():
# loudest symptom of a watcher launched from a stale checkout
log(f"[warn] input missing: {p} - is this the live checkout?")
ok = build_dashboard(campaign, metrics, outdir / "campaign_dashboard.svg") ok = build_dashboard(campaign, metrics, outdir / "campaign_dashboard.svg")
except Exception as e: except Exception:
print(f"[error] dashboard build failed: {e}") log(f"[error] dashboard build failed:\n{traceback.format_exc().rstrip()}")
ok = False ok = False
if ok: if ok:
print(f"[done] dashboard written to {outdir / 'campaign_dashboard.svg'}") print(f"[done] dashboard written to {outdir / 'campaign_dashboard.svg'}")
else: else:
print("[error] dashboard NOT updated - check paths above") print("[error] dashboard NOT updated - see " + str(LOG_FILE))
sys.exit(1) sys.exit(1)
+16 -3
View File
@@ -1,10 +1,23 @@
#!/bin/sh #!/bin/sh
# Keep docs/campaign_dashboard.svg fresh: regenerate every 60 s. # Keep docs/campaign_dashboard.svg fresh: regenerate every 60 s.
# Errors go to stderr and never exit the loop silently. # Failures are appended to tools/plot_progress.log (by this wrapper and by
dir=$(dirname "$0") # plot_progress.py itself) - check that file when the dashboard looks stale.
# The startup banner records WHICH tree this instance watches, so a copy
# launched from a stale checkout (the post-reboot failure mode) is visible.
set -u
dir=$(cd "$(dirname "$0")" && pwd)
log="$dir/plot_progress.log"
if command -v flock >/dev/null 2>&1; then
exec 9>"$dir/.watch_dashboard.lock"
flock -n 9 || { echo "[watch_dashboard] another instance already running, exiting" >&2; exit 0; }
fi
echo "[watch_dashboard] $(date '+%F %T') started, watching root=$(cd "$dir/.." && pwd)" >> "$log" 2>/dev/null || true
while :; do while :; do
if ! python3 "$dir/plot_progress.py"; then if ! python3 "$dir/plot_progress.py"; then
echo "[watch_dashboard] $(date '+%F %T') regeneration failed (see error above)" >&2 echo "[watch_dashboard] $(date '+%F %T') regeneration failed (see $log)" >&2
echo "[watch_dashboard] $(date '+%F %T') regeneration failed" >> "$log" 2>/dev/null || true
fi fi
sleep 60 sleep 60
done done