pwn 0.5.677 → 0.5.679

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/documentation/AI-Integration.md +4 -3
  4. data/documentation/Agent-Tool-Registry.md +27 -5
  5. data/documentation/CLI-Drivers.md +1 -1
  6. data/documentation/Configuration.md +65 -25
  7. data/documentation/Cron.md +12 -2
  8. data/documentation/Home.md +1 -1
  9. data/documentation/How-PWN-Works.md +1 -1
  10. data/documentation/Installation.md +12 -7
  11. data/documentation/Reinforcement-Learning.md +10 -6
  12. data/documentation/Skills-Memory-Learning.md +1 -1
  13. data/documentation/What-is-PWN.md +1 -1
  14. data/documentation/diagrams/agent-tool-registry.svg +156 -147
  15. data/documentation/diagrams/cron-scheduling.svg +149 -126
  16. data/documentation/diagrams/dot/agent-tool-registry.dot +2 -1
  17. data/documentation/diagrams/dot/cron-scheduling.dot +6 -3
  18. data/documentation/diagrams/dot/pwn-ai-feedback-learning-loop.dot +1 -1
  19. data/documentation/diagrams/pwn-ai-feedback-learning-loop.svg +14 -13
  20. data/documentation/pwn-REPL.md +1 -1
  21. data/documentation/pwn-ai-Agent.md +16 -9
  22. data/lib/pwn/ai/agent/policy.rb +9 -3
  23. data/lib/pwn/ai/agent/registry.rb +95 -6
  24. data/lib/pwn/ai/anthropic.rb +2 -6
  25. data/lib/pwn/ai/gemini.rb +2 -6
  26. data/lib/pwn/ai/grok.rb +7 -8
  27. data/lib/pwn/ai/ollama.rb +2 -6
  28. data/lib/pwn/ai/open_ai.rb +2 -6
  29. data/lib/pwn/ai/open_web_ui.rb +2 -6
  30. data/lib/pwn/blockchain/btc.rb +2 -6
  31. data/lib/pwn/blockchain/eth.rb +2 -6
  32. data/lib/pwn/config.rb +4 -3
  33. data/lib/pwn/plugins/black_duck_binary_analysis.rb +2 -4
  34. data/lib/pwn/plugins/jira_data_center.rb +2 -4
  35. data/lib/pwn/plugins/repl.rb +12 -6
  36. data/lib/pwn/plugins/tty_spinner.rb +75 -0
  37. data/lib/pwn/plugins.rb +1 -0
  38. data/lib/pwn/version.rb +1 -1
  39. data/spec/lib/pwn/ai/agent/registry_spec.rb +6 -0
  40. data/spec/lib/pwn/ai/grok_spec.rb +7 -0
  41. data/spec/lib/pwn/plugins/tty_spinner_spec.rb +61 -0
  42. data/third_party/pwn_rdoc.jsonl +8 -2
  43. metadata +3 -1
@@ -4,245 +4,268 @@
4
4
  <!-- Generated by graphviz version 14.1.2 (0)
5
5
  -->
6
6
  <!-- Title: PWN_Cron Pages: 1 -->
7
- <svg width="1575pt" height="617pt"
8
- viewBox="0.00 0.00 1575.00 617.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
7
+ <svg width="1605pt" height="617pt"
8
+ viewBox="0.00 0.00 1605.00 617.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
9
9
  <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(43.2 574.2)">
10
10
  <title>PWN_Cron</title>
11
- <polygon fill="#0f172a" stroke="none" points="-43.2,43.2 -43.2,-574.2 1531.7,-574.2 1531.7,43.2 -43.2,43.2"/>
12
- <text xml:space="preserve" text-anchor="start" x="542.88" y="-509" font-family="sans-Serif" font-weight="bold" font-size="20.00" fill="#e2e8f0">PWN::Cron &#45; Scheduled Autonomous Jobs</text>
13
- <text xml:space="preserve" text-anchor="start" x="516.25" y="-497.55" font-family="sans-Serif" font-size="11.00" fill="#94a3b8">prompt · ruby · script → jobs.yml → crontab → pwn&#45;ai &#160;· &#160;seeded self&#45;improvement (Curriculum)</text>
11
+ <polygon fill="#0f172a" stroke="none" points="-43.2,43.2 -43.2,-574.2 1561.7,-574.2 1561.7,43.2 -43.2,43.2"/>
12
+ <text xml:space="preserve" text-anchor="start" x="557.88" y="-509" font-family="sans-Serif" font-weight="bold" font-size="20.00" fill="#e2e8f0">PWN::Cron &#45; Scheduled Autonomous Jobs</text>
13
+ <text xml:space="preserve" text-anchor="start" x="532.75" y="-497.55" font-family="sans-Serif" font-size="11.00" fill="#94a3b8">prompt · ruby · script → jobs.yml → worker → pwn&#45;ai &#160;· &#160;seeded self&#45;improvement (Curriculum)</text>
14
14
  <g id="clust2" class="cluster">
15
15
  <title>cluster_kinds</title>
16
- <path fill="#022c22" stroke="#047857" stroke-width="2" d="M844,-257C844,-257 998.25,-257 998.25,-257 1004.25,-257 1010.25,-263 1010.25,-269 1010.25,-269 1010.25,-472 1010.25,-472 1010.25,-478 1004.25,-484 998.25,-484 998.25,-484 844,-484 844,-484 838,-484 832,-478 832,-472 832,-472 832,-269 832,-269 832,-263 838,-257 844,-257"/>
17
- <text xml:space="preserve" text-anchor="middle" x="921.12" y="-461" font-family="sans-Serif" font-size="20.00" fill="#a7f3d0">Job Kinds</text>
16
+ <path fill="#022c22" stroke="#047857" stroke-width="2" d="M874,-257C874,-257 1028.25,-257 1028.25,-257 1034.25,-257 1040.25,-263 1040.25,-269 1040.25,-269 1040.25,-472 1040.25,-472 1040.25,-478 1034.25,-484 1028.25,-484 1028.25,-484 874,-484 874,-484 868,-484 862,-478 862,-472 862,-472 862,-269 862,-269 862,-263 868,-257 874,-257"/>
17
+ <text xml:space="preserve" text-anchor="middle" x="951.12" y="-461" font-family="sans-Serif" font-size="20.00" fill="#a7f3d0">Job Kinds</text>
18
18
  </g>
19
19
  <g id="clust4" class="cluster">
20
20
  <title>cluster_seed</title>
21
- <path fill="#2e1065" stroke="#6d28d9" stroke-width="2" d="M1101.25,-8C1101.25,-8 1476.5,-8 1476.5,-8 1482.5,-8 1488.5,-14 1488.5,-20 1488.5,-20 1488.5,-359 1488.5,-359 1488.5,-365 1482.5,-371 1476.5,-371 1476.5,-371 1101.25,-371 1101.25,-371 1095.25,-371 1089.25,-365 1089.25,-359 1089.25,-359 1089.25,-20 1089.25,-20 1089.25,-14 1095.25,-8 1101.25,-8"/>
22
- <text xml:space="preserve" text-anchor="middle" x="1288.88" y="-348" font-family="sans-Serif" font-size="20.00" fill="#ddd6fe">Seeded Self&#45;Improvement (install_defaults)</text>
21
+ <path fill="#2e1065" stroke="#6d28d9" stroke-width="2" d="M1131.25,-8C1131.25,-8 1506.5,-8 1506.5,-8 1512.5,-8 1518.5,-14 1518.5,-20 1518.5,-20 1518.5,-359 1518.5,-359 1518.5,-365 1512.5,-371 1506.5,-371 1506.5,-371 1131.25,-371 1131.25,-371 1125.25,-371 1119.25,-365 1119.25,-359 1119.25,-359 1119.25,-20 1119.25,-20 1119.25,-14 1125.25,-8 1131.25,-8"/>
22
+ <text xml:space="preserve" text-anchor="middle" x="1318.88" y="-348" font-family="sans-Serif" font-size="20.00" fill="#ddd6fe">Seeded Self&#45;Improvement (install_defaults)</text>
23
23
  </g>
24
24
  <!-- Create -->
25
25
  <g id="node1" class="node">
26
26
  <title>Create</title>
27
- <path fill="#7dd3fc" stroke="#334155" stroke-width="1.4" d="M118,-413.25C118,-413.25 27.75,-413.25 27.75,-413.25 21.75,-413.25 15.75,-407.25 15.75,-401.25 15.75,-401.25 15.75,-376.75 15.75,-376.75 15.75,-370.75 21.75,-364.75 27.75,-364.75 27.75,-364.75 118,-364.75 118,-364.75 124,-364.75 130,-370.75 130,-376.75 130,-376.75 130,-401.25 130,-401.25 130,-407.25 124,-413.25 118,-413.25"/>
28
- <text xml:space="preserve" text-anchor="middle" x="72.88" y="-398.8" font-family="sans-Serif" font-size="11.00" fill="#0f172a">cron_create</text>
29
- <text xml:space="preserve" text-anchor="middle" x="72.88" y="-385.3" font-family="sans-Serif" font-size="11.00" fill="#0f172a">name · schedule</text>
30
- <text xml:space="preserve" text-anchor="middle" x="72.88" y="-371.8" font-family="sans-Serif" font-size="11.00" fill="#0f172a">prompt | ruby | script</text>
27
+ <path fill="#7dd3fc" stroke="#334155" stroke-width="1.4" d="M118,-440.25C118,-440.25 27.75,-440.25 27.75,-440.25 21.75,-440.25 15.75,-434.25 15.75,-428.25 15.75,-428.25 15.75,-403.75 15.75,-403.75 15.75,-397.75 21.75,-391.75 27.75,-391.75 27.75,-391.75 118,-391.75 118,-391.75 124,-391.75 130,-397.75 130,-403.75 130,-403.75 130,-428.25 130,-428.25 130,-434.25 124,-440.25 118,-440.25"/>
28
+ <text xml:space="preserve" text-anchor="middle" x="72.88" y="-425.8" font-family="sans-Serif" font-size="11.00" fill="#0f172a">cron_create</text>
29
+ <text xml:space="preserve" text-anchor="middle" x="72.88" y="-412.3" font-family="sans-Serif" font-size="11.00" fill="#0f172a">name · schedule</text>
30
+ <text xml:space="preserve" text-anchor="middle" x="72.88" y="-398.8" font-family="sans-Serif" font-size="11.00" fill="#0f172a">prompt | ruby | script</text>
31
31
  </g>
32
32
  <!-- Jobs -->
33
33
  <g id="node3" class="node">
34
34
  <title>Jobs</title>
35
- <path fill="#fcd34d" stroke="#334155" stroke-width="1.4" d="M424.12,-321.73C424.12,-323.53 398.35,-325 366.62,-325 334.9,-325 309.12,-323.53 309.12,-321.73 309.12,-321.73 309.12,-292.27 309.12,-292.27 309.12,-290.47 334.9,-289 366.62,-289 398.35,-289 424.12,-290.47 424.12,-292.27 424.12,-292.27 424.12,-321.73 424.12,-321.73"/>
36
- <path fill="none" stroke="#334155" stroke-width="1.4" d="M424.12,-321.73C424.12,-319.92 398.35,-318.45 366.62,-318.45 334.9,-318.45 309.12,-319.92 309.12,-321.73"/>
37
- <text xml:space="preserve" text-anchor="middle" x="366.62" y="-303.3" font-family="sans-Serif" font-size="11.00" fill="#0f172a">~/.pwn/cron/jobs.yml</text>
35
+ <path fill="#fcd34d" stroke="#334155" stroke-width="1.4" d="M439.12,-392.73C439.12,-394.53 413.35,-396 381.62,-396 349.9,-396 324.12,-394.53 324.12,-392.73 324.12,-392.73 324.12,-363.27 324.12,-363.27 324.12,-361.47 349.9,-360 381.62,-360 413.35,-360 439.12,-361.47 439.12,-363.27 439.12,-363.27 439.12,-392.73 439.12,-392.73"/>
36
+ <path fill="none" stroke="#334155" stroke-width="1.4" d="M439.12,-392.73C439.12,-390.92 413.35,-389.45 381.62,-389.45 349.9,-389.45 324.12,-390.92 324.12,-392.73"/>
37
+ <text xml:space="preserve" text-anchor="middle" x="381.62" y="-374.3" font-family="sans-Serif" font-size="11.00" fill="#0f172a">~/.pwn/cron/jobs.yml</text>
38
38
  </g>
39
39
  <!-- Create&#45;&gt;Jobs -->
40
40
  <g id="edge1" class="edge">
41
41
  <title>Create&#45;&gt;Jobs</title>
42
- <path fill="none" stroke="#38bdf8" stroke-width="1.3" d="M130.47,-373.09C178.83,-359.5 248.46,-339.93 299.4,-325.61"/>
43
- <polygon fill="#38bdf8" stroke="#38bdf8" stroke-width="1.3" points="299.85,-328.4 306.79,-323.54 298.33,-323 299.85,-328.4"/>
44
- <text xml:space="preserve" text-anchor="middle" x="226.88" y="-357.29" font-family="sans-Serif" font-size="9.00" fill="#cbd5e1">write</text>
42
+ <path fill="none" stroke="#38bdf8" stroke-width="1.3" d="M130.5,-408.99C182.35,-402.56 259.13,-393.05 313.93,-386.26"/>
43
+ <polygon fill="#38bdf8" stroke="#38bdf8" stroke-width="1.3" points="314.01,-389.07 321.6,-385.31 313.32,-383.52 314.01,-389.07"/>
44
+ <text xml:space="preserve" text-anchor="middle" x="226.88" y="-402.35" font-family="sans-Serif" font-size="9.00" fill="#cbd5e1">write</text>
45
45
  </g>
46
46
  <!-- Crontab -->
47
47
  <g id="node4" class="node">
48
48
  <title>Crontab</title>
49
- <path fill="#fda4af" stroke="#334155" stroke-width="1.4" d="M413.25,-420C413.25,-420 320,-420 320,-420 314,-420 308,-414 308,-408 308,-408 308,-396 308,-396 308,-390 314,-384 320,-384 320,-384 413.25,-384 413.25,-384 419.25,-384 425.25,-390 425.25,-396 425.25,-396 425.25,-408 425.25,-408 425.25,-414 419.25,-420 413.25,-420"/>
50
- <text xml:space="preserve" text-anchor="middle" x="366.62" y="-405.05" font-family="sans-Serif" font-size="11.00" fill="#0f172a">system crontab</text>
51
- <text xml:space="preserve" text-anchor="middle" x="366.62" y="-391.55" font-family="sans-Serif" font-size="11.00" fill="#0f172a">(install_crontab: true)</text>
49
+ <path fill="#fda4af" stroke="#334155" stroke-width="1.4" d="M428.25,-468C428.25,-468 335,-468 335,-468 329,-468 323,-462 323,-456 323,-456 323,-444 323,-444 323,-438 329,-432 335,-432 335,-432 428.25,-432 428.25,-432 434.25,-432 440.25,-438 440.25,-444 440.25,-444 440.25,-456 440.25,-456 440.25,-462 434.25,-468 428.25,-468"/>
50
+ <text xml:space="preserve" text-anchor="middle" x="381.62" y="-453.05" font-family="sans-Serif" font-size="11.00" fill="#0f172a">per&#45;job crontab</text>
51
+ <text xml:space="preserve" text-anchor="middle" x="381.62" y="-439.55" font-family="sans-Serif" font-size="11.00" fill="#0f172a">(install_crontab: true)</text>
52
52
  </g>
53
53
  <!-- Create&#45;&gt;Crontab -->
54
54
  <g id="edge3" class="edge">
55
55
  <title>Create&#45;&gt;Crontab</title>
56
- <path fill="none" stroke="#fb7185" stroke-width="1.3" d="M130.47,-391.52C178.24,-393.65 246.77,-396.7 297.53,-398.97"/>
57
- <polygon fill="#fb7185" stroke="#fb7185" stroke-width="1.3" points="297.35,-401.76 305.47,-399.32 297.6,-396.17 297.35,-401.76"/>
58
- <text xml:space="preserve" text-anchor="middle" x="226.88" y="-399" font-family="sans-Serif" font-size="9.00" fill="#cbd5e1">append</text>
56
+ <path fill="none" stroke="#fb7185" stroke-width="1.3" d="M130.5,-422.28C182.02,-427.99 258.16,-436.43 312.89,-442.49"/>
57
+ <polygon fill="#fb7185" stroke="#fb7185" stroke-width="1.3" points="312.3,-445.24 320.56,-443.34 312.91,-439.68 312.3,-445.24"/>
58
+ <text xml:space="preserve" text-anchor="middle" x="226.88" y="-438" font-family="sans-Serif" font-size="9.00" fill="#cbd5e1">optional per&#45;job</text>
59
59
  </g>
60
60
  <!-- Seed -->
61
61
  <g id="node2" class="node">
62
62
  <title>Seed</title>
63
- <path fill="#7dd3fc" stroke="#334155" stroke-width="1.4" d="M133.75,-316C133.75,-316 12,-316 12,-316 6,-316 0,-310 0,-304 0,-304 0,-292 0,-292 0,-286 6,-280 12,-280 12,-280 133.75,-280 133.75,-280 139.75,-280 145.75,-286 145.75,-292 145.75,-292 145.75,-304 145.75,-304 145.75,-310 139.75,-316 133.75,-316"/>
64
- <text xml:space="preserve" text-anchor="middle" x="72.88" y="-301.05" font-family="sans-Serif" font-size="11.00" fill="#0f172a">PWN::Cron.install_defaults</text>
65
- <text xml:space="preserve" text-anchor="middle" x="72.88" y="-287.55" font-family="sans-Serif" font-size="11.00" fill="#0f172a">(pwn setup &#45;&#45;migrate)</text>
63
+ <path fill="#7dd3fc" stroke="#334155" stroke-width="1.4" d="M133.75,-343C133.75,-343 12,-343 12,-343 6,-343 0,-337 0,-331 0,-331 0,-319 0,-319 0,-313 6,-307 12,-307 12,-307 133.75,-307 133.75,-307 139.75,-307 145.75,-313 145.75,-319 145.75,-319 145.75,-331 145.75,-331 145.75,-337 139.75,-343 133.75,-343"/>
64
+ <text xml:space="preserve" text-anchor="middle" x="72.88" y="-328.05" font-family="sans-Serif" font-size="11.00" fill="#0f172a">PWN::Cron.install_defaults</text>
65
+ <text xml:space="preserve" text-anchor="middle" x="72.88" y="-314.55" font-family="sans-Serif" font-size="11.00" fill="#0f172a">(pwn setup &#45;&#45;migrate)</text>
66
66
  </g>
67
67
  <!-- Seed&#45;&gt;Jobs -->
68
68
  <g id="edge2" class="edge">
69
69
  <title>Seed&#45;&gt;Jobs</title>
70
- <path fill="none" stroke="#38bdf8" stroke-width="1.3" d="M146.33,-296.19C181.04,-295.74 223.19,-295.79 261,-297.5 273.22,-298.05 286.22,-298.97 298.75,-300.02"/>
71
- <polygon fill="#38bdf8" stroke="#38bdf8" stroke-width="1.3" points="298.5,-302.81 306.71,-300.71 298.99,-297.23 298.5,-302.81"/>
72
- <text xml:space="preserve" text-anchor="middle" x="226.88" y="-299.45" font-family="sans-Serif" font-size="9.00" fill="#cbd5e1">idempotent seed</text>
70
+ <path fill="none" stroke="#38bdf8" stroke-width="1.3" d="M146.18,-337.49C197,-346.27 264.47,-357.93 313.98,-366.48"/>
71
+ <polygon fill="#38bdf8" stroke="#38bdf8" stroke-width="1.3" points="313.33,-369.21 321.69,-367.82 314.29,-363.7 313.33,-369.21"/>
72
+ <text xml:space="preserve" text-anchor="middle" x="226.88" y="-358.2" font-family="sans-Serif" font-size="9.00" fill="#cbd5e1">idempotent seed</text>
73
73
  </g>
74
- <!-- Runner -->
74
+ <!-- Worker -->
75
75
  <g id="node5" class="node">
76
+ <title>Worker</title>
77
+ <path fill="#fda4af" stroke="#334155" stroke-width="1.4" d="M443.25,-324C443.25,-324 320,-324 320,-324 314,-324 308,-318 308,-312 308,-312 308,-274 308,-274 308,-268 314,-262 320,-262 320,-262 443.25,-262 443.25,-262 449.25,-262 455.25,-268 455.25,-274 455.25,-274 455.25,-312 455.25,-312 455.25,-318 449.25,-324 443.25,-324"/>
78
+ <text xml:space="preserve" text-anchor="middle" x="381.62" y="-309.55" font-family="sans-Serif" font-size="11.00" fill="#0f172a">background worker</text>
79
+ <text xml:space="preserve" text-anchor="middle" x="381.62" y="-296.05" font-family="sans-Serif" font-size="11.00" fill="#0f172a">pwn setup keep&#45;alive</text>
80
+ <text xml:space="preserve" text-anchor="middle" x="381.62" y="-282.55" font-family="sans-Serif" font-size="11.00" fill="#0f172a">systemd &#45;&#45;user / launchd</text>
81
+ <text xml:space="preserve" text-anchor="middle" x="381.62" y="-269.05" font-family="sans-Serif" font-size="11.00" fill="#0f172a">schtasks / crontab @reboot</text>
82
+ </g>
83
+ <!-- Seed&#45;&gt;Worker -->
84
+ <g id="edge4" class="edge">
85
+ <title>Seed&#45;&gt;Worker</title>
86
+ <path fill="none" stroke="#fb7185" stroke-width="1.3" d="M130.08,-306.33C149.68,-300.71 171.97,-295.29 192.75,-292.5 227.03,-287.9 265.14,-287.19 298.03,-287.95"/>
87
+ <polygon fill="#fb7185" stroke="#fb7185" stroke-width="1.3" points="297.57,-290.74 305.64,-288.16 297.72,-285.14 297.57,-290.74"/>
88
+ <text xml:space="preserve" text-anchor="middle" x="226.88" y="-294.45" font-family="sans-Serif" font-size="9.00" fill="#cbd5e1">pwn setup</text>
89
+ </g>
90
+ <!-- Runner -->
91
+ <g id="node6" class="node">
76
92
  <title>Runner</title>
77
- <path fill="#c4b5fd" stroke="#334155" stroke-width="1.4" d="M679.25,-373C679.25,-373 596.5,-373 596.5,-373 590.5,-373 584.5,-367 584.5,-361 584.5,-361 584.5,-349 584.5,-349 584.5,-343 590.5,-337 596.5,-337 596.5,-337 679.25,-337 679.25,-337 685.25,-337 691.25,-343 691.25,-349 691.25,-349 691.25,-361 691.25,-361 691.25,-367 685.25,-373 679.25,-373"/>
78
- <text xml:space="preserve" text-anchor="middle" x="637.88" y="-351.3" font-family="sans-Serif" font-size="11.00" fill="#0f172a">PWN::Cron.run(id)</text>
93
+ <path fill="#c4b5fd" stroke="#334155" stroke-width="1.4" d="M709.25,-373C709.25,-373 626.5,-373 626.5,-373 620.5,-373 614.5,-367 614.5,-361 614.5,-361 614.5,-349 614.5,-349 614.5,-343 620.5,-337 626.5,-337 626.5,-337 709.25,-337 709.25,-337 715.25,-337 721.25,-343 721.25,-349 721.25,-349 721.25,-361 721.25,-361 721.25,-367 715.25,-373 709.25,-373"/>
94
+ <text xml:space="preserve" text-anchor="middle" x="667.88" y="-351.3" font-family="sans-Serif" font-size="11.00" fill="#0f172a">PWN::Cron.run(id)</text>
79
95
  </g>
80
96
  <!-- Jobs&#45;&gt;Runner -->
81
- <g id="edge5" class="edge">
97
+ <g id="edge7" class="edge">
82
98
  <title>Jobs&#45;&gt;Runner</title>
83
- <path fill="none" stroke="#f59e0b" stroke-width="1.3" d="M424.73,-317.18C468.59,-325 529.11,-335.79 574.29,-343.84"/>
84
- <polygon fill="#f59e0b" stroke="#f59e0b" stroke-width="1.3" points="573.67,-346.58 582.03,-345.22 574.65,-341.06 573.67,-346.58"/>
85
- <text xml:space="preserve" text-anchor="middle" x="504.88" y="-338.66" font-family="sans-Serif" font-size="9.00" fill="#cbd5e1">load job</text>
99
+ <path fill="none" stroke="#f59e0b" stroke-width="1.3" d="M439.81,-373.37C487.43,-369.52 555.15,-364.04 604.24,-360.07"/>
100
+ <polygon fill="#f59e0b" stroke="#f59e0b" stroke-width="1.3" points="604.39,-362.86 612.14,-359.43 603.94,-357.28 604.39,-362.86"/>
101
+ <text xml:space="preserve" text-anchor="middle" x="534.88" y="-369.83" font-family="sans-Serif" font-size="9.00" fill="#cbd5e1">load job</text>
86
102
  </g>
87
103
  <!-- Crontab&#45;&gt;Runner -->
88
- <g id="edge4" class="edge">
104
+ <g id="edge5" class="edge">
89
105
  <title>Crontab&#45;&gt;Runner</title>
90
- <path fill="none" stroke="#fb7185" stroke-width="2" d="M425.72,-391.86C469.13,-384.28 528.45,-373.93 573.17,-366.12"/>
91
- <polygon fill="#fb7185" stroke="#fb7185" stroke-width="2" points="573.53,-368.9 580.93,-364.77 572.57,-363.38 573.53,-368.9"/>
92
- <text xml:space="preserve" text-anchor="middle" x="504.88" y="-384.66" font-family="sans-Serif" font-size="9.00" fill="#cbd5e1">fire on schedule</text>
106
+ <path fill="none" stroke="#fb7185" stroke-width="2" d="M440.92,-441.88C477.95,-435.63 526.46,-425.41 567.5,-410 589.04,-401.91 611.58,-389.77 629.74,-378.96"/>
107
+ <polygon fill="#fb7185" stroke="#fb7185" stroke-width="2" points="630.84,-381.56 636.23,-375.02 627.93,-376.78 630.84,-381.56"/>
108
+ <text xml:space="preserve" text-anchor="middle" x="534.88" y="-431.28" font-family="sans-Serif" font-size="9.00" fill="#cbd5e1">fire on schedule</text>
109
+ </g>
110
+ <!-- Worker&#45;&gt;Runner -->
111
+ <g id="edge6" class="edge">
112
+ <title>Worker&#45;&gt;Runner</title>
113
+ <path fill="none" stroke="#fb7185" stroke-width="2" d="M455.83,-308.97C501.57,-318.94 559.88,-331.66 603.61,-341.2"/>
114
+ <polygon fill="#fb7185" stroke="#fb7185" stroke-width="2" points="602.74,-343.88 611.16,-342.85 603.94,-338.41 602.74,-343.88"/>
115
+ <text xml:space="preserve" text-anchor="middle" x="534.88" y="-335.13" font-family="sans-Serif" font-size="9.00" fill="#cbd5e1">poll jobs.yml</text>
93
116
  </g>
94
117
  <!-- Prompt -->
95
- <g id="node6" class="node">
118
+ <g id="node7" class="node">
96
119
  <title>Prompt</title>
97
- <path fill="#6ee7b7" stroke="#334155" stroke-width="1.4" d="M962.88,-373C962.88,-373 879.38,-373 879.38,-373 873.38,-373 867.38,-367 867.38,-361 867.38,-361 867.38,-349 867.38,-349 867.38,-343 873.38,-337 879.38,-337 879.38,-337 962.88,-337 962.88,-337 968.88,-337 974.88,-343 974.88,-349 974.88,-349 974.88,-361 974.88,-361 974.88,-367 968.88,-373 962.88,-373"/>
98
- <text xml:space="preserve" text-anchor="middle" x="921.12" y="-358.05" font-family="sans-Serif" font-size="11.00" fill="#0f172a">:prompt</text>
99
- <text xml:space="preserve" text-anchor="middle" x="921.12" y="-344.55" font-family="sans-Serif" font-size="11.00" fill="#0f172a">→ pwn&#45;ai one&#45;shot</text>
120
+ <path fill="#6ee7b7" stroke="#334155" stroke-width="1.4" d="M992.88,-373C992.88,-373 909.38,-373 909.38,-373 903.38,-373 897.38,-367 897.38,-361 897.38,-361 897.38,-349 897.38,-349 897.38,-343 903.38,-337 909.38,-337 909.38,-337 992.88,-337 992.88,-337 998.88,-337 1004.88,-343 1004.88,-349 1004.88,-349 1004.88,-361 1004.88,-361 1004.88,-367 998.88,-373 992.88,-373"/>
121
+ <text xml:space="preserve" text-anchor="middle" x="951.12" y="-358.05" font-family="sans-Serif" font-size="11.00" fill="#0f172a">:prompt</text>
122
+ <text xml:space="preserve" text-anchor="middle" x="951.12" y="-344.55" font-family="sans-Serif" font-size="11.00" fill="#0f172a">→ pwn&#45;ai one&#45;shot</text>
100
123
  </g>
101
124
  <!-- Runner&#45;&gt;Prompt -->
102
- <g id="edge6" class="edge">
125
+ <g id="edge8" class="edge">
103
126
  <title>Runner&#45;&gt;Prompt</title>
104
- <path fill="none" stroke="#34d399" stroke-width="1.3" d="M691.78,-355C738.77,-355 807.52,-355 857.29,-355"/>
105
- <polygon fill="#34d399" stroke="#34d399" stroke-width="1.3" points="857.02,-357.8 865.02,-355 857.02,-352.2 857.02,-357.8"/>
127
+ <path fill="none" stroke="#34d399" stroke-width="1.3" d="M721.78,-355C768.77,-355 837.52,-355 887.29,-355"/>
128
+ <polygon fill="#34d399" stroke="#34d399" stroke-width="1.3" points="887.02,-357.8 895.02,-355 887.02,-352.2 887.02,-357.8"/>
106
129
  </g>
107
130
  <!-- Ruby -->
108
- <g id="node7" class="node">
131
+ <g id="node8" class="node">
109
132
  <title>Ruby</title>
110
- <path fill="#6ee7b7" stroke="#334155" stroke-width="1.4" d="M990.25,-301C990.25,-301 852,-301 852,-301 846,-301 840,-295 840,-289 840,-289 840,-277 840,-277 840,-271 846,-265 852,-265 852,-265 990.25,-265 990.25,-265 996.25,-265 1002.25,-271 1002.25,-277 1002.25,-277 1002.25,-289 1002.25,-289 1002.25,-295 996.25,-301 990.25,-301"/>
111
- <text xml:space="preserve" text-anchor="middle" x="921.12" y="-286.05" font-family="sans-Serif" font-size="11.00" fill="#0f172a">:ruby</text>
112
- <text xml:space="preserve" text-anchor="middle" x="921.12" y="-272.55" font-family="sans-Serif" font-size="11.00" fill="#0f172a">→ TOPLEVEL_BINDING.eval</text>
133
+ <path fill="#6ee7b7" stroke="#334155" stroke-width="1.4" d="M1020.25,-301C1020.25,-301 882,-301 882,-301 876,-301 870,-295 870,-289 870,-289 870,-277 870,-277 870,-271 876,-265 882,-265 882,-265 1020.25,-265 1020.25,-265 1026.25,-265 1032.25,-271 1032.25,-277 1032.25,-277 1032.25,-289 1032.25,-289 1032.25,-295 1026.25,-301 1020.25,-301"/>
134
+ <text xml:space="preserve" text-anchor="middle" x="951.12" y="-286.05" font-family="sans-Serif" font-size="11.00" fill="#0f172a">:ruby</text>
135
+ <text xml:space="preserve" text-anchor="middle" x="951.12" y="-272.55" font-family="sans-Serif" font-size="11.00" fill="#0f172a">→ TOPLEVEL_BINDING.eval</text>
113
136
  </g>
114
137
  <!-- Runner&#45;&gt;Ruby -->
115
- <g id="edge7" class="edge">
138
+ <g id="edge9" class="edge">
116
139
  <title>Runner&#45;&gt;Ruby</title>
117
- <path fill="none" stroke="#34d399" stroke-width="1.3" d="M691.78,-341.46C732.86,-330.94 790.59,-316.16 837.72,-304.1"/>
118
- <polygon fill="#34d399" stroke="#34d399" stroke-width="1.3" points="838.33,-306.83 845.39,-302.13 836.95,-301.4 838.33,-306.83"/>
140
+ <path fill="none" stroke="#34d399" stroke-width="1.3" d="M721.78,-341.46C762.86,-330.94 820.59,-316.16 867.72,-304.1"/>
141
+ <polygon fill="#34d399" stroke="#34d399" stroke-width="1.3" points="868.33,-306.83 875.39,-302.13 866.95,-301.4 868.33,-306.83"/>
119
142
  </g>
120
143
  <!-- Script -->
121
- <g id="node8" class="node">
144
+ <g id="node9" class="node">
122
145
  <title>Script</title>
123
- <path fill="#6ee7b7" stroke="#334155" stroke-width="1.4" d="M964.38,-445C964.38,-445 877.88,-445 877.88,-445 871.88,-445 865.88,-439 865.88,-433 865.88,-433 865.88,-421 865.88,-421 865.88,-415 871.88,-409 877.88,-409 877.88,-409 964.38,-409 964.38,-409 970.38,-409 976.38,-415 976.38,-421 976.38,-421 976.38,-433 976.38,-433 976.38,-439 970.38,-445 964.38,-445"/>
124
- <text xml:space="preserve" text-anchor="middle" x="921.12" y="-430.05" font-family="sans-Serif" font-size="11.00" fill="#0f172a">:script</text>
125
- <text xml:space="preserve" text-anchor="middle" x="921.12" y="-416.55" font-family="sans-Serif" font-size="11.00" fill="#0f172a">→ exec external file</text>
146
+ <path fill="#6ee7b7" stroke="#334155" stroke-width="1.4" d="M994.38,-445C994.38,-445 907.88,-445 907.88,-445 901.88,-445 895.88,-439 895.88,-433 895.88,-433 895.88,-421 895.88,-421 895.88,-415 901.88,-409 907.88,-409 907.88,-409 994.38,-409 994.38,-409 1000.38,-409 1006.38,-415 1006.38,-421 1006.38,-421 1006.38,-433 1006.38,-433 1006.38,-439 1000.38,-445 994.38,-445"/>
147
+ <text xml:space="preserve" text-anchor="middle" x="951.12" y="-430.05" font-family="sans-Serif" font-size="11.00" fill="#0f172a">:script</text>
148
+ <text xml:space="preserve" text-anchor="middle" x="951.12" y="-416.55" font-family="sans-Serif" font-size="11.00" fill="#0f172a">→ exec external file</text>
126
149
  </g>
127
150
  <!-- Runner&#45;&gt;Script -->
128
- <g id="edge8" class="edge">
151
+ <g id="edge10" class="edge">
129
152
  <title>Runner&#45;&gt;Script</title>
130
- <path fill="none" stroke="#34d399" stroke-width="1.3" d="M691.9,-370.33C706.85,-374.55 723.16,-379.05 738.25,-383 777.17,-393.19 821.01,-403.82 855.89,-412.08"/>
131
- <polygon fill="#34d399" stroke="#34d399" stroke-width="1.3" points="855.13,-414.77 863.56,-413.89 856.42,-409.32 855.13,-414.77"/>
153
+ <path fill="none" stroke="#34d399" stroke-width="1.3" d="M721.9,-370.33C736.85,-374.55 753.16,-379.05 768.25,-383 807.17,-393.19 851.01,-403.82 885.89,-412.08"/>
154
+ <polygon fill="#34d399" stroke="#34d399" stroke-width="1.3" points="885.13,-414.77 893.56,-413.89 886.42,-409.32 885.13,-414.77"/>
132
155
  </g>
133
156
  <!-- Log -->
134
- <g id="node13" class="node">
157
+ <g id="node14" class="node">
135
158
  <title>Log</title>
136
- <path fill="#fcd34d" stroke="#334155" stroke-width="1.4" d="M1354.5,-446.69C1354.5,-449.1 1324.86,-451.06 1288.38,-451.06 1251.89,-451.06 1222.25,-449.1 1222.25,-446.69 1222.25,-446.69 1222.25,-407.31 1222.25,-407.31 1222.25,-404.9 1251.89,-402.94 1288.38,-402.94 1324.86,-402.94 1354.5,-404.9 1354.5,-407.31 1354.5,-407.31 1354.5,-446.69 1354.5,-446.69"/>
137
- <path fill="none" stroke="#334155" stroke-width="1.4" d="M1354.5,-446.69C1354.5,-444.27 1324.86,-442.31 1288.38,-442.31 1251.89,-442.31 1222.25,-444.27 1222.25,-446.69"/>
138
- <text xml:space="preserve" text-anchor="middle" x="1288.38" y="-430.05" font-family="sans-Serif" font-size="11.00" fill="#0f172a">~/.pwn/cron/log/&lt;id&gt;.log</text>
139
- <text xml:space="preserve" text-anchor="middle" x="1288.38" y="-416.55" font-family="sans-Serif" font-size="11.00" fill="#0f172a">last_run · last_status</text>
159
+ <path fill="#fcd34d" stroke="#334155" stroke-width="1.4" d="M1384.5,-446.69C1384.5,-449.1 1354.86,-451.06 1318.38,-451.06 1281.89,-451.06 1252.25,-449.1 1252.25,-446.69 1252.25,-446.69 1252.25,-407.31 1252.25,-407.31 1252.25,-404.9 1281.89,-402.94 1318.38,-402.94 1354.86,-402.94 1384.5,-404.9 1384.5,-407.31 1384.5,-407.31 1384.5,-446.69 1384.5,-446.69"/>
160
+ <path fill="none" stroke="#334155" stroke-width="1.4" d="M1384.5,-446.69C1384.5,-444.27 1354.86,-442.31 1318.38,-442.31 1281.89,-442.31 1252.25,-444.27 1252.25,-446.69"/>
161
+ <text xml:space="preserve" text-anchor="middle" x="1318.38" y="-430.05" font-family="sans-Serif" font-size="11.00" fill="#0f172a">~/.pwn/cron/log/&lt;id&gt;.log</text>
162
+ <text xml:space="preserve" text-anchor="middle" x="1318.38" y="-416.55" font-family="sans-Serif" font-size="11.00" fill="#0f172a">last_run · last_status</text>
140
163
  </g>
141
164
  <!-- Prompt&#45;&gt;Log -->
142
- <g id="edge13" class="edge">
165
+ <g id="edge15" class="edge">
143
166
  <title>Prompt&#45;&gt;Log</title>
144
- <path fill="none" stroke="#f59e0b" stroke-width="1.3" d="M975.24,-365.47C1037.59,-377.76 1141.46,-398.24 1212.1,-412.16"/>
145
- <polygon fill="#f59e0b" stroke="#f59e0b" stroke-width="1.3" points="1211.52,-414.9 1219.91,-413.7 1212.6,-409.41 1211.52,-414.9"/>
167
+ <path fill="none" stroke="#f59e0b" stroke-width="1.3" d="M1005.24,-365.47C1067.59,-377.76 1171.46,-398.24 1242.1,-412.16"/>
168
+ <polygon fill="#f59e0b" stroke="#f59e0b" stroke-width="1.3" points="1241.52,-414.9 1249.91,-413.7 1242.6,-409.41 1241.52,-414.9"/>
146
169
  </g>
147
170
  <!-- Practice -->
148
- <g id="node9" class="node">
171
+ <g id="node10" class="node">
149
172
  <title>Practice</title>
150
- <path fill="#c4b5fd" stroke="#334155" stroke-width="1.4" d="M1349.25,-331.25C1349.25,-331.25 1227.5,-331.25 1227.5,-331.25 1221.5,-331.25 1215.5,-325.25 1215.5,-319.25 1215.5,-319.25 1215.5,-294.75 1215.5,-294.75 1215.5,-288.75 1221.5,-282.75 1227.5,-282.75 1227.5,-282.75 1349.25,-282.75 1349.25,-282.75 1355.25,-282.75 1361.25,-288.75 1361.25,-294.75 1361.25,-294.75 1361.25,-319.25 1361.25,-319.25 1361.25,-325.25 1355.25,-331.25 1349.25,-331.25"/>
151
- <text xml:space="preserve" text-anchor="middle" x="1288.38" y="-316.8" font-family="sans-Serif" font-size="11.00" fill="#0f172a">curriculum_practice_nightly</text>
152
- <text xml:space="preserve" text-anchor="middle" x="1288.38" y="-303.3" font-family="sans-Serif" font-size="11.00" fill="#0f172a">0 3 * * *</text>
153
- <text xml:space="preserve" text-anchor="middle" x="1288.38" y="-289.8" font-family="sans-Serif" font-size="11.00" fill="#0f172a">Curriculum.practice(limit:3)</text>
173
+ <path fill="#c4b5fd" stroke="#334155" stroke-width="1.4" d="M1379.25,-331.25C1379.25,-331.25 1257.5,-331.25 1257.5,-331.25 1251.5,-331.25 1245.5,-325.25 1245.5,-319.25 1245.5,-319.25 1245.5,-294.75 1245.5,-294.75 1245.5,-288.75 1251.5,-282.75 1257.5,-282.75 1257.5,-282.75 1379.25,-282.75 1379.25,-282.75 1385.25,-282.75 1391.25,-288.75 1391.25,-294.75 1391.25,-294.75 1391.25,-319.25 1391.25,-319.25 1391.25,-325.25 1385.25,-331.25 1379.25,-331.25"/>
174
+ <text xml:space="preserve" text-anchor="middle" x="1318.38" y="-316.8" font-family="sans-Serif" font-size="11.00" fill="#0f172a">curriculum_practice_nightly</text>
175
+ <text xml:space="preserve" text-anchor="middle" x="1318.38" y="-303.3" font-family="sans-Serif" font-size="11.00" fill="#0f172a">0 3 * * *</text>
176
+ <text xml:space="preserve" text-anchor="middle" x="1318.38" y="-289.8" font-family="sans-Serif" font-size="11.00" fill="#0f172a">Curriculum.practice(limit:3)</text>
154
177
  </g>
155
178
  <!-- Ruby&#45;&gt;Practice -->
156
- <g id="edge9" class="edge">
179
+ <g id="edge11" class="edge">
157
180
  <title>Ruby&#45;&gt;Practice</title>
158
- <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M1002.73,-288.3C1062.83,-292.25 1144.63,-297.62 1205.12,-301.6"/>
159
- <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="1204.89,-304.39 1213.06,-302.12 1205.26,-298.8 1204.89,-304.39"/>
181
+ <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M1032.73,-288.3C1092.83,-292.25 1174.63,-297.62 1235.12,-301.6"/>
182
+ <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="1234.89,-304.39 1243.06,-302.12 1235.26,-298.8 1234.89,-304.39"/>
160
183
  </g>
161
184
  <!-- Offline -->
162
- <g id="node10" class="node">
185
+ <g id="node11" class="node">
163
186
  <title>Offline</title>
164
- <path fill="#c4b5fd" stroke="#334155" stroke-width="1.4" d="M1342.5,-246.25C1342.5,-246.25 1234.25,-246.25 1234.25,-246.25 1228.25,-246.25 1222.25,-240.25 1222.25,-234.25 1222.25,-234.25 1222.25,-209.75 1222.25,-209.75 1222.25,-203.75 1228.25,-197.75 1234.25,-197.75 1234.25,-197.75 1342.5,-197.75 1342.5,-197.75 1348.5,-197.75 1354.5,-203.75 1354.5,-209.75 1354.5,-209.75 1354.5,-234.25 1354.5,-234.25 1354.5,-240.25 1348.5,-246.25 1342.5,-246.25"/>
165
- <text xml:space="preserve" text-anchor="middle" x="1288.38" y="-231.8" font-family="sans-Serif" font-size="11.00" fill="#0f172a">curriculum_offline_judge</text>
166
- <text xml:space="preserve" text-anchor="middle" x="1288.38" y="-218.3" font-family="sans-Serif" font-size="11.00" fill="#0f172a">30 3 * * *</text>
167
- <text xml:space="preserve" text-anchor="middle" x="1288.38" y="-204.8" font-family="sans-Serif" font-size="11.00" fill="#0f172a">Curriculum.offline_judge</text>
187
+ <path fill="#c4b5fd" stroke="#334155" stroke-width="1.4" d="M1372.5,-246.25C1372.5,-246.25 1264.25,-246.25 1264.25,-246.25 1258.25,-246.25 1252.25,-240.25 1252.25,-234.25 1252.25,-234.25 1252.25,-209.75 1252.25,-209.75 1252.25,-203.75 1258.25,-197.75 1264.25,-197.75 1264.25,-197.75 1372.5,-197.75 1372.5,-197.75 1378.5,-197.75 1384.5,-203.75 1384.5,-209.75 1384.5,-209.75 1384.5,-234.25 1384.5,-234.25 1384.5,-240.25 1378.5,-246.25 1372.5,-246.25"/>
188
+ <text xml:space="preserve" text-anchor="middle" x="1318.38" y="-231.8" font-family="sans-Serif" font-size="11.00" fill="#0f172a">curriculum_offline_judge</text>
189
+ <text xml:space="preserve" text-anchor="middle" x="1318.38" y="-218.3" font-family="sans-Serif" font-size="11.00" fill="#0f172a">30 3 * * *</text>
190
+ <text xml:space="preserve" text-anchor="middle" x="1318.38" y="-204.8" font-family="sans-Serif" font-size="11.00" fill="#0f172a">Curriculum.offline_judge</text>
168
191
  </g>
169
192
  <!-- Ruby&#45;&gt;Offline -->
170
- <g id="edge10" class="edge">
193
+ <g id="edge12" class="edge">
171
194
  <title>Ruby&#45;&gt;Offline</title>
172
- <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M1002.73,-269.54C1065.15,-259.11 1150.97,-244.78 1212.02,-234.58"/>
173
- <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="1212.23,-237.39 1219.66,-233.31 1211.31,-231.86 1212.23,-237.39"/>
195
+ <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M1032.73,-269.54C1095.15,-259.11 1180.97,-244.78 1242.02,-234.58"/>
196
+ <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="1242.23,-237.39 1249.66,-233.31 1241.31,-231.86 1242.23,-237.39"/>
174
197
  </g>
175
198
  <!-- Train -->
176
- <g id="node11" class="node">
199
+ <g id="node12" class="node">
177
200
  <title>Train</title>
178
- <path fill="#c4b5fd" stroke="#334155" stroke-width="1.4" d="M1348.12,-162C1348.12,-162 1228.62,-162 1228.62,-162 1222.62,-162 1216.62,-156 1216.62,-150 1216.62,-150 1216.62,-112 1216.62,-112 1216.62,-106 1222.62,-100 1228.62,-100 1228.62,-100 1348.12,-100 1348.12,-100 1354.12,-100 1360.12,-106 1360.12,-112 1360.12,-112 1360.12,-150 1360.12,-150 1360.12,-156 1354.12,-162 1348.12,-162"/>
179
- <text xml:space="preserve" text-anchor="middle" x="1288.38" y="-147.55" font-family="sans-Serif" font-size="11.00" fill="#0f172a">curriculum_train_weekly</text>
180
- <text xml:space="preserve" text-anchor="middle" x="1288.38" y="-134.05" font-family="sans-Serif" font-size="11.00" fill="#0f172a">0 4 * * 0</text>
181
- <text xml:space="preserve" text-anchor="middle" x="1288.38" y="-120.55" font-family="sans-Serif" font-size="11.00" fill="#0f172a">Curriculum.train_and_gate</text>
182
- <text xml:space="preserve" text-anchor="middle" x="1288.38" y="-107.05" font-family="sans-Serif" font-size="11.00" fill="#0f172a">(dry_run / export_ready)</text>
201
+ <path fill="#c4b5fd" stroke="#334155" stroke-width="1.4" d="M1378.12,-162C1378.12,-162 1258.62,-162 1258.62,-162 1252.62,-162 1246.62,-156 1246.62,-150 1246.62,-150 1246.62,-112 1246.62,-112 1246.62,-106 1252.62,-100 1258.62,-100 1258.62,-100 1378.12,-100 1378.12,-100 1384.12,-100 1390.12,-106 1390.12,-112 1390.12,-112 1390.12,-150 1390.12,-150 1390.12,-156 1384.12,-162 1378.12,-162"/>
202
+ <text xml:space="preserve" text-anchor="middle" x="1318.38" y="-147.55" font-family="sans-Serif" font-size="11.00" fill="#0f172a">curriculum_train_weekly</text>
203
+ <text xml:space="preserve" text-anchor="middle" x="1318.38" y="-134.05" font-family="sans-Serif" font-size="11.00" fill="#0f172a">0 4 * * 0</text>
204
+ <text xml:space="preserve" text-anchor="middle" x="1318.38" y="-120.55" font-family="sans-Serif" font-size="11.00" fill="#0f172a">Curriculum.train_and_gate</text>
205
+ <text xml:space="preserve" text-anchor="middle" x="1318.38" y="-107.05" font-family="sans-Serif" font-size="11.00" fill="#0f172a">(dry_run / export_ready)</text>
183
206
  </g>
184
207
  <!-- Ruby&#45;&gt;Train -->
185
- <g id="edge11" class="edge">
208
+ <g id="edge13" class="edge">
186
209
  <title>Ruby&#45;&gt;Train</title>
187
- <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M946.84,-264.34C978.33,-241.38 1035.2,-202.69 1089.25,-180 1126.44,-164.39 1169.73,-152.97 1206.34,-145.11"/>
188
- <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="1206.8,-147.87 1214.06,-143.49 1205.65,-142.39 1206.8,-147.87"/>
210
+ <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M976.84,-264.34C1008.33,-241.38 1065.2,-202.69 1119.25,-180 1156.44,-164.39 1199.73,-152.97 1236.34,-145.11"/>
211
+ <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="1236.8,-147.87 1244.06,-143.49 1235.65,-142.39 1236.8,-147.87"/>
189
212
  </g>
190
213
  <!-- MemGC -->
191
- <g id="node12" class="node">
214
+ <g id="node13" class="node">
192
215
  <title>MemGC</title>
193
- <path fill="#c4b5fd" stroke="#334155" stroke-width="1.4" d="M1351.88,-64.25C1351.88,-64.25 1224.88,-64.25 1224.88,-64.25 1218.88,-64.25 1212.88,-58.25 1212.88,-52.25 1212.88,-52.25 1212.88,-27.75 1212.88,-27.75 1212.88,-21.75 1218.88,-15.75 1224.88,-15.75 1224.88,-15.75 1351.88,-15.75 1351.88,-15.75 1357.88,-15.75 1363.88,-21.75 1363.88,-27.75 1363.88,-27.75 1363.88,-52.25 1363.88,-52.25 1363.88,-58.25 1357.88,-64.25 1351.88,-64.25"/>
194
- <text xml:space="preserve" text-anchor="middle" x="1288.38" y="-49.8" font-family="sans-Serif" font-size="11.00" fill="#0f172a">learning_consolidate_nightly</text>
195
- <text xml:space="preserve" text-anchor="middle" x="1288.38" y="-36.3" font-family="sans-Serif" font-size="11.00" fill="#0f172a">0 5 * * *</text>
196
- <text xml:space="preserve" text-anchor="middle" x="1288.38" y="-22.8" font-family="sans-Serif" font-size="11.00" fill="#0f172a">Learning.consolidate</text>
216
+ <path fill="#c4b5fd" stroke="#334155" stroke-width="1.4" d="M1381.88,-64.25C1381.88,-64.25 1254.88,-64.25 1254.88,-64.25 1248.88,-64.25 1242.88,-58.25 1242.88,-52.25 1242.88,-52.25 1242.88,-27.75 1242.88,-27.75 1242.88,-21.75 1248.88,-15.75 1254.88,-15.75 1254.88,-15.75 1381.88,-15.75 1381.88,-15.75 1387.88,-15.75 1393.88,-21.75 1393.88,-27.75 1393.88,-27.75 1393.88,-52.25 1393.88,-52.25 1393.88,-58.25 1387.88,-64.25 1381.88,-64.25"/>
217
+ <text xml:space="preserve" text-anchor="middle" x="1318.38" y="-49.8" font-family="sans-Serif" font-size="11.00" fill="#0f172a">learning_consolidate_nightly</text>
218
+ <text xml:space="preserve" text-anchor="middle" x="1318.38" y="-36.3" font-family="sans-Serif" font-size="11.00" fill="#0f172a">0 5 * * *</text>
219
+ <text xml:space="preserve" text-anchor="middle" x="1318.38" y="-22.8" font-family="sans-Serif" font-size="11.00" fill="#0f172a">Learning.consolidate</text>
197
220
  </g>
198
221
  <!-- Ruby&#45;&gt;MemGC -->
199
- <g id="edge12" class="edge">
222
+ <g id="edge14" class="edge">
200
223
  <title>Ruby&#45;&gt;MemGC</title>
201
- <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M931.79,-264.48C953.83,-224.24 1011.93,-128.67 1089.25,-82 1123.24,-61.49 1165.79,-50.9 1202.73,-45.47"/>
202
- <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="1203,-48.26 1210.54,-44.4 1202.24,-42.71 1203,-48.26"/>
224
+ <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M961.79,-264.48C983.83,-224.24 1041.93,-128.67 1119.25,-82 1153.24,-61.49 1195.79,-50.9 1232.73,-45.47"/>
225
+ <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="1233,-48.26 1240.54,-44.4 1232.24,-42.71 1233,-48.26"/>
203
226
  </g>
204
227
  <!-- Ruby&#45;&gt;Log -->
205
- <g id="edge14" class="edge">
228
+ <g id="edge16" class="edge">
206
229
  <title>Ruby&#45;&gt;Log</title>
207
- <path fill="none" stroke="#f59e0b" stroke-width="1.3" d="M974.49,-301.68C986.54,-306.71 999.08,-312.56 1010.25,-319 1048.69,-341.14 1049.21,-360.9 1089.25,-380 1127.78,-398.39 1174.05,-409.88 1212.18,-416.9"/>
208
- <polygon fill="#f59e0b" stroke="#f59e0b" stroke-width="1.3" points="1211.39,-419.6 1219.75,-418.25 1212.36,-414.09 1211.39,-419.6"/>
230
+ <path fill="none" stroke="#f59e0b" stroke-width="1.3" d="M1004.49,-301.68C1016.54,-306.71 1029.08,-312.56 1040.25,-319 1078.69,-341.14 1079.21,-360.9 1119.25,-380 1157.78,-398.39 1204.05,-409.88 1242.18,-416.9"/>
231
+ <polygon fill="#f59e0b" stroke="#f59e0b" stroke-width="1.3" points="1241.39,-419.6 1249.75,-418.25 1242.36,-414.09 1241.39,-419.6"/>
209
232
  </g>
210
233
  <!-- Script&#45;&gt;Log -->
211
- <g id="edge15" class="edge">
234
+ <g id="edge17" class="edge">
212
235
  <title>Script&#45;&gt;Log</title>
213
- <path fill="none" stroke="#f59e0b" stroke-width="1.3" d="M976.81,-427C1039.34,-427 1142.09,-427 1212.14,-427"/>
214
- <polygon fill="#f59e0b" stroke="#f59e0b" stroke-width="1.3" points="1211.84,-429.8 1219.84,-427 1211.84,-424.2 1211.84,-429.8"/>
236
+ <path fill="none" stroke="#f59e0b" stroke-width="1.3" d="M1006.81,-427C1069.34,-427 1172.09,-427 1242.14,-427"/>
237
+ <polygon fill="#f59e0b" stroke="#f59e0b" stroke-width="1.3" points="1241.84,-429.8 1249.84,-427 1241.84,-424.2 1241.84,-429.8"/>
215
238
  </g>
216
239
  <!-- Practice&#45;&gt;Log -->
217
- <g id="edge17" class="edge">
240
+ <g id="edge19" class="edge">
218
241
  <title>Practice&#45;&gt;Log</title>
219
- <path fill="none" stroke="#fbbf24" stroke-width="1.3" stroke-dasharray="5,2" d="M1288.38,-331.84C1288.38,-352.07 1288.38,-372.31 1288.38,-392.54"/>
220
- <polygon fill="#fbbf24" stroke="#fbbf24" stroke-width="1.3" points="1285.58,-392.5 1288.38,-400.5 1291.18,-392.5 1285.58,-392.5"/>
242
+ <path fill="none" stroke="#fbbf24" stroke-width="1.3" stroke-dasharray="5,2" d="M1318.38,-331.84C1318.38,-352.07 1318.38,-372.31 1318.38,-392.54"/>
243
+ <polygon fill="#fbbf24" stroke="#fbbf24" stroke-width="1.3" points="1315.58,-392.5 1318.38,-400.5 1321.18,-392.5 1315.58,-392.5"/>
221
244
  </g>
222
245
  <!-- Offline&#45;&gt;Log -->
223
- <g id="edge18" class="edge">
246
+ <g id="edge20" class="edge">
224
247
  <title>Offline&#45;&gt;Log</title>
225
- <path fill="none" stroke="#fbbf24" stroke-width="1.3" stroke-dasharray="5,2" d="M1221.6,-216.96C1164.23,-216.83 1085.32,-227.71 1049.75,-283 1030.76,-312.53 1030.76,-332.47 1049.75,-362 1083.44,-414.38 1155.55,-428.27 1211.74,-430.47"/>
226
- <polygon fill="#fbbf24" stroke="#fbbf24" stroke-width="1.3" points="1211.63,-433.27 1219.71,-430.69 1211.79,-427.67 1211.63,-433.27"/>
248
+ <path fill="none" stroke="#fbbf24" stroke-width="1.3" stroke-dasharray="5,2" d="M1251.6,-216.96C1194.23,-216.83 1115.32,-227.71 1079.75,-283 1060.76,-312.53 1060.76,-332.47 1079.75,-362 1113.44,-414.38 1185.55,-428.27 1241.74,-430.47"/>
249
+ <polygon fill="#fbbf24" stroke="#fbbf24" stroke-width="1.3" points="1241.63,-433.27 1249.71,-430.69 1241.79,-427.67 1241.63,-433.27"/>
227
250
  </g>
228
251
  <!-- Train&#45;&gt;Log -->
229
- <g id="edge19" class="edge">
252
+ <g id="edge21" class="edge">
230
253
  <title>Train&#45;&gt;Log</title>
231
- <path fill="none" stroke="#fbbf24" stroke-width="1.3" stroke-dasharray="5,2" d="M1216.05,-128.08C1159.33,-130.27 1084.38,-144.17 1049.75,-198 1010.32,-259.3 1010.32,-300.7 1049.75,-362 1083.44,-414.38 1155.55,-428.27 1211.74,-430.47"/>
232
- <polygon fill="#fbbf24" stroke="#fbbf24" stroke-width="1.3" points="1211.63,-433.27 1219.71,-430.69 1211.79,-427.67 1211.63,-433.27"/>
254
+ <path fill="none" stroke="#fbbf24" stroke-width="1.3" stroke-dasharray="5,2" d="M1246.05,-128.08C1189.33,-130.27 1114.38,-144.17 1079.75,-198 1040.32,-259.3 1040.32,-300.7 1079.75,-362 1113.44,-414.38 1185.55,-428.27 1241.74,-430.47"/>
255
+ <polygon fill="#fbbf24" stroke="#fbbf24" stroke-width="1.3" points="1241.63,-433.27 1249.71,-430.69 1241.79,-427.67 1241.63,-433.27"/>
233
256
  </g>
234
257
  <!-- MemGC&#45;&gt;Log -->
235
- <g id="edge20" class="edge">
258
+ <g id="edge22" class="edge">
236
259
  <title>MemGC&#45;&gt;Log</title>
237
- <path fill="none" stroke="#fbbf24" stroke-width="1.3" stroke-dasharray="5,2" d="M1212.46,-34.66C1156.11,-35.45 1083.43,-47.64 1049.75,-100 1018.25,-148.97 1018.25,-313.03 1049.75,-362 1083.44,-414.38 1155.55,-428.27 1211.74,-430.47"/>
238
- <polygon fill="#fbbf24" stroke="#fbbf24" stroke-width="1.3" points="1211.63,-433.27 1219.71,-430.69 1211.79,-427.67 1211.63,-433.27"/>
260
+ <path fill="none" stroke="#fbbf24" stroke-width="1.3" stroke-dasharray="5,2" d="M1242.46,-34.66C1186.11,-35.45 1113.43,-47.64 1079.75,-100 1048.25,-148.97 1048.25,-313.03 1079.75,-362 1113.44,-414.38 1185.55,-428.27 1241.74,-430.47"/>
261
+ <polygon fill="#fbbf24" stroke="#fbbf24" stroke-width="1.3" points="1241.63,-433.27 1249.71,-430.69 1241.79,-427.67 1241.63,-433.27"/>
239
262
  </g>
240
263
  <!-- Log&#45;&gt;Jobs -->
241
- <g id="edge16" class="edge">
264
+ <g id="edge18" class="edge">
242
265
  <title>Log&#45;&gt;Jobs</title>
243
- <path fill="none" stroke="#fbbf24" stroke-width="1.3" stroke-dasharray="5,2" d="M1221.77,-424.28C1180.35,-419.64 1127.61,-408.1 1089.25,-380 1034.09,-339.6 1069.73,-281.72 1010.25,-248 825.42,-143.21 748.48,-293.93 537.5,-319 503.58,-323.03 465.67,-320.98 434.28,-317.51"/>
244
- <polygon fill="#fbbf24" stroke="#fbbf24" stroke-width="1.3" points="434.99,-314.78 426.72,-316.63 434.34,-320.34 434.99,-314.78"/>
245
- <text xml:space="preserve" text-anchor="middle" x="765.62" y="-256.44" font-family="sans-Serif" font-size="9.00" fill="#cbd5e1">update status</text>
266
+ <path fill="none" stroke="#fbbf24" stroke-width="1.3" stroke-dasharray="5,2" d="M1251.77,-424.28C1210.35,-419.64 1157.61,-408.1 1119.25,-380 1064.09,-339.6 1099.73,-281.72 1040.25,-248 971.33,-208.93 940.45,-236.97 862,-248 748.68,-263.93 712.79,-260.4 614.5,-319 588.86,-334.29 594.67,-354.62 567.5,-367 530.84,-383.71 485.78,-386.7 449.32,-385.39"/>
267
+ <polygon fill="#fbbf24" stroke="#fbbf24" stroke-width="1.3" points="449.85,-382.61 441.73,-385.04 449.59,-388.21 449.85,-382.61"/>
268
+ <text xml:space="preserve" text-anchor="middle" x="795.62" y="-262.32" font-family="sans-Serif" font-size="9.00" fill="#cbd5e1">update status</text>
246
269
  </g>
247
270
  </g>
248
271
  </svg>
@@ -9,7 +9,7 @@ digraph "PWN_Agent_Tool_Registry" {
9
9
  shape=box, penwidth=1.3, color="#334155", fontcolor="#0f172a"];
10
10
  edge [color="#94a3b8", penwidth=1.1, arrowsize=0.7];
11
11
 
12
- Registry [label="Registry\nJSON-Schema function defs\nrank(query) · CORE_TOOLS\ntool_router → CORE + top-K", fillcolor="#c4b5fd", fontsize=12, penwidth=2];
12
+ Registry [label="Registry\nJSON-Schema function defs\nrank(query) · CORE_TOOLS\ntool_router → CORE + top-K\ntool_preference (memory_recall first)", fillcolor="#c4b5fd", fontsize=12, penwidth=2];
13
13
 
14
14
  subgraph cluster_ts {
15
15
  label="Toolsets"; fontcolor="#a7f3d0"; style=rounded;
@@ -68,4 +68,5 @@ digraph "PWN_Agent_Tool_Registry" {
68
68
  curric -> t_curric [color="#f59e0b"];
69
69
 
70
70
  t_metric -> Registry [label="success_rate\n→ router tie-break", style=dashed, color="#fbbf24", constraint=false];
71
+ t_policy -> Registry [label="preference_order\n+ Q-advantage", style=dashed, color="#c4b5fd", constraint=false];
71
72
  }
@@ -1,6 +1,6 @@
1
1
  digraph "PWN_Cron" {
2
2
  graph [
3
- label=<<B>PWN::Cron - Scheduled Autonomous Jobs</B><BR/><FONT POINT-SIZE="11" COLOR="#94a3b8">prompt · ruby · script → jobs.yml → crontab → pwn-ai · seeded self-improvement (Curriculum)</FONT>>,
3
+ label=<<B>PWN::Cron - Scheduled Autonomous Jobs</B><BR/><FONT POINT-SIZE="11" COLOR="#94a3b8">prompt · ruby · script → jobs.yml → worker → pwn-ai · seeded self-improvement (Curriculum)</FONT>>,
4
4
  labelloc=t, fontsize=20, fontname="Helvetica",
5
5
  rankdir=LR, splines=spline, nodesep=0.5, ranksep=1.3,
6
6
  bgcolor="#0f172a", fontcolor="#e2e8f0", pad=0.6, newrank=true
@@ -15,7 +15,8 @@ digraph "PWN_Cron" {
15
15
  {rank=same; Create; Seed}
16
16
 
17
17
  Jobs [label="~/.pwn/cron/jobs.yml", shape=cylinder, fillcolor="#fcd34d"];
18
- Crontab [label="system crontab\n(install_crontab: true)", fillcolor="#fda4af"];
18
+ Crontab [label="per-job crontab\n(install_crontab: true)", fillcolor="#fda4af"];
19
+ Worker [label="background worker\npwn setup keep-alive\nsystemd --user / launchd\nschtasks / crontab @reboot", fillcolor="#fda4af"];
19
20
  Runner [label="PWN::Cron.run(id)", fillcolor="#c4b5fd"];
20
21
 
21
22
  subgraph cluster_kinds {
@@ -41,8 +42,10 @@ digraph "PWN_Cron" {
41
42
 
42
43
  Create -> Jobs [label="write", color="#38bdf8"];
43
44
  Seed -> Jobs [label="idempotent seed", color="#38bdf8"];
44
- Create -> Crontab [label="append", color="#fb7185"];
45
+ Create -> Crontab [label="optional per-job", color="#fb7185"];
46
+ Seed -> Worker [label="pwn setup", color="#fb7185"];
45
47
  Crontab -> Runner [label="fire on schedule", color="#fb7185", penwidth=2];
48
+ Worker -> Runner [label="poll jobs.yml", color="#fb7185", penwidth=2];
46
49
  Jobs -> Runner [label="load job", color="#f59e0b"];
47
50
  Runner -> Prompt [color="#34d399"];
48
51
  Runner -> Ruby [color="#34d399"];
@@ -90,7 +90,7 @@ Escalate [label="escalate\n>=N fails → Swarm hint", fillcolor="#c4b5fd"
90
90
  /* L1 → L2 */
91
91
  Dispatch -> Metrics [label="record(engine:)", color="#34d399"];
92
92
  Dispatch -> Policy [label="observe_step", color="#34d399"];
93
- Result -> Learning [label="auto_introspect", color="#34d399"];
93
+ Result -> Learning [label="auto_introspect\n(deferred after reply)", color="#34d399"];
94
94
  Result -> Policy [label="finish (judge)", color="#34d399"];
95
95
  Dispatch -> Mistakes [label="on failure\nrecord()", color="#fb7185", penwidth=2];
96
96
  User -> Mistakes [label="\"that's wrong\"\ncheck_user_correction", color="#fb7185",