pwn 0.5.784 → 0.5.787

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 (254) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/Gemfile +6 -6
  4. data/README.md +37 -0
  5. data/bin/pwn +2 -1
  6. data/bin/pwn_web_cache_deception +35 -7
  7. data/build_gem.sh +1 -1
  8. data/documentation/AI-Integration.md +7 -5
  9. data/documentation/Agent-Tool-Registry.md +2 -2
  10. data/documentation/Backup-Retention.md +69 -15
  11. data/documentation/Configuration.md +10 -6
  12. data/documentation/Contributing.md +1 -1
  13. data/documentation/Cron.md +2 -2
  14. data/documentation/Diagrams.md +2 -2
  15. data/documentation/General-PWN-Usage.md +4 -3
  16. data/documentation/Harness-Evaluation.md +1 -1
  17. data/documentation/Home.md +6 -5
  18. data/documentation/How-PWN-Works.md +6 -5
  19. data/documentation/Installation.md +12 -9
  20. data/documentation/Mission-Cancellation.md +134 -0
  21. data/documentation/Operability.md +18 -0
  22. data/documentation/Persistence.md +7 -5
  23. data/documentation/Plugin-Degradation.md +14 -0
  24. data/documentation/Plugins.md +3 -2
  25. data/documentation/Policy-Benchmark.md +32 -33
  26. data/documentation/Runtime-Source-Protection.md +162 -0
  27. data/documentation/Transparent-Browser.md +11 -0
  28. data/documentation/Troubleshooting.md +3 -2
  29. data/documentation/What-is-PWN.md +2 -2
  30. data/documentation/YubiKey-Vaults.md +185 -0
  31. data/documentation/YubiKey.md +218 -0
  32. data/documentation/diagrams/cron-scheduling.svg +130 -130
  33. data/documentation/diagrams/dot/cron-scheduling.dot +3 -3
  34. data/documentation/diagrams/dot/persistence-filesystem.dot +5 -3
  35. data/documentation/diagrams/dot/plugin-ecosystem.dot +2 -2
  36. data/documentation/diagrams/dot/pwn-ai-feedback-learning-loop.dot +1 -1
  37. data/documentation/diagrams/dot/reinforcement-learning.dot +2 -2
  38. data/documentation/diagrams/persistence-filesystem.svg +172 -142
  39. data/documentation/diagrams/plugin-ecosystem.svg +64 -64
  40. data/documentation/diagrams/pwn-ai-feedback-learning-loop.svg +1 -1
  41. data/documentation/diagrams/reinforcement-learning.svg +89 -89
  42. data/documentation/pwn-ai-Agent.md +10 -4
  43. data/etc/default_cron/session_cleanup.rb +43 -27
  44. data/etc/default_skills/pwn/ai/agent/mission_namespace/SKILL.md +21 -0
  45. data/etc/default_skills/pwn/ai/agent/tools/browser_act/SKILL.md +45 -0
  46. data/etc/default_skills/pwn/ai/agent/tools/loot_query/SKILL.md +27 -26
  47. data/etc/default_skills/pwn/ai/agent/tools/recon_run/SKILL.md +25 -15
  48. data/etc/default_skills/pwn/ai/agent/tools/workspace_tool/SKILL.md +24 -0
  49. data/etc/default_skills/pwn/ai/server_tools/SKILL.md +25 -0
  50. data/etc/default_skills/pwn/backups/SKILL.md +54 -0
  51. data/etc/default_skills/pwn/plugins/recon/SKILL.md +12 -1
  52. data/etc/default_skills/pwn/plugins/yubikey/SKILL.md +157 -0
  53. data/etc/default_skills/pwn/plugins/yubikey/fido/SKILL.md +189 -0
  54. data/etc/default_skills/pwn/plugins/yubikey/hsmauth/SKILL.md +83 -0
  55. data/etc/default_skills/pwn/plugins/yubikey/management/SKILL.md +80 -0
  56. data/etc/default_skills/pwn/plugins/yubikey/oath/SKILL.md +115 -0
  57. data/etc/default_skills/pwn/plugins/yubikey/openpgp/SKILL.md +144 -0
  58. data/etc/default_skills/pwn/plugins/yubikey/otp/SKILL.md +97 -0
  59. data/etc/default_skills/pwn/plugins/yubikey/piv/SKILL.md +110 -0
  60. data/etc/default_skills/pwn/plugins/yubikey/protocol/SKILL.md +21 -0
  61. data/etc/default_skills/pwn/plugins/yubikey/security_domain/SKILL.md +75 -0
  62. data/etc/default_skills/pwn/plugins/yubikey/security_domain/scp/SKILL.md +46 -0
  63. data/etc/default_skills/pwn/plugins/yubikey/transport/SKILL.md +98 -0
  64. data/etc/default_skills/pwn/redaction/SKILL.md +13 -1
  65. data/lib/pwn/ai/agent/dispatch.rb +26 -15
  66. data/lib/pwn/ai/agent/learning.rb +14 -18
  67. data/lib/pwn/ai/agent/loop.rb +17 -1
  68. data/lib/pwn/ai/agent/mission_namespace.rb +331 -0
  69. data/lib/pwn/ai/agent/policy_evaluation.rb +334 -36
  70. data/lib/pwn/ai/agent/prompt_builder.rb +13 -2
  71. data/lib/pwn/ai/agent/request_runtime.rb +122 -18
  72. data/lib/pwn/ai/agent/reward.rb +5 -3
  73. data/lib/pwn/ai/agent/skill_consolidation.rb +3 -2
  74. data/lib/pwn/ai/agent/skill_review.rb +9 -5
  75. data/lib/pwn/ai/agent/swarm.rb +4 -0
  76. data/lib/pwn/ai/agent/tools/browser_act.rb +32 -0
  77. data/lib/pwn/ai/agent/tools/loot_query.rb +11 -1
  78. data/lib/pwn/ai/agent/tools/recon_run.rb +11 -1
  79. data/lib/pwn/ai/agent/tools/workspace_tool.rb +29 -0
  80. data/lib/pwn/ai/agent/turn_finalizer.rb +6 -2
  81. data/lib/pwn/ai/agent.rb +1 -0
  82. data/lib/pwn/ai/anthropic.rb +8 -33
  83. data/lib/pwn/ai/cli.rb +34 -5
  84. data/lib/pwn/ai/gemini.rb +1 -0
  85. data/lib/pwn/ai/grok.rb +39 -28
  86. data/lib/pwn/ai/ollama.rb +4 -2
  87. data/lib/pwn/ai/open_ai.rb +11 -32
  88. data/lib/pwn/ai/open_web_ui.rb +62 -4
  89. data/lib/pwn/ai/router.rb +8 -1
  90. data/lib/pwn/ai/server_tools.rb +231 -0
  91. data/lib/pwn/ai.rb +1 -0
  92. data/lib/pwn/backups.rb +349 -0
  93. data/lib/pwn/config.rb +70 -39
  94. data/lib/pwn/migrate.rb +85 -280
  95. data/lib/pwn/module_skills.rb +7 -0
  96. data/lib/pwn/plugins/ai_sandbox.rb +538 -1
  97. data/lib/pwn/plugins/authentication_helper.rb +74 -4
  98. data/lib/pwn/plugins/basic_auth.rb +2 -1
  99. data/lib/pwn/plugins/google_workspace.rb +4 -21
  100. data/lib/pwn/plugins/jobs.rb +1 -1
  101. data/lib/pwn/plugins/log.rb +3 -1
  102. data/lib/pwn/plugins/preflight_checker.rb +34 -9
  103. data/lib/pwn/plugins/recon.rb +4 -1
  104. data/lib/pwn/plugins/repl/ai.rb +293 -26
  105. data/lib/pwn/plugins/repl/ai_console.rb +268 -88
  106. data/lib/pwn/plugins/repl/ai_swarm.rb +177 -58
  107. data/lib/pwn/plugins/repl/mesh.rb +14 -19
  108. data/lib/pwn/plugins/repl/vault.rb +4 -15
  109. data/lib/pwn/plugins/repl.rb +9 -216
  110. data/lib/pwn/plugins/sandbox/driver.rb +4 -0
  111. data/lib/pwn/plugins/transparent_browser.rb +215 -0
  112. data/lib/pwn/plugins/vault.rb +412 -135
  113. data/lib/pwn/plugins/yubikey/fido.rb +1288 -0
  114. data/lib/pwn/plugins/yubikey/hsmauth.rb +439 -0
  115. data/lib/pwn/plugins/yubikey/management.rb +686 -0
  116. data/lib/pwn/plugins/yubikey/oath.rb +766 -0
  117. data/lib/pwn/plugins/yubikey/openpgp.rb +1063 -0
  118. data/lib/pwn/plugins/yubikey/otp.rb +897 -0
  119. data/lib/pwn/plugins/yubikey/piv.rb +1315 -0
  120. data/lib/pwn/plugins/yubikey/protocol.rb +341 -0
  121. data/lib/pwn/plugins/yubikey/security_domain/scp.rb +482 -0
  122. data/lib/pwn/plugins/yubikey/security_domain.rb +464 -0
  123. data/lib/pwn/plugins/yubikey/transport.rb +1017 -0
  124. data/lib/pwn/plugins/yubikey.rb +844 -0
  125. data/lib/pwn/plugins.rb +1 -0
  126. data/lib/pwn/redaction.rb +69 -12
  127. data/lib/pwn/session_trace.rb +4 -0
  128. data/lib/pwn/setup.rb +114 -24
  129. data/lib/pwn/version.rb +1 -1
  130. data/lib/pwn/www/app_cobalt_io.rb +16 -5
  131. data/lib/pwn/www/bug_crowd.rb +16 -5
  132. data/lib/pwn/www/coinbase_pro.rb +16 -5
  133. data/lib/pwn/www/github.rb +30 -14
  134. data/lib/pwn/www/paypal.rb +15 -4
  135. data/lib/pwn/www/synack.rb +16 -5
  136. data/lib/pwn/www/twitter.rb +17 -6
  137. data/lib/pwn.rb +1 -0
  138. data/spec/documentation/installation_md_spec.rb +1 -1
  139. data/spec/fixtures/yubikey/apdu_frames.json +162 -0
  140. data/spec/integration/authentication_helper_oath_spec.rb +117 -0
  141. data/spec/integration/controller_spill_spec.rb +48 -0
  142. data/spec/integration/harness_process_spec.rb +97 -0
  143. data/spec/integration/mission_cancel_spec.rb +79 -0
  144. data/spec/integration/mission_curses_pty_spec.rb +44 -0
  145. data/spec/integration/readme_security_spec.rb +47 -0
  146. data/spec/integration/web_cache_deception_yubikey_spec.rb +159 -0
  147. data/spec/lib/pwn/ai/agent/dispatch_spec.rb +6 -3
  148. data/spec/lib/pwn/ai/agent/dispatch_vault_safety_spec.rb +86 -0
  149. data/spec/lib/pwn/ai/agent/injection_guard_spec.rb +2 -0
  150. data/spec/lib/pwn/ai/agent/learning_spec.rb +4 -4
  151. data/spec/lib/pwn/ai/agent/loop_artifacts_spec.rb +5 -0
  152. data/spec/lib/pwn/ai/agent/loop_spec.rb +104 -29
  153. data/spec/lib/pwn/ai/agent/mission_namespace_spec.rb +138 -0
  154. data/spec/lib/pwn/ai/agent/policy_evaluation_spec.rb +10 -23
  155. data/spec/lib/pwn/ai/agent/request_runtime_spec.rb +48 -0
  156. data/spec/lib/pwn/ai/agent/shell_search_effect_spec.rb +44 -0
  157. data/spec/lib/pwn/ai/agent/solve_spec.rb +6 -4
  158. data/spec/lib/pwn/ai/agent/tools/browser_act_spec.rb +44 -0
  159. data/spec/lib/pwn/ai/agent/tools/loot_query_yubikey_spec.rb +55 -0
  160. data/spec/lib/pwn/ai/agent/tools/recon_run_yubikey_spec.rb +43 -0
  161. data/spec/lib/pwn/ai/agent/tools/workspace_tool_spec.rb +20 -0
  162. data/spec/lib/pwn/ai/agent/turn_finalizer_spec.rb +7 -0
  163. data/spec/lib/pwn/ai/anthropic_vault_enrollment_spec.rb +37 -0
  164. data/spec/lib/pwn/ai/cli_spec.rb +8 -16
  165. data/spec/lib/pwn/ai/oauth_vault_persistence_spec.rb +195 -0
  166. data/spec/lib/pwn/ai/open_ai_spec.rb +2 -2
  167. data/spec/lib/pwn/ai/open_web_ui_workspace_spec.rb +36 -0
  168. data/spec/lib/pwn/ai/router_spec.rb +1 -1
  169. data/spec/lib/pwn/ai/server_tools_spec.rb +39 -0
  170. data/spec/lib/pwn/backups_spec.rb +129 -0
  171. data/spec/lib/pwn/config_redaction_yubikey_spec.rb +28 -0
  172. data/spec/lib/pwn/config_yubikey_spec.rb +92 -0
  173. data/spec/lib/pwn/migrate_spec.rb +29 -81
  174. data/spec/lib/pwn/migrate_yubikey_spec.rb +128 -0
  175. data/spec/lib/pwn/module_skills_spec.rb +8 -0
  176. data/spec/lib/pwn/plugins/ai_sandbox_spec.rb +230 -0
  177. data/spec/lib/pwn/plugins/authentication_helper_native_yubikey_spec.rb +40 -0
  178. data/spec/lib/pwn/plugins/authentication_helper_yubikey_spec.rb +90 -0
  179. data/spec/lib/pwn/plugins/capability_broker/daemon_spec.rb +1 -1
  180. data/spec/lib/pwn/plugins/google_workspace_spec.rb +17 -35
  181. data/spec/lib/pwn/plugins/log_yubikey_spec.rb +47 -0
  182. data/spec/lib/pwn/plugins/preflight_checker_native_yubikey_spec.rb +19 -0
  183. data/spec/lib/pwn/plugins/preflight_checker_yubikey_spec.rb +55 -0
  184. data/spec/lib/pwn/plugins/recon_yubikey_spec.rb +43 -0
  185. data/spec/lib/pwn/plugins/repl/ai_console_spec.rb +110 -75
  186. data/spec/lib/pwn/plugins/repl/ai_legacy_containment_spec.rb +200 -0
  187. data/spec/lib/pwn/plugins/repl/ai_swarm_spec.rb +19 -16
  188. data/spec/lib/pwn/plugins/repl/ai_vault_edit_yubikey_spec.rb +103 -0
  189. data/spec/lib/pwn/plugins/repl/ai_yubikey_spec.rb +48 -0
  190. data/spec/lib/pwn/plugins/repl/mesh_vault_persistence_spec.rb +149 -0
  191. data/spec/lib/pwn/plugins/repl/vault_yaml_serialization_spec.rb +11 -0
  192. data/spec/lib/pwn/plugins/repl/vault_yubikey_spec.rb +39 -0
  193. data/spec/lib/pwn/plugins/repl_mesh_layout_spec.rb +2 -0
  194. data/spec/lib/pwn/plugins/repl_spec.rb +56 -5
  195. data/spec/lib/pwn/plugins/transparent_browser_jev_spec.rb +46 -0
  196. data/spec/lib/pwn/plugins/vault_native_yubikey_spec.rb +29 -0
  197. data/spec/lib/pwn/plugins/vault_publication_safety_spec.rb +258 -0
  198. data/spec/lib/pwn/plugins/vault_store_safety_spec.rb +241 -0
  199. data/spec/lib/pwn/plugins/vault_yubikey_safety_spec.rb +168 -0
  200. data/spec/lib/pwn/plugins/vault_yubikey_spec.rb +128 -0
  201. data/spec/lib/pwn/plugins/vault_yubikey_vector_spec.rb +45 -0
  202. data/spec/lib/pwn/plugins/yubikey/fido_spec.rb +854 -0
  203. data/spec/lib/pwn/plugins/yubikey/hsmauth_spec.rb +235 -0
  204. data/spec/lib/pwn/plugins/yubikey/management_spec.rb +277 -0
  205. data/spec/lib/pwn/plugins/yubikey/oath_spec.rb +349 -0
  206. data/spec/lib/pwn/plugins/yubikey/openpgp_spec.rb +810 -0
  207. data/spec/lib/pwn/plugins/yubikey/otp_spec.rb +337 -0
  208. data/spec/lib/pwn/plugins/yubikey/piv_spec.rb +646 -0
  209. data/spec/lib/pwn/plugins/yubikey/protocol_secure_spec.rb +28 -0
  210. data/spec/lib/pwn/plugins/yubikey/protocol_spec.rb +149 -0
  211. data/spec/lib/pwn/plugins/yubikey/protocol_vectors_spec.rb +18 -0
  212. data/spec/lib/pwn/plugins/yubikey/security_domain/scp_spec.rb +256 -0
  213. data/spec/lib/pwn/plugins/yubikey/security_domain/support.rb +153 -0
  214. data/spec/lib/pwn/plugins/yubikey/security_domain_spec.rb +296 -0
  215. data/spec/lib/pwn/plugins/yubikey/transport_spec.rb +760 -0
  216. data/spec/lib/pwn/plugins/yubikey_security_spec.rb +260 -0
  217. data/spec/lib/pwn/plugins/yubikey_spec.rb +209 -0
  218. data/spec/lib/pwn/plugins/yubikey_terminal_spec.rb +147 -0
  219. data/spec/lib/pwn/redaction_yubikey_spec.rb +61 -0
  220. data/spec/lib/pwn/session_cleanup_default_spec.rb +7 -5
  221. data/spec/lib/pwn/session_cleanup_payload_spec.rb +11 -11
  222. data/spec/lib/pwn/session_cleanup_recovery_spec.rb +34 -20
  223. data/spec/lib/pwn/setup_native_yubikey_spec.rb +66 -0
  224. data/spec/lib/pwn/setup_vault_yubikey_spec.rb +61 -0
  225. data/spec/lib/pwn/setup_yubikey_spec.rb +40 -0
  226. data/spec/lib/pwn/www/login_yubikey_spec.rb +273 -0
  227. data/spec/spec_helper.rb +15 -0
  228. data/spec/support/harness/cli_faults.rb +13 -9
  229. data/spec/support/harness/controller_spill.rb +26 -0
  230. data/spec/support/harness/controller_state.rb +54 -0
  231. data/spec/support/harness/evaluate.rb +12 -1
  232. data/spec/support/harness/experiments.rb +1 -1
  233. data/spec/support/harness/fake_provider.rb +22 -6
  234. data/spec/support/harness/fault_preload.rb +3 -1
  235. data/spec/support/harness/mission_console.rb +54 -0
  236. data/spec/support/harness/mission_curses_pty.rb +41 -0
  237. data/spec/support/harness/mission_dispatch.rb +30 -0
  238. data/spec/support/harness/mission_fixture_preload.rb +24 -0
  239. data/spec/support/harness/mission_job_lifetime.rb +25 -0
  240. data/spec/support/harness/mission_legacy.rb +25 -0
  241. data/spec/support/harness/mission_normal_exit.rb +34 -0
  242. data/spec/support/harness/mission_swarm.rb +23 -0
  243. data/spec/support/harness/mission_unsupported.rb +29 -0
  244. data/spec/support/harness/package_acceptance.rb +33 -5
  245. data/spec/support/harness/session_acceptance.rb +4 -4
  246. data/spec/support/harness/swarm_acceptance.rb +1 -1
  247. data/spec/support/harness/swarm_control.rb +44 -0
  248. data/spec/support/mission_namespace.rb +14 -0
  249. data/spec/support/mission_pipe_queue.rb +33 -0
  250. data/third_party/pwn_rdoc.jsonl +605 -19
  251. metadata +129 -16
  252. data/scripts/benchmark_policy.rb +0 -376
  253. data/scripts/build_gate.rb +0 -58
  254. data/spec/integration/build_gate_spec.rb +0 -73
@@ -4,310 +4,310 @@
4
4
  <!-- Generated by graphviz version 14.1.2 (0)
5
5
  -->
6
6
  <!-- Title: PWN_Cron Pages: 1 -->
7
- <svg width="2020pt" height="1168pt"
8
- viewBox="0.00 0.00 2020.00 1168.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
9
- <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(43.2 1124.5)">
7
+ <svg width="2066pt" height="1186pt"
8
+ viewBox="0.00 0.00 2066.00 1186.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
9
+ <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(43.2 1143.04)">
10
10
  <title>PWN_Cron</title>
11
- <polygon fill="#0f172a" stroke="none" points="-43.2,43.2 -43.2,-1124.5 1977.2,-1124.5 1977.2,43.2 -43.2,43.2"/>
12
- <text xml:space="preserve" text-anchor="start" x="765.62" y="-1059.3" font-family="Helvetica,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="761.88" y="-1047.85" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#94a3b8">prompt · ruby · script → jobs.yml → worker → pwn&#45;ai &#160;· &#160;hygiene on · curriculum opt&#45;in</text>
11
+ <polygon fill="#0f172a" stroke="none" points="-43.2,43.2 -43.2,-1143.04 2022.95,-1143.04 2022.95,43.2 -43.2,43.2"/>
12
+ <text xml:space="preserve" text-anchor="start" x="788.5" y="-1077.84" 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="784.75" y="-1066.39" font-family="sans-Serif" font-size="11.00" fill="#94a3b8">prompt · ruby · script → jobs.yml → worker → pwn&#45;ai &#160;· &#160;hygiene on · curriculum opt&#45;in</text>
14
14
  <g id="clust2" class="cluster">
15
15
  <title>cluster_kinds</title>
16
- <path fill="#022c22" stroke="#047857" stroke-width="2" d="M831.5,-464.36C831.5,-464.36 985.75,-464.36 985.75,-464.36 991.75,-464.36 997.75,-470.36 997.75,-476.36 997.75,-476.36 997.75,-679.36 997.75,-679.36 997.75,-685.36 991.75,-691.36 985.75,-691.36 985.75,-691.36 831.5,-691.36 831.5,-691.36 825.5,-691.36 819.5,-685.36 819.5,-679.36 819.5,-679.36 819.5,-476.36 819.5,-476.36 819.5,-470.36 825.5,-464.36 831.5,-464.36"/>
17
- <text xml:space="preserve" text-anchor="middle" x="908.62" y="-668.36" font-family="Helvetica,sans-Serif" font-size="20.00" fill="#a7f3d0">Job Kinds</text>
16
+ <path fill="#022c22" stroke="#047857" stroke-width="2" d="M831.5,-476.28C831.5,-476.28 985.75,-476.28 985.75,-476.28 991.75,-476.28 997.75,-482.28 997.75,-488.28 997.75,-488.28 997.75,-691.28 997.75,-691.28 997.75,-697.28 991.75,-703.28 985.75,-703.28 985.75,-703.28 831.5,-703.28 831.5,-703.28 825.5,-703.28 819.5,-697.28 819.5,-691.28 819.5,-691.28 819.5,-488.28 819.5,-488.28 819.5,-482.28 825.5,-476.28 831.5,-476.28"/>
17
+ <text xml:space="preserve" text-anchor="middle" x="908.62" y="-680.28" 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="M1096.75,-282.36C1096.75,-282.36 1694.75,-282.36 1694.75,-282.36 1700.75,-282.36 1706.75,-288.36 1706.75,-294.36 1706.75,-294.36 1706.75,-718.36 1706.75,-718.36 1706.75,-724.36 1700.75,-730.36 1694.75,-730.36 1694.75,-730.36 1096.75,-730.36 1096.75,-730.36 1090.75,-730.36 1084.75,-724.36 1084.75,-718.36 1084.75,-718.36 1084.75,-294.36 1084.75,-294.36 1084.75,-288.36 1090.75,-282.36 1096.75,-282.36"/>
22
- <text xml:space="preserve" text-anchor="middle" x="1395.75" y="-707.36" font-family="Helvetica,sans-Serif" font-size="20.00" fill="#ddd6fe">Optional curriculum templates / preserved legacy jobs (NOT seeded)</text>
21
+ <path fill="#2e1065" stroke="#6d28d9" stroke-width="2" d="M1096.75,-294.28C1096.75,-294.28 1740.5,-294.28 1740.5,-294.28 1746.5,-294.28 1752.5,-300.28 1752.5,-306.28 1752.5,-306.28 1752.5,-730.28 1752.5,-730.28 1752.5,-736.28 1746.5,-742.28 1740.5,-742.28 1740.5,-742.28 1096.75,-742.28 1096.75,-742.28 1090.75,-742.28 1084.75,-736.28 1084.75,-730.28 1084.75,-730.28 1084.75,-306.28 1084.75,-306.28 1084.75,-300.28 1090.75,-294.28 1096.75,-294.28"/>
22
+ <text xml:space="preserve" text-anchor="middle" x="1418.62" y="-719.28" font-family="sans-Serif" font-size="20.00" fill="#ddd6fe">Not seeded. Curriculum templates, plus legacy split jobs if already present</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,-647.61C118,-647.61 27.75,-647.61 27.75,-647.61 21.75,-647.61 15.75,-641.61 15.75,-635.61 15.75,-635.61 15.75,-611.11 15.75,-611.11 15.75,-605.11 21.75,-599.11 27.75,-599.11 27.75,-599.11 118,-599.11 118,-599.11 124,-599.11 130,-605.11 130,-611.11 130,-611.11 130,-635.61 130,-635.61 130,-641.61 124,-647.61 118,-647.61"/>
28
- <text xml:space="preserve" text-anchor="middle" x="72.88" y="-633.16" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">cron_create</text>
29
- <text xml:space="preserve" text-anchor="middle" x="72.88" y="-619.66" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">name · schedule</text>
30
- <text xml:space="preserve" text-anchor="middle" x="72.88" y="-606.16" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">prompt | ruby | script</text>
27
+ <path fill="#7dd3fc" stroke="#334155" stroke-width="1.4" d="M118,-659.53C118,-659.53 27.75,-659.53 27.75,-659.53 21.75,-659.53 15.75,-653.53 15.75,-647.53 15.75,-647.53 15.75,-623.03 15.75,-623.03 15.75,-617.03 21.75,-611.03 27.75,-611.03 27.75,-611.03 118,-611.03 118,-611.03 124,-611.03 130,-617.03 130,-623.03 130,-623.03 130,-647.53 130,-647.53 130,-653.53 124,-659.53 118,-659.53"/>
28
+ <text xml:space="preserve" text-anchor="middle" x="72.88" y="-645.08" 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="-631.58" 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="-618.08" 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="M444.75,-600.08C444.75,-601.89 418.98,-603.36 387.25,-603.36 355.52,-603.36 329.75,-601.89 329.75,-600.08 329.75,-600.08 329.75,-570.63 329.75,-570.63 329.75,-568.82 355.52,-567.36 387.25,-567.36 418.98,-567.36 444.75,-568.82 444.75,-570.63 444.75,-570.63 444.75,-600.08 444.75,-600.08"/>
36
- <path fill="none" stroke="#334155" stroke-width="1.4" d="M444.75,-600.08C444.75,-598.28 418.98,-596.81 387.25,-596.81 355.52,-596.81 329.75,-598.28 329.75,-600.08"/>
37
- <text xml:space="preserve" text-anchor="middle" x="387.25" y="-581.66" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">~/.pwn/cron/jobs.yml</text>
35
+ <path fill="#fcd34d" stroke="#334155" stroke-width="1.4" d="M444.75,-612.01C444.75,-613.81 418.98,-615.28 387.25,-615.28 355.52,-615.28 329.75,-613.81 329.75,-612.01 329.75,-612.01 329.75,-582.55 329.75,-582.55 329.75,-580.75 355.52,-579.28 387.25,-579.28 418.98,-579.28 444.75,-580.75 444.75,-582.55 444.75,-582.55 444.75,-612.01 444.75,-612.01"/>
36
+ <path fill="none" stroke="#334155" stroke-width="1.4" d="M444.75,-612.01C444.75,-610.2 418.98,-608.73 387.25,-608.73 355.52,-608.73 329.75,-610.2 329.75,-612.01"/>
37
+ <text xml:space="preserve" text-anchor="middle" x="387.25" y="-593.58" 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="edge3" class="edge">
41
41
  <title>Create&#45;&gt;Jobs</title>
42
- <path fill="none" stroke="#38bdf8" stroke-width="1.3" d="M130.44,-616.47C183.6,-610.01 263.18,-600.33 319.44,-593.48"/>
43
- <polygon fill="#38bdf8" stroke="#38bdf8" stroke-width="1.3" points="319.75,-596.27 327.36,-592.52 319.08,-590.71 319.75,-596.27"/>
44
- <text xml:space="preserve" text-anchor="middle" x="226.88" y="-610.83" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#cbd5e1">write</text>
42
+ <path fill="none" stroke="#38bdf8" stroke-width="1.3" d="M130.44,-628.4C183.6,-621.93 263.18,-612.25 319.44,-605.41"/>
43
+ <polygon fill="#38bdf8" stroke="#38bdf8" stroke-width="1.3" points="319.75,-608.19 327.36,-604.44 319.08,-602.63 319.75,-608.19"/>
44
+ <text xml:space="preserve" text-anchor="middle" x="226.88" y="-622.75" 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="M433.88,-675.36C433.88,-675.36 340.62,-675.36 340.62,-675.36 334.62,-675.36 328.62,-669.36 328.62,-663.36 328.62,-663.36 328.62,-651.36 328.62,-651.36 328.62,-645.36 334.62,-639.36 340.62,-639.36 340.62,-639.36 433.88,-639.36 433.88,-639.36 439.88,-639.36 445.88,-645.36 445.88,-651.36 445.88,-651.36 445.88,-663.36 445.88,-663.36 445.88,-669.36 439.88,-675.36 433.88,-675.36"/>
50
- <text xml:space="preserve" text-anchor="middle" x="387.25" y="-660.41" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">per&#45;job crontab</text>
51
- <text xml:space="preserve" text-anchor="middle" x="387.25" y="-646.91" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">(install_crontab: true)</text>
49
+ <path fill="#fda4af" stroke="#334155" stroke-width="1.4" d="M433.88,-687.28C433.88,-687.28 340.62,-687.28 340.62,-687.28 334.62,-687.28 328.62,-681.28 328.62,-675.28 328.62,-675.28 328.62,-663.28 328.62,-663.28 328.62,-657.28 334.62,-651.28 340.62,-651.28 340.62,-651.28 433.88,-651.28 433.88,-651.28 439.88,-651.28 445.88,-657.28 445.88,-663.28 445.88,-663.28 445.88,-675.28 445.88,-675.28 445.88,-681.28 439.88,-687.28 433.88,-687.28"/>
50
+ <text xml:space="preserve" text-anchor="middle" x="387.25" y="-672.33" font-family="sans-Serif" font-size="11.00" fill="#0f172a">per&#45;job crontab</text>
51
+ <text xml:space="preserve" text-anchor="middle" x="387.25" y="-658.83" 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="edge5" class="edge">
55
55
  <title>Create&#45;&gt;Crontab</title>
56
- <path fill="none" stroke="#fb7185" stroke-width="1.3" d="M130.44,-629.51C183.19,-635.25 261.94,-643.83 318.12,-649.94"/>
57
- <polygon fill="#fb7185" stroke="#fb7185" stroke-width="1.3" points="317.77,-652.72 326.03,-650.8 318.38,-647.15 317.77,-652.72"/>
58
- <text xml:space="preserve" text-anchor="middle" x="226.88" y="-645.35" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#cbd5e1">optional per&#45;job</text>
56
+ <path fill="none" stroke="#fb7185" stroke-width="1.3" d="M130.44,-641.44C183.19,-647.18 261.94,-655.75 318.12,-661.86"/>
57
+ <polygon fill="#fb7185" stroke="#fb7185" stroke-width="1.3" points="317.77,-664.64 326.03,-662.72 318.38,-659.07 317.77,-664.64"/>
58
+ <text xml:space="preserve" text-anchor="middle" x="226.88" y="-657.27" 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,-550.36C133.75,-550.36 12,-550.36 12,-550.36 6,-550.36 0,-544.36 0,-538.36 0,-538.36 0,-526.36 0,-526.36 0,-520.36 6,-514.36 12,-514.36 12,-514.36 133.75,-514.36 133.75,-514.36 139.75,-514.36 145.75,-520.36 145.75,-526.36 145.75,-526.36 145.75,-538.36 145.75,-538.36 145.75,-544.36 139.75,-550.36 133.75,-550.36"/>
64
- <text xml:space="preserve" text-anchor="middle" x="72.88" y="-535.41" font-family="Helvetica,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="-521.91" font-family="Helvetica,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,-562.28C133.75,-562.28 12,-562.28 12,-562.28 6,-562.28 0,-556.28 0,-550.28 0,-550.28 0,-538.28 0,-538.28 0,-532.28 6,-526.28 12,-526.28 12,-526.28 133.75,-526.28 133.75,-526.28 139.75,-526.28 145.75,-532.28 145.75,-538.28 145.75,-538.28 145.75,-550.28 145.75,-550.28 145.75,-556.28 139.75,-562.28 133.75,-562.28"/>
64
+ <text xml:space="preserve" text-anchor="middle" x="72.88" y="-547.33" 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="-533.83" 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="edge4" class="edge">
69
69
  <title>Seed&#45;&gt;Jobs</title>
70
- <path fill="none" stroke="#38bdf8" stroke-width="1.3" d="M146.33,-544.65C198.64,-553.53 268.76,-565.42 319.68,-574.06"/>
71
- <polygon fill="#38bdf8" stroke="#38bdf8" stroke-width="1.3" points="318.98,-576.78 327.33,-575.36 319.91,-571.26 318.98,-576.78"/>
72
- <text xml:space="preserve" text-anchor="middle" x="226.88" y="-565.55" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#cbd5e1">idempotent seed</text>
70
+ <path fill="none" stroke="#38bdf8" stroke-width="1.3" d="M146.33,-556.57C198.64,-565.45 268.76,-577.34 319.68,-585.98"/>
71
+ <polygon fill="#38bdf8" stroke="#38bdf8" stroke-width="1.3" points="318.98,-588.7 327.33,-587.28 319.91,-583.18 318.98,-588.7"/>
72
+ <text xml:space="preserve" text-anchor="middle" x="226.88" y="-577.48" font-family="sans-Serif" font-size="9.00" fill="#cbd5e1">idempotent seed</text>
73
73
  </g>
74
74
  <!-- Worker -->
75
75
  <g id="node5" class="node">
76
76
  <title>Worker</title>
77
- <path fill="#fda4af" stroke="#334155" stroke-width="1.4" d="M454.5,-531.36C454.5,-531.36 320,-531.36 320,-531.36 314,-531.36 308,-525.36 308,-519.36 308,-519.36 308,-481.36 308,-481.36 308,-475.36 314,-469.36 320,-469.36 320,-469.36 454.5,-469.36 454.5,-469.36 460.5,-469.36 466.5,-475.36 466.5,-481.36 466.5,-481.36 466.5,-519.36 466.5,-519.36 466.5,-525.36 460.5,-531.36 454.5,-531.36"/>
78
- <text xml:space="preserve" text-anchor="middle" x="387.25" y="-516.91" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">background worker</text>
79
- <text xml:space="preserve" text-anchor="middle" x="387.25" y="-503.41" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">pwn setup starts/reuses</text>
80
- <text xml:space="preserve" text-anchor="middle" x="387.25" y="-489.91" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">portable internal scheduler</text>
81
- <text xml:space="preserve" text-anchor="middle" x="387.25" y="-476.41" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">housekeeping: never systemd</text>
77
+ <path fill="#fda4af" stroke="#334155" stroke-width="1.4" d="M454.5,-543.28C454.5,-543.28 320,-543.28 320,-543.28 314,-543.28 308,-537.28 308,-531.28 308,-531.28 308,-493.28 308,-493.28 308,-487.28 314,-481.28 320,-481.28 320,-481.28 454.5,-481.28 454.5,-481.28 460.5,-481.28 466.5,-487.28 466.5,-493.28 466.5,-493.28 466.5,-531.28 466.5,-531.28 466.5,-537.28 460.5,-543.28 454.5,-543.28"/>
78
+ <text xml:space="preserve" text-anchor="middle" x="387.25" y="-528.83" font-family="sans-Serif" font-size="11.00" fill="#0f172a">background worker</text>
79
+ <text xml:space="preserve" text-anchor="middle" x="387.25" y="-515.33" font-family="sans-Serif" font-size="11.00" fill="#0f172a">pwn setup starts/reuses</text>
80
+ <text xml:space="preserve" text-anchor="middle" x="387.25" y="-501.83" font-family="sans-Serif" font-size="11.00" fill="#0f172a">portable internal scheduler</text>
81
+ <text xml:space="preserve" text-anchor="middle" x="387.25" y="-488.33" font-family="sans-Serif" font-size="11.00" fill="#0f172a">housekeeping: never systemd</text>
82
82
  </g>
83
83
  <!-- Seed&#45;&gt;Worker -->
84
84
  <g id="edge6" class="edge">
85
85
  <title>Seed&#45;&gt;Worker</title>
86
- <path fill="none" stroke="#fb7185" stroke-width="1.3" d="M130.08,-513.69C149.68,-508.06 171.97,-502.65 192.75,-499.86 226.84,-495.28 264.62,-494.44 297.68,-495.09"/>
87
- <polygon fill="#fb7185" stroke="#fb7185" stroke-width="1.3" points="297.29,-497.88 305.35,-495.27 297.42,-492.28 297.29,-497.88"/>
88
- <text xml:space="preserve" text-anchor="middle" x="226.88" y="-501.81" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#cbd5e1">pwn setup</text>
86
+ <path fill="none" stroke="#fb7185" stroke-width="1.3" d="M130.08,-525.61C149.68,-519.98 171.97,-514.57 192.75,-511.78 226.84,-507.2 264.62,-506.37 297.68,-507.01"/>
87
+ <polygon fill="#fb7185" stroke="#fb7185" stroke-width="1.3" points="297.29,-509.8 305.35,-507.2 297.42,-504.2 297.29,-509.8"/>
88
+ <text xml:space="preserve" text-anchor="middle" x="226.88" y="-513.73" font-family="sans-Serif" font-size="9.00" fill="#cbd5e1">pwn setup</text>
89
89
  </g>
90
90
  <!-- Runner -->
91
91
  <g id="node6" class="node">
92
92
  <title>Runner</title>
93
- <path fill="#c4b5fd" stroke="#334155" stroke-width="1.4" d="M720.5,-580.36C720.5,-580.36 637.75,-580.36 637.75,-580.36 631.75,-580.36 625.75,-574.36 625.75,-568.36 625.75,-568.36 625.75,-556.36 625.75,-556.36 625.75,-550.36 631.75,-544.36 637.75,-544.36 637.75,-544.36 720.5,-544.36 720.5,-544.36 726.5,-544.36 732.5,-550.36 732.5,-556.36 732.5,-556.36 732.5,-568.36 732.5,-568.36 732.5,-574.36 726.5,-580.36 720.5,-580.36"/>
94
- <text xml:space="preserve" text-anchor="middle" x="679.12" y="-558.66" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">PWN::Cron.run(id)</text>
93
+ <path fill="#c4b5fd" stroke="#334155" stroke-width="1.4" d="M720.5,-592.28C720.5,-592.28 637.75,-592.28 637.75,-592.28 631.75,-592.28 625.75,-586.28 625.75,-580.28 625.75,-580.28 625.75,-568.28 625.75,-568.28 625.75,-562.28 631.75,-556.28 637.75,-556.28 637.75,-556.28 720.5,-556.28 720.5,-556.28 726.5,-556.28 732.5,-562.28 732.5,-568.28 732.5,-568.28 732.5,-580.28 732.5,-580.28 732.5,-586.28 726.5,-592.28 720.5,-592.28"/>
94
+ <text xml:space="preserve" text-anchor="middle" x="679.12" y="-570.58" font-family="sans-Serif" font-size="11.00" fill="#0f172a">PWN::Cron.run(id)</text>
95
95
  </g>
96
96
  <!-- Jobs&#45;&gt;Runner -->
97
97
  <g id="edge9" class="edge">
98
98
  <title>Jobs&#45;&gt;Runner</title>
99
- <path fill="none" stroke="#f59e0b" stroke-width="1.3" d="M445.17,-580.84C494.17,-576.95 564.78,-571.35 615.39,-567.33"/>
100
- <polygon fill="#f59e0b" stroke="#f59e0b" stroke-width="1.3" points="615.52,-570.13 623.28,-566.71 615.08,-564.55 615.52,-570.13"/>
101
- <text xml:space="preserve" text-anchor="middle" x="546.12" y="-577.18" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#cbd5e1">load job</text>
99
+ <path fill="none" stroke="#f59e0b" stroke-width="1.3" d="M445.17,-592.76C494.17,-588.87 564.78,-583.27 615.39,-579.26"/>
100
+ <polygon fill="#f59e0b" stroke="#f59e0b" stroke-width="1.3" points="615.52,-582.05 623.28,-578.63 615.08,-576.47 615.52,-582.05"/>
101
+ <text xml:space="preserve" text-anchor="middle" x="546.12" y="-589.11" font-family="sans-Serif" font-size="9.00" fill="#cbd5e1">load job</text>
102
102
  </g>
103
103
  <!-- Crontab&#45;&gt;Runner -->
104
104
  <g id="edge7" class="edge">
105
105
  <title>Crontab&#45;&gt;Runner</title>
106
- <path fill="none" stroke="#fb7185" stroke-width="2" d="M446.19,-649.79C484.6,-643.67 535.68,-633.38 578.75,-617.36 600.31,-609.33 622.86,-597.2 641.02,-586.37"/>
107
- <polygon fill="#fb7185" stroke="#fb7185" stroke-width="2" points="642.12,-588.98 647.5,-582.43 639.21,-584.19 642.12,-588.98"/>
108
- <text xml:space="preserve" text-anchor="middle" x="546.12" y="-637.66" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#cbd5e1">fire on schedule</text>
106
+ <path fill="none" stroke="#fb7185" stroke-width="2" d="M446.19,-661.72C484.6,-655.59 535.68,-645.31 578.75,-629.28 600.31,-621.26 622.86,-609.12 641.02,-598.29"/>
107
+ <polygon fill="#fb7185" stroke="#fb7185" stroke-width="2" points="642.12,-600.9 647.5,-594.35 639.21,-596.12 642.12,-600.9"/>
108
+ <text xml:space="preserve" text-anchor="middle" x="546.12" y="-649.58" font-family="sans-Serif" font-size="9.00" fill="#cbd5e1">fire on schedule</text>
109
109
  </g>
110
110
  <!-- Worker&#45;&gt;Runner -->
111
111
  <g id="edge8" class="edge">
112
112
  <title>Worker&#45;&gt;Runner</title>
113
- <path fill="none" stroke="#fb7185" stroke-width="2" d="M467.08,-517.22C513.44,-527.13 571.3,-539.51 614.7,-548.79"/>
114
- <polygon fill="#fb7185" stroke="#fb7185" stroke-width="2" points="614.04,-551.51 622.45,-550.45 615.21,-546.04 614.04,-551.51"/>
115
- <text xml:space="preserve" text-anchor="middle" x="546.12" y="-542.48" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#cbd5e1">poll jobs.yml</text>
113
+ <path fill="none" stroke="#fb7185" stroke-width="2" d="M467.08,-529.14C513.44,-539.06 571.3,-551.43 614.7,-560.71"/>
114
+ <polygon fill="#fb7185" stroke="#fb7185" stroke-width="2" points="614.04,-563.43 622.45,-562.37 615.21,-557.96 614.04,-563.43"/>
115
+ <text xml:space="preserve" text-anchor="middle" x="546.12" y="-554.4" font-family="sans-Serif" font-size="9.00" fill="#cbd5e1">poll jobs.yml</text>
116
116
  </g>
117
117
  <!-- Prompt -->
118
118
  <g id="node7" class="node">
119
119
  <title>Prompt</title>
120
- <path fill="#6ee7b7" stroke="#334155" stroke-width="1.4" d="M950.38,-580.36C950.38,-580.36 866.88,-580.36 866.88,-580.36 860.88,-580.36 854.88,-574.36 854.88,-568.36 854.88,-568.36 854.88,-556.36 854.88,-556.36 854.88,-550.36 860.88,-544.36 866.88,-544.36 866.88,-544.36 950.38,-544.36 950.38,-544.36 956.38,-544.36 962.38,-550.36 962.38,-556.36 962.38,-556.36 962.38,-568.36 962.38,-568.36 962.38,-574.36 956.38,-580.36 950.38,-580.36"/>
121
- <text xml:space="preserve" text-anchor="middle" x="908.62" y="-565.41" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">:prompt</text>
122
- <text xml:space="preserve" text-anchor="middle" x="908.62" y="-551.91" font-family="Helvetica,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="M950.38,-592.28C950.38,-592.28 866.88,-592.28 866.88,-592.28 860.88,-592.28 854.88,-586.28 854.88,-580.28 854.88,-580.28 854.88,-568.28 854.88,-568.28 854.88,-562.28 860.88,-556.28 866.88,-556.28 866.88,-556.28 950.38,-556.28 950.38,-556.28 956.38,-556.28 962.38,-562.28 962.38,-568.28 962.38,-568.28 962.38,-580.28 962.38,-580.28 962.38,-586.28 956.38,-592.28 950.38,-592.28"/>
121
+ <text xml:space="preserve" text-anchor="middle" x="908.62" y="-577.33" font-family="sans-Serif" font-size="11.00" fill="#0f172a">:prompt</text>
122
+ <text xml:space="preserve" text-anchor="middle" x="908.62" y="-563.83" font-family="sans-Serif" font-size="11.00" fill="#0f172a">→ pwn&#45;ai one&#45;shot</text>
123
123
  </g>
124
124
  <!-- Runner&#45;&gt;Prompt -->
125
125
  <g id="edge10" class="edge">
126
126
  <title>Runner&#45;&gt;Prompt</title>
127
- <path fill="none" stroke="#34d399" stroke-width="1.3" d="M733.18,-562.36C766.54,-562.36 809.76,-562.36 844.83,-562.36"/>
128
- <polygon fill="#34d399" stroke="#34d399" stroke-width="1.3" points="844.52,-565.16 852.52,-562.36 844.52,-559.56 844.52,-565.16"/>
127
+ <path fill="none" stroke="#34d399" stroke-width="1.3" d="M733.18,-574.28C766.54,-574.28 809.76,-574.28 844.83,-574.28"/>
128
+ <polygon fill="#34d399" stroke="#34d399" stroke-width="1.3" points="844.52,-577.08 852.52,-574.28 844.52,-571.48 844.52,-577.08"/>
129
129
  </g>
130
130
  <!-- Ruby -->
131
131
  <g id="node8" class="node">
132
132
  <title>Ruby</title>
133
- <path fill="#6ee7b7" stroke="#334155" stroke-width="1.4" d="M977.75,-508.36C977.75,-508.36 839.5,-508.36 839.5,-508.36 833.5,-508.36 827.5,-502.36 827.5,-496.36 827.5,-496.36 827.5,-484.36 827.5,-484.36 827.5,-478.36 833.5,-472.36 839.5,-472.36 839.5,-472.36 977.75,-472.36 977.75,-472.36 983.75,-472.36 989.75,-478.36 989.75,-484.36 989.75,-484.36 989.75,-496.36 989.75,-496.36 989.75,-502.36 983.75,-508.36 977.75,-508.36"/>
134
- <text xml:space="preserve" text-anchor="middle" x="908.62" y="-493.41" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">:ruby</text>
135
- <text xml:space="preserve" text-anchor="middle" x="908.62" y="-479.91" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">→ TOPLEVEL_BINDING.eval</text>
133
+ <path fill="#6ee7b7" stroke="#334155" stroke-width="1.4" d="M977.75,-520.28C977.75,-520.28 839.5,-520.28 839.5,-520.28 833.5,-520.28 827.5,-514.28 827.5,-508.28 827.5,-508.28 827.5,-496.28 827.5,-496.28 827.5,-490.28 833.5,-484.28 839.5,-484.28 839.5,-484.28 977.75,-484.28 977.75,-484.28 983.75,-484.28 989.75,-490.28 989.75,-496.28 989.75,-496.28 989.75,-508.28 989.75,-508.28 989.75,-514.28 983.75,-520.28 977.75,-520.28"/>
134
+ <text xml:space="preserve" text-anchor="middle" x="908.62" y="-505.33" font-family="sans-Serif" font-size="11.00" fill="#0f172a">:ruby</text>
135
+ <text xml:space="preserve" text-anchor="middle" x="908.62" y="-491.83" font-family="sans-Serif" font-size="11.00" fill="#0f172a">→ TOPLEVEL_BINDING.eval</text>
136
136
  </g>
137
137
  <!-- Runner&#45;&gt;Ruby -->
138
138
  <g id="edge11" class="edge">
139
139
  <title>Runner&#45;&gt;Ruby</title>
140
- <path fill="none" stroke="#34d399" stroke-width="1.3" d="M733.18,-545.57C764.86,-535.54 805.43,-522.7 839.47,-511.93"/>
141
- <polygon fill="#34d399" stroke="#34d399" stroke-width="1.3" points="840.23,-514.62 847.01,-509.54 838.54,-509.28 840.23,-514.62"/>
140
+ <path fill="none" stroke="#34d399" stroke-width="1.3" d="M733.18,-557.49C764.86,-547.46 805.43,-534.62 839.47,-523.85"/>
141
+ <polygon fill="#34d399" stroke="#34d399" stroke-width="1.3" points="840.23,-526.55 847.01,-521.46 838.54,-521.21 840.23,-526.55"/>
142
142
  </g>
143
143
  <!-- Script -->
144
144
  <g id="node9" class="node">
145
145
  <title>Script</title>
146
- <path fill="#6ee7b7" stroke="#334155" stroke-width="1.4" d="M951.88,-652.36C951.88,-652.36 865.38,-652.36 865.38,-652.36 859.38,-652.36 853.38,-646.36 853.38,-640.36 853.38,-640.36 853.38,-628.36 853.38,-628.36 853.38,-622.36 859.38,-616.36 865.38,-616.36 865.38,-616.36 951.88,-616.36 951.88,-616.36 957.88,-616.36 963.88,-622.36 963.88,-628.36 963.88,-628.36 963.88,-640.36 963.88,-640.36 963.88,-646.36 957.88,-652.36 951.88,-652.36"/>
147
- <text xml:space="preserve" text-anchor="middle" x="908.62" y="-637.41" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">:script</text>
148
- <text xml:space="preserve" text-anchor="middle" x="908.62" y="-623.91" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">→ exec external file</text>
146
+ <path fill="#6ee7b7" stroke="#334155" stroke-width="1.4" d="M951.88,-664.28C951.88,-664.28 865.38,-664.28 865.38,-664.28 859.38,-664.28 853.38,-658.28 853.38,-652.28 853.38,-652.28 853.38,-640.28 853.38,-640.28 853.38,-634.28 859.38,-628.28 865.38,-628.28 865.38,-628.28 951.88,-628.28 951.88,-628.28 957.88,-628.28 963.88,-634.28 963.88,-640.28 963.88,-640.28 963.88,-652.28 963.88,-652.28 963.88,-658.28 957.88,-664.28 951.88,-664.28"/>
147
+ <text xml:space="preserve" text-anchor="middle" x="908.62" y="-649.33" font-family="sans-Serif" font-size="11.00" fill="#0f172a">:script</text>
148
+ <text xml:space="preserve" text-anchor="middle" x="908.62" y="-635.83" font-family="sans-Serif" font-size="11.00" fill="#0f172a">→ exec external file</text>
149
149
  </g>
150
150
  <!-- Runner&#45;&gt;Script -->
151
151
  <g id="edge12" class="edge">
152
152
  <title>Runner&#45;&gt;Script</title>
153
- <path fill="none" stroke="#34d399" stroke-width="1.3" d="M733.18,-579.15C766.2,-589.6 808.88,-603.1 843.76,-614.14"/>
154
- <polygon fill="#34d399" stroke="#34d399" stroke-width="1.3" points="842.56,-616.7 851.03,-616.44 844.25,-611.36 842.56,-616.7"/>
153
+ <path fill="none" stroke="#34d399" stroke-width="1.3" d="M733.18,-591.07C766.2,-601.52 808.88,-615.03 843.76,-626.06"/>
154
+ <polygon fill="#34d399" stroke="#34d399" stroke-width="1.3" points="842.56,-628.62 851.03,-628.37 844.25,-623.28 842.56,-628.62"/>
155
155
  </g>
156
156
  <!-- Log -->
157
157
  <g id="node16" class="node">
158
158
  <title>Log</title>
159
- <path fill="#fcd34d" stroke="#334155" stroke-width="1.4" d="M1934,-641.04C1934,-643.46 1904.36,-645.42 1867.88,-645.42 1831.39,-645.42 1801.75,-643.46 1801.75,-641.04 1801.75,-641.04 1801.75,-601.67 1801.75,-601.67 1801.75,-599.25 1831.39,-597.29 1867.88,-597.29 1904.36,-597.29 1934,-599.25 1934,-601.67 1934,-601.67 1934,-641.04 1934,-641.04"/>
160
- <path fill="none" stroke="#334155" stroke-width="1.4" d="M1934,-641.04C1934,-638.63 1904.36,-636.67 1867.88,-636.67 1831.39,-636.67 1801.75,-638.63 1801.75,-641.04"/>
161
- <text xml:space="preserve" text-anchor="middle" x="1867.88" y="-624.41" font-family="Helvetica,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="1867.88" y="-610.91" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">last_run · last_status</text>
159
+ <path fill="#fcd34d" stroke="#334155" stroke-width="1.4" d="M1979.75,-652.97C1979.75,-655.38 1950.11,-657.34 1913.62,-657.34 1877.14,-657.34 1847.5,-655.38 1847.5,-652.97 1847.5,-652.97 1847.5,-613.59 1847.5,-613.59 1847.5,-611.18 1877.14,-609.22 1913.62,-609.22 1950.11,-609.22 1979.75,-611.18 1979.75,-613.59 1979.75,-613.59 1979.75,-652.97 1979.75,-652.97"/>
160
+ <path fill="none" stroke="#334155" stroke-width="1.4" d="M1979.75,-652.97C1979.75,-650.55 1950.11,-648.59 1913.62,-648.59 1877.14,-648.59 1847.5,-650.55 1847.5,-652.97"/>
161
+ <text xml:space="preserve" text-anchor="middle" x="1913.62" y="-636.33" 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="1913.62" y="-622.83" font-family="sans-Serif" font-size="11.00" fill="#0f172a">last_run · last_status</text>
163
163
  </g>
164
164
  <!-- Prompt&#45;&gt;Log -->
165
165
  <g id="edge18" class="edge">
166
166
  <title>Prompt&#45;&gt;Log</title>
167
- <path fill="none" stroke="#f59e0b" stroke-width="1.3" d="M962.91,-578C975.18,-583.2 987.59,-589.89 997.75,-598.36 1052.87,-644.29 1021.81,-699.9 1084.75,-734.36 1206,-800.73 1575,-776.16 1706.75,-734.36 1756.98,-718.42 1805.04,-680.41 1835.17,-652.86"/>
168
- <polygon fill="#f59e0b" stroke="#f59e0b" stroke-width="1.3" points="1837.04,-654.94 1840.99,-647.45 1833.23,-650.84 1837.04,-654.94"/>
167
+ <path fill="none" stroke="#f59e0b" stroke-width="1.3" d="M962.91,-589.93C975.18,-595.12 987.59,-601.81 997.75,-610.28 1052.87,-656.22 1021.81,-711.82 1084.75,-746.28 1214.91,-817.53 1611.06,-791.16 1752.5,-746.28 1802.73,-730.34 1850.79,-692.33 1880.92,-664.78"/>
168
+ <polygon fill="#f59e0b" stroke="#f59e0b" stroke-width="1.3" points="1882.79,-666.87 1886.74,-659.37 1878.98,-662.77 1882.79,-666.87"/>
169
169
  </g>
170
170
  <!-- Practice -->
171
171
  <g id="node10" class="node">
172
172
  <title>Practice</title>
173
- <path fill="#c4b5fd" stroke="#334155" stroke-width="1.4" d="M1456.12,-690.61C1456.12,-690.61 1334.38,-690.61 1334.38,-690.61 1328.38,-690.61 1322.38,-684.61 1322.38,-678.61 1322.38,-678.61 1322.38,-654.11 1322.38,-654.11 1322.38,-648.11 1328.38,-642.11 1334.38,-642.11 1334.38,-642.11 1456.12,-642.11 1456.12,-642.11 1462.12,-642.11 1468.12,-648.11 1468.12,-654.11 1468.12,-654.11 1468.12,-678.61 1468.12,-678.61 1468.12,-684.61 1462.12,-690.61 1456.12,-690.61"/>
174
- <text xml:space="preserve" text-anchor="middle" x="1395.25" y="-676.16" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">curriculum_practice_nightly</text>
175
- <text xml:space="preserve" text-anchor="middle" x="1395.25" y="-662.66" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">0 3 * * * &#160;OFF</text>
176
- <text xml:space="preserve" text-anchor="middle" x="1395.25" y="-649.16" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">Curriculum.practice(limit:3)</text>
173
+ <path fill="#c4b5fd" stroke="#334155" stroke-width="1.4" d="M1479,-702.53C1479,-702.53 1357.25,-702.53 1357.25,-702.53 1351.25,-702.53 1345.25,-696.53 1345.25,-690.53 1345.25,-690.53 1345.25,-666.03 1345.25,-666.03 1345.25,-660.03 1351.25,-654.03 1357.25,-654.03 1357.25,-654.03 1479,-654.03 1479,-654.03 1485,-654.03 1491,-660.03 1491,-666.03 1491,-666.03 1491,-690.53 1491,-690.53 1491,-696.53 1485,-702.53 1479,-702.53"/>
174
+ <text xml:space="preserve" text-anchor="middle" x="1418.12" y="-688.08" font-family="sans-Serif" font-size="11.00" fill="#0f172a">curriculum_practice_nightly</text>
175
+ <text xml:space="preserve" text-anchor="middle" x="1418.12" y="-674.58" font-family="sans-Serif" font-size="11.00" fill="#0f172a">0 3 * * * &#160;OFF</text>
176
+ <text xml:space="preserve" text-anchor="middle" x="1418.12" y="-661.08" font-family="sans-Serif" font-size="11.00" fill="#0f172a">Curriculum.practice(limit:3)</text>
177
177
  </g>
178
178
  <!-- Ruby&#45;&gt;Practice -->
179
179
  <g id="edge13" class="edge">
180
180
  <title>Ruby&#45;&gt;Practice</title>
181
- <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M966.15,-509C977.11,-513.82 988.16,-519.6 997.75,-526.36 1045.09,-559.71 1033.62,-596.16 1084.75,-623.36 1155.13,-660.8 1246.7,-669.42 1311.94,-669.98"/>
182
- <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="1311.79,-672.78 1319.8,-670 1311.81,-667.18 1311.79,-672.78"/>
181
+ <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M966.15,-520.92C977.11,-525.74 988.16,-531.52 997.75,-538.28 1045.09,-571.63 1033.5,-608.32 1084.75,-635.28 1162.71,-676.28 1264.69,-683.82 1335.02,-683.15"/>
182
+ <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="1334.81,-685.95 1342.76,-683.03 1334.72,-680.35 1334.81,-685.95"/>
183
183
  </g>
184
184
  <!-- Offline -->
185
185
  <g id="node11" class="node">
186
186
  <title>Offline</title>
187
- <path fill="#c4b5fd" stroke="#334155" stroke-width="1.4" d="M1449.38,-605.61C1449.38,-605.61 1341.12,-605.61 1341.12,-605.61 1335.12,-605.61 1329.12,-599.61 1329.12,-593.61 1329.12,-593.61 1329.12,-569.11 1329.12,-569.11 1329.12,-563.11 1335.12,-557.11 1341.12,-557.11 1341.12,-557.11 1449.38,-557.11 1449.38,-557.11 1455.38,-557.11 1461.38,-563.11 1461.38,-569.11 1461.38,-569.11 1461.38,-593.61 1461.38,-593.61 1461.38,-599.61 1455.38,-605.61 1449.38,-605.61"/>
188
- <text xml:space="preserve" text-anchor="middle" x="1395.25" y="-591.16" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">curriculum_offline_judge</text>
189
- <text xml:space="preserve" text-anchor="middle" x="1395.25" y="-577.66" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">30 3 * * * &#160;OFF</text>
190
- <text xml:space="preserve" text-anchor="middle" x="1395.25" y="-564.16" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">Curriculum.offline_judge</text>
187
+ <path fill="#c4b5fd" stroke="#334155" stroke-width="1.4" d="M1472.25,-617.53C1472.25,-617.53 1364,-617.53 1364,-617.53 1358,-617.53 1352,-611.53 1352,-605.53 1352,-605.53 1352,-581.03 1352,-581.03 1352,-575.03 1358,-569.03 1364,-569.03 1364,-569.03 1472.25,-569.03 1472.25,-569.03 1478.25,-569.03 1484.25,-575.03 1484.25,-581.03 1484.25,-581.03 1484.25,-605.53 1484.25,-605.53 1484.25,-611.53 1478.25,-617.53 1472.25,-617.53"/>
188
+ <text xml:space="preserve" text-anchor="middle" x="1418.12" y="-603.08" font-family="sans-Serif" font-size="11.00" fill="#0f172a">curriculum_offline_judge</text>
189
+ <text xml:space="preserve" text-anchor="middle" x="1418.12" y="-589.58" font-family="sans-Serif" font-size="11.00" fill="#0f172a">30 3 * * * &#160;OFF</text>
190
+ <text xml:space="preserve" text-anchor="middle" x="1418.12" y="-576.08" font-family="sans-Serif" font-size="11.00" fill="#0f172a">Curriculum.offline_judge</text>
191
191
  </g>
192
192
  <!-- Ruby&#45;&gt;Offline -->
193
193
  <g id="edge14" class="edge">
194
194
  <title>Ruby&#45;&gt;Offline</title>
195
- <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M968.3,-508.96C1002.08,-519.12 1045.48,-531.24 1084.75,-539.36 1163.89,-555.72 1255.77,-567.26 1318.74,-574.05"/>
196
- <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="1318.39,-576.83 1326.64,-574.89 1318.98,-571.26 1318.39,-576.83"/>
195
+ <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M967.88,-520.9C1001.7,-531.12 1045.29,-543.31 1084.75,-551.28 1172.1,-568.92 1273.95,-580.49 1341.65,-586.93"/>
196
+ <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="1341.2,-589.7 1349.43,-587.66 1341.73,-584.13 1341.2,-589.7"/>
197
197
  </g>
198
198
  <!-- Train -->
199
199
  <g id="node12" class="node">
200
200
  <title>Train</title>
201
- <path fill="#c4b5fd" stroke="#334155" stroke-width="1.4" d="M1455,-521.36C1455,-521.36 1335.5,-521.36 1335.5,-521.36 1329.5,-521.36 1323.5,-515.36 1323.5,-509.36 1323.5,-509.36 1323.5,-471.36 1323.5,-471.36 1323.5,-465.36 1329.5,-459.36 1335.5,-459.36 1335.5,-459.36 1455,-459.36 1455,-459.36 1461,-459.36 1467,-465.36 1467,-471.36 1467,-471.36 1467,-509.36 1467,-509.36 1467,-515.36 1461,-521.36 1455,-521.36"/>
202
- <text xml:space="preserve" text-anchor="middle" x="1395.25" y="-506.91" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">curriculum_train_weekly</text>
203
- <text xml:space="preserve" text-anchor="middle" x="1395.25" y="-493.41" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">0 4 * * 0 &#160;OFF</text>
204
- <text xml:space="preserve" text-anchor="middle" x="1395.25" y="-479.91" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">Curriculum.train_and_gate</text>
205
- <text xml:space="preserve" text-anchor="middle" x="1395.25" y="-466.41" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">(dry_run / export_ready)</text>
201
+ <path fill="#c4b5fd" stroke="#334155" stroke-width="1.4" d="M1477.88,-533.28C1477.88,-533.28 1358.38,-533.28 1358.38,-533.28 1352.38,-533.28 1346.38,-527.28 1346.38,-521.28 1346.38,-521.28 1346.38,-483.28 1346.38,-483.28 1346.38,-477.28 1352.38,-471.28 1358.38,-471.28 1358.38,-471.28 1477.88,-471.28 1477.88,-471.28 1483.88,-471.28 1489.88,-477.28 1489.88,-483.28 1489.88,-483.28 1489.88,-521.28 1489.88,-521.28 1489.88,-527.28 1483.88,-533.28 1477.88,-533.28"/>
202
+ <text xml:space="preserve" text-anchor="middle" x="1418.12" y="-518.83" font-family="sans-Serif" font-size="11.00" fill="#0f172a">curriculum_train_weekly</text>
203
+ <text xml:space="preserve" text-anchor="middle" x="1418.12" y="-505.33" font-family="sans-Serif" font-size="11.00" fill="#0f172a">0 4 * * 0 &#160;OFF</text>
204
+ <text xml:space="preserve" text-anchor="middle" x="1418.12" y="-491.83" font-family="sans-Serif" font-size="11.00" fill="#0f172a">Curriculum.train_and_gate</text>
205
+ <text xml:space="preserve" text-anchor="middle" x="1418.12" y="-478.33" font-family="sans-Serif" font-size="11.00" fill="#0f172a">(dry_run / export_ready)</text>
206
206
  </g>
207
207
  <!-- Ruby&#45;&gt;Train -->
208
208
  <g id="edge15" class="edge">
209
209
  <title>Ruby&#45;&gt;Train</title>
210
- <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M990.19,-490.36C1079.7,-490.36 1223.38,-490.36 1313.11,-490.36"/>
211
- <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="1313,-493.16 1321,-490.36 1313,-487.56 1313,-493.16"/>
210
+ <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M990.32,-502.28C1084.99,-502.28 1241.05,-502.28 1335.94,-502.28"/>
211
+ <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="1335.81,-505.08 1343.81,-502.28 1335.81,-499.48 1335.81,-505.08"/>
212
212
  </g>
213
213
  <!-- MemGC -->
214
214
  <g id="node13" class="node">
215
215
  <title>MemGC</title>
216
- <path fill="#c4b5fd" stroke="#334155" stroke-width="1.4" d="M1458.75,-423.61C1458.75,-423.61 1331.75,-423.61 1331.75,-423.61 1325.75,-423.61 1319.75,-417.61 1319.75,-411.61 1319.75,-411.61 1319.75,-387.11 1319.75,-387.11 1319.75,-381.11 1325.75,-375.11 1331.75,-375.11 1331.75,-375.11 1458.75,-375.11 1458.75,-375.11 1464.75,-375.11 1470.75,-381.11 1470.75,-387.11 1470.75,-387.11 1470.75,-411.61 1470.75,-411.61 1470.75,-417.61 1464.75,-423.61 1458.75,-423.61"/>
217
- <text xml:space="preserve" text-anchor="middle" x="1395.25" y="-409.16" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">learning_consolidate_nightly</text>
218
- <text xml:space="preserve" text-anchor="middle" x="1395.25" y="-395.66" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">0 5 * * * &#160;ON</text>
219
- <text xml:space="preserve" text-anchor="middle" x="1395.25" y="-382.16" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">Learning.consolidate</text>
216
+ <path fill="#c4b5fd" stroke="#334155" stroke-width="1.4" d="M1492.12,-435.53C1492.12,-435.53 1344.12,-435.53 1344.12,-435.53 1338.12,-435.53 1332.12,-429.53 1332.12,-423.53 1332.12,-423.53 1332.12,-399.03 1332.12,-399.03 1332.12,-393.03 1338.12,-387.03 1344.12,-387.03 1344.12,-387.03 1492.12,-387.03 1492.12,-387.03 1498.12,-387.03 1504.12,-393.03 1504.12,-399.03 1504.12,-399.03 1504.12,-423.53 1504.12,-423.53 1504.12,-429.53 1498.12,-435.53 1492.12,-435.53"/>
217
+ <text xml:space="preserve" text-anchor="middle" x="1418.12" y="-421.08" font-family="sans-Serif" font-size="11.00" fill="#0f172a">learning_consolidate_nightly</text>
218
+ <text xml:space="preserve" text-anchor="middle" x="1418.12" y="-407.58" font-family="sans-Serif" font-size="11.00" fill="#0f172a">not seeded</text>
219
+ <text xml:space="preserve" text-anchor="middle" x="1418.12" y="-394.08" font-family="sans-Serif" font-size="11.00" fill="#0f172a">preserved only if already present</text>
220
220
  </g>
221
221
  <!-- Ruby&#45;&gt;MemGC -->
222
222
  <g id="edge16" class="edge">
223
223
  <title>Ruby&#45;&gt;MemGC</title>
224
- <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M968.3,-471.75C1002.08,-461.6 1045.48,-449.47 1084.75,-441.36 1160.11,-425.78 1247.02,-414.56 1309.53,-407.66"/>
225
- <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="1309.74,-410.46 1317.39,-406.81 1309.13,-404.89 1309.74,-410.46"/>
224
+ <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M967.88,-483.66C1001.7,-473.43 1045.29,-461.25 1084.75,-453.28 1163.95,-437.28 1255.07,-426.28 1321.85,-419.56"/>
225
+ <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="1321.88,-422.37 1329.56,-418.8 1321.32,-416.8 1321.88,-422.37"/>
226
226
  </g>
227
227
  <!-- Lean -->
228
228
  <g id="node14" class="node">
229
229
  <title>Lean</title>
230
- <path fill="#c4b5fd" stroke="#334155" stroke-width="1.4" d="M1450.5,-338.61C1450.5,-338.61 1340,-338.61 1340,-338.61 1334,-338.61 1328,-332.61 1328,-326.61 1328,-326.61 1328,-302.11 1328,-302.11 1328,-296.11 1334,-290.11 1340,-290.11 1340,-290.11 1450.5,-290.11 1450.5,-290.11 1456.5,-290.11 1462.5,-296.11 1462.5,-302.11 1462.5,-302.11 1462.5,-326.61 1462.5,-326.61 1462.5,-332.61 1456.5,-338.61 1450.5,-338.61"/>
231
- <text xml:space="preserve" text-anchor="middle" x="1395.25" y="-324.16" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">pwn_stores_lean_nightly</text>
232
- <text xml:space="preserve" text-anchor="middle" x="1395.25" y="-310.66" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">15 5 * * * &#160;ON</text>
233
- <text xml:space="preserve" text-anchor="middle" x="1395.25" y="-297.16" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">Learning.gc_stores!</text>
230
+ <path fill="#c4b5fd" stroke="#334155" stroke-width="1.4" d="M1492.12,-350.53C1492.12,-350.53 1344.12,-350.53 1344.12,-350.53 1338.12,-350.53 1332.12,-344.53 1332.12,-338.53 1332.12,-338.53 1332.12,-314.03 1332.12,-314.03 1332.12,-308.03 1338.12,-302.03 1344.12,-302.03 1344.12,-302.03 1492.12,-302.03 1492.12,-302.03 1498.12,-302.03 1504.12,-308.03 1504.12,-314.03 1504.12,-314.03 1504.12,-338.53 1504.12,-338.53 1504.12,-344.53 1498.12,-350.53 1492.12,-350.53"/>
231
+ <text xml:space="preserve" text-anchor="middle" x="1418.12" y="-336.08" font-family="sans-Serif" font-size="11.00" fill="#0f172a">pwn_stores_lean_nightly</text>
232
+ <text xml:space="preserve" text-anchor="middle" x="1418.12" y="-322.58" font-family="sans-Serif" font-size="11.00" fill="#0f172a">not seeded</text>
233
+ <text xml:space="preserve" text-anchor="middle" x="1418.12" y="-309.08" font-family="sans-Serif" font-size="11.00" fill="#0f172a">preserved only if already present</text>
234
234
  </g>
235
235
  <!-- Ruby&#45;&gt;Lean -->
236
236
  <g id="edge17" class="edge">
237
237
  <title>Ruby&#45;&gt;Lean</title>
238
- <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M927.04,-472.07C956.44,-442.47 1019.17,-384.6 1084.75,-357.36 1159.92,-326.12 1253.3,-316.73 1317.71,-314.31"/>
239
- <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="1317.53,-317.11 1325.43,-314.05 1317.35,-311.52 1317.53,-317.11"/>
238
+ <path fill="none" stroke="#a78bfa" stroke-width="1.3" d="M927.01,-483.93C956.37,-454.22 1019.05,-396.22 1084.75,-369.28 1160.56,-338.2 1253.55,-328.3 1321.87,-325.68"/>
239
+ <polygon fill="#a78bfa" stroke="#a78bfa" stroke-width="1.3" points="1321.9,-328.48 1329.8,-325.42 1321.71,-322.89 1321.9,-328.48"/>
240
240
  </g>
241
241
  <!-- Cleanup -->
242
242
  <g id="node15" class="node">
243
243
  <title>Cleanup</title>
244
- <path fill="#c4b5fd" stroke="#334155" stroke-width="1.4" d="M1488.38,-254.11C1488.38,-254.11 1302.12,-254.11 1302.12,-254.11 1296.12,-254.11 1290.12,-248.11 1290.12,-242.11 1290.12,-242.11 1290.12,-190.61 1290.12,-190.61 1290.12,-184.61 1296.12,-178.61 1302.12,-178.61 1302.12,-178.61 1488.38,-178.61 1488.38,-178.61 1494.38,-178.61 1500.38,-184.61 1500.38,-190.61 1500.38,-190.61 1500.38,-242.11 1500.38,-242.11 1500.38,-248.11 1494.38,-254.11 1488.38,-254.11"/>
245
- <text xml:space="preserve" text-anchor="middle" x="1395.25" y="-239.66" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">ONLY fresh default: session_cleanup</text>
246
- <text xml:space="preserve" text-anchor="middle" x="1395.25" y="-226.16" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">45 3 * * * ON (first&#45;slot guard)</text>
247
- <text xml:space="preserve" text-anchor="middle" x="1395.25" y="-212.66" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">evidence&#45;first maintenance</text>
248
- <text xml:space="preserve" text-anchor="middle" x="1395.25" y="-199.16" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">then memory consolidation</text>
249
- <text xml:space="preserve" text-anchor="middle" x="1395.25" y="-185.66" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0f172a">then learning / mistakes / policy retention</text>
244
+ <path fill="#c4b5fd" stroke="#334155" stroke-width="1.4" d="M1511.25,-266.03C1511.25,-266.03 1325,-266.03 1325,-266.03 1319,-266.03 1313,-260.03 1313,-254.03 1313,-254.03 1313,-202.53 1313,-202.53 1313,-196.53 1319,-190.53 1325,-190.53 1325,-190.53 1511.25,-190.53 1511.25,-190.53 1517.25,-190.53 1523.25,-196.53 1523.25,-202.53 1523.25,-202.53 1523.25,-254.03 1523.25,-254.03 1523.25,-260.03 1517.25,-266.03 1511.25,-266.03"/>
245
+ <text xml:space="preserve" text-anchor="middle" x="1418.12" y="-251.58" font-family="sans-Serif" font-size="11.00" fill="#0f172a">ONLY fresh default: session_cleanup</text>
246
+ <text xml:space="preserve" text-anchor="middle" x="1418.12" y="-238.08" font-family="sans-Serif" font-size="11.00" fill="#0f172a">45 3 * * * ON (first&#45;slot guard)</text>
247
+ <text xml:space="preserve" text-anchor="middle" x="1418.12" y="-224.58" font-family="sans-Serif" font-size="11.00" fill="#0f172a">evidence&#45;first maintenance</text>
248
+ <text xml:space="preserve" text-anchor="middle" x="1418.12" y="-211.08" font-family="sans-Serif" font-size="11.00" fill="#0f172a">then memory consolidation</text>
249
+ <text xml:space="preserve" text-anchor="middle" x="1418.12" y="-197.58" font-family="sans-Serif" font-size="11.00" fill="#0f172a">then learning / mistakes / policy retention</text>
250
250
  </g>
251
251
  <!-- Ruby&#45;&gt;Cleanup -->
252
252
  <g id="edge1" class="edge">
253
253
  <title>Ruby&#45;&gt;Cleanup</title>
254
- <path fill="none" stroke="#94a3b8" stroke-width="1.3" d="M918.66,-471.82C940.56,-429.04 1000.93,-323.25 1084.75,-273.36 1143.35,-238.47 1218.39,-224.05 1279.9,-218.44"/>
255
- <polygon fill="#94a3b8" stroke="#94a3b8" stroke-width="1.3" points="1279.95,-221.24 1287.69,-217.78 1279.48,-215.66 1279.95,-221.24"/>
254
+ <path fill="none" stroke="#94a3b8" stroke-width="1.3" d="M918.62,-483.68C940.43,-440.75 1000.62,-334.66 1084.75,-285.28 1150.44,-246.72 1235.2,-232.63 1302.69,-228.1"/>
255
+ <polygon fill="#94a3b8" stroke="#94a3b8" stroke-width="1.3" points="1302.74,-230.9 1310.56,-227.62 1302.4,-225.31 1302.74,-230.9"/>
256
256
  </g>
257
257
  <!-- Ruby&#45;&gt;Log -->
258
258
  <g id="edge19" class="edge">
259
259
  <title>Ruby&#45;&gt;Log</title>
260
- <path fill="none" stroke="#f59e0b" stroke-width="1.3" d="M916.55,-471.8C940.93,-407.54 1024.58,-196.54 1084.75,-160.36 1203.2,-89.12 1594.11,-80.24 1706.75,-160.36 1848.87,-261.44 1865.97,-498.03 1867.21,-586.85"/>
261
- <polygon fill="#f59e0b" stroke="#f59e0b" stroke-width="1.3" points="1864.41,-586.74 1867.27,-594.72 1870.01,-586.7 1864.41,-586.74"/>
260
+ <path fill="none" stroke="#f59e0b" stroke-width="1.3" d="M916.55,-483.72C940.93,-419.47 1024.58,-208.46 1084.75,-172.28 1211.91,-95.8 1631.58,-86.27 1752.5,-172.28 1894.62,-273.37 1911.72,-509.96 1912.96,-598.77"/>
261
+ <polygon fill="#f59e0b" stroke="#f59e0b" stroke-width="1.3" points="1910.16,-598.67 1913.02,-606.64 1915.76,-598.62 1910.16,-598.67"/>
262
262
  </g>
263
263
  <!-- Script&#45;&gt;Log -->
264
264
  <g id="edge20" class="edge">
265
265
  <title>Script&#45;&gt;Log</title>
266
- <path fill="none" stroke="#f59e0b" stroke-width="1.3" d="M919.89,-652.94C938.67,-685.14 981.76,-751.14 1036.75,-785.36 1315.82,-958.97 1488.52,-1155.07 1754.75,-962.36 1854.35,-890.26 1867.03,-726.75 1867.6,-655.55"/>
267
- <polygon fill="#f59e0b" stroke="#f59e0b" stroke-width="1.3" points="1870.4,-655.71 1867.61,-647.71 1864.8,-655.7 1870.4,-655.71"/>
266
+ <path fill="none" stroke="#f59e0b" stroke-width="1.3" d="M919.84,-664.94C938.55,-697.27 981.52,-763.45 1036.75,-797.28 1333.89,-979.26 1518.25,-1178.59 1800.5,-974.28 1900.1,-902.18 1912.78,-738.67 1913.35,-667.47"/>
267
+ <polygon fill="#f59e0b" stroke="#f59e0b" stroke-width="1.3" points="1916.15,-667.63 1913.36,-659.63 1910.55,-667.63 1916.15,-667.63"/>
268
268
  </g>
269
269
  <!-- Practice&#45;&gt;Log -->
270
270
  <g id="edge22" class="edge">
271
271
  <title>Practice&#45;&gt;Log</title>
272
- <path fill="none" stroke="#fbbf24" stroke-width="1.3" stroke-dasharray="5,2" d="M1409.88,-691.31C1457.01,-774.35 1617.66,-1030.87 1754.75,-934.36 1846.56,-869.72 1863.58,-722.6 1866.47,-655.66"/>
273
- <polygon fill="#fbbf24" stroke="#fbbf24" stroke-width="1.3" points="1869.25,-656.07 1866.74,-647.98 1863.66,-655.87 1869.25,-656.07"/>
272
+ <path fill="none" stroke="#fbbf24" stroke-width="1.3" stroke-dasharray="5,2" d="M1433.5,-702.94C1483.93,-786.33 1657.41,-1047.02 1800.5,-946.28 1892.31,-881.65 1909.33,-734.53 1912.22,-667.59"/>
273
+ <polygon fill="#fbbf24" stroke="#fbbf24" stroke-width="1.3" points="1915,-667.99 1912.49,-659.9 1909.41,-667.8 1915,-667.99"/>
274
274
  </g>
275
275
  <!-- Offline&#45;&gt;Log -->
276
276
  <g id="edge23" class="edge">
277
277
  <title>Offline&#45;&gt;Log</title>
278
- <path fill="none" stroke="#fbbf24" stroke-width="1.3" stroke-dasharray="5,2" d="M1461.98,-570.02C1532.34,-561.98 1642.49,-561.84 1706.75,-624.36 1797.83,-712.96 1656.8,-824.23 1753.75,-906.36 1838.04,-977.76 1860.01,-746.16 1865.31,-655.85"/>
279
- <polygon fill="#fbbf24" stroke="#fbbf24" stroke-width="1.3" points="1868.09,-656.17 1865.74,-648.03 1862.5,-655.86 1868.09,-656.17"/>
278
+ <path fill="none" stroke="#fbbf24" stroke-width="1.3" stroke-dasharray="5,2" d="M1484.86,-580.95C1560.03,-570.99 1681.8,-568.14 1752.5,-636.28 1843.99,-724.45 1702.55,-836.15 1799.5,-918.28 1883.79,-989.68 1905.76,-758.08 1911.06,-667.77"/>
279
+ <polygon fill="#fbbf24" stroke="#fbbf24" stroke-width="1.3" points="1913.84,-668.1 1911.49,-659.95 1908.25,-667.79 1913.84,-668.1"/>
280
280
  </g>
281
281
  <!-- Train&#45;&gt;Log -->
282
282
  <g id="edge24" class="edge">
283
283
  <title>Train&#45;&gt;Log</title>
284
- <path fill="none" stroke="#fbbf24" stroke-width="1.3" stroke-dasharray="5,2" d="M1467.62,-479.74C1538.45,-473.59 1645.11,-476.94 1706.75,-539.36 1809,-642.88 1643.72,-768.14 1753.75,-863.36 1825.05,-925.06 1854.45,-736.13 1863.53,-655.74"/>
285
- <polygon fill="#fbbf24" stroke="#fbbf24" stroke-width="1.3" points="1866.29,-656.26 1864.37,-648 1860.72,-655.65 1866.29,-656.26"/>
284
+ <path fill="none" stroke="#fbbf24" stroke-width="1.3" stroke-dasharray="5,2" d="M1490.39,-490.48C1566.25,-482.36 1684.52,-483.17 1752.5,-551.28 1855.29,-654.26 1689.47,-780.06 1799.5,-875.28 1870.8,-936.98 1900.2,-748.05 1909.28,-667.66"/>
285
+ <polygon fill="#fbbf24" stroke="#fbbf24" stroke-width="1.3" points="1912.04,-668.18 1910.12,-659.93 1906.47,-667.58 1912.04,-668.18"/>
286
286
  </g>
287
287
  <!-- MemGC&#45;&gt;Log -->
288
288
  <g id="edge25" class="edge">
289
289
  <title>MemGC&#45;&gt;Log</title>
290
- <path fill="none" stroke="#fbbf24" stroke-width="1.3" stroke-dasharray="5,2" d="M1471.35,-386.24C1542.2,-378.57 1646.31,-380.25 1706.75,-441.36 1826.1,-562.04 1626.56,-707.96 1753.75,-820.36 1812.65,-872.4 1848.06,-725.26 1861.12,-655.63"/>
291
- <polygon fill="#fbbf24" stroke="#fbbf24" stroke-width="1.3" points="1863.85,-656.27 1862.53,-647.89 1858.34,-655.26 1863.85,-656.27"/>
290
+ <path fill="none" stroke="#fbbf24" stroke-width="1.3" stroke-dasharray="5,2" d="M1504.76,-395.77C1580.59,-387.4 1688.83,-389.49 1752.5,-453.28 1872.4,-573.42 1672.31,-719.89 1799.5,-832.28 1858.4,-884.32 1893.81,-737.18 1906.87,-667.56"/>
291
+ <polygon fill="#fbbf24" stroke="#fbbf24" stroke-width="1.3" points="1909.6,-668.19 1908.28,-659.82 1904.09,-667.18 1909.6,-668.19"/>
292
292
  </g>
293
293
  <!-- Lean&#45;&gt;Log -->
294
294
  <g id="edge26" class="edge">
295
295
  <title>Lean&#45;&gt;Log</title>
296
- <path fill="none" stroke="#fbbf24" stroke-width="1.3" stroke-dasharray="5,2" d="M1463.17,-307.81C1530.25,-304.65 1633.77,-309.37 1706.75,-357.36 1791.01,-412.75 1837.9,-529.29 1856.84,-587.2"/>
297
- <polygon fill="#fbbf24" stroke="#fbbf24" stroke-width="1.3" points="1854.16,-587.99 1859.25,-594.76 1859.49,-586.29 1854.16,-587.99"/>
296
+ <path fill="none" stroke="#fbbf24" stroke-width="1.3" stroke-dasharray="5,2" d="M1504.81,-317.76C1576.61,-314.93 1678.89,-321.37 1752.5,-369.28 1837.23,-424.42 1884.02,-541.59 1902.79,-599.47"/>
297
+ <polygon fill="#fbbf24" stroke="#fbbf24" stroke-width="1.3" points="1900.09,-600.24 1905.17,-607.02 1905.43,-598.55 1900.09,-600.24"/>
298
298
  </g>
299
299
  <!-- Cleanup&#45;&gt;Log -->
300
300
  <g id="edge2" class="edge">
301
301
  <title>Cleanup&#45;&gt;Log</title>
302
- <path fill="none" stroke="#94a3b8" stroke-width="1.3" d="M1500.71,-212.14C1566.09,-214.74 1648.65,-228.21 1706.75,-273.36 1810.11,-353.67 1849.19,-516.19 1861.73,-587.04"/>
303
- <polygon fill="#94a3b8" stroke="#94a3b8" stroke-width="1.3" points="1858.96,-587.45 1863.06,-594.87 1864.48,-586.51 1858.96,-587.45"/>
302
+ <path fill="none" stroke="#94a3b8" stroke-width="1.3" d="M1523.8,-221.98C1595.03,-223.06 1687.75,-235.6 1752.5,-285.28 1856.35,-364.96 1895.16,-527.82 1907.56,-598.86"/>
303
+ <polygon fill="#94a3b8" stroke="#94a3b8" stroke-width="1.3" points="1904.79,-599.29 1908.88,-606.71 1910.31,-598.36 1904.79,-599.29"/>
304
304
  </g>
305
305
  <!-- Log&#45;&gt;Jobs -->
306
306
  <g id="edge21" class="edge">
307
307
  <title>Log&#45;&gt;Jobs</title>
308
- <path fill="none" stroke="#fbbf24" stroke-width="1.3" stroke-dasharray="5,2" d="M1863.59,-596.68C1850.17,-500.11 1795.88,-150.44 1706.75,-94.36 1472.77,52.87 1341.72,7.55 1084.75,-94.36 824.34,-197.63 825.79,-330.23 625.75,-526.36 604.43,-547.26 605.93,-562 578.75,-574.36 540.41,-591.79 493.17,-594.62 455.32,-593.05"/>
309
- <polygon fill="#fbbf24" stroke="#fbbf24" stroke-width="1.3" points="455.51,-590.26 447.37,-592.64 455.22,-595.85 455.51,-590.26"/>
310
- <text xml:space="preserve" text-anchor="middle" x="908.62" y="-293.88" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#cbd5e1">update status</text>
308
+ <path fill="none" stroke="#fbbf24" stroke-width="1.3" stroke-dasharray="5,2" d="M1909.4,-608.78C1896.09,-512.09 1841.92,-159.49 1752.5,-102.28 1502.51,57.67 1360.37,7.76 1084.75,-102.28 823.44,-206.6 826.21,-340.84 625.75,-538.28 604.48,-559.23 605.93,-573.92 578.75,-586.28 540.41,-603.71 493.17,-606.54 455.32,-604.98"/>
309
+ <polygon fill="#fbbf24" stroke="#fbbf24" stroke-width="1.3" points="455.51,-602.18 447.37,-604.56 455.22,-607.77 455.51,-602.18"/>
310
+ <text xml:space="preserve" text-anchor="middle" x="908.62" y="-302.58" font-family="sans-Serif" font-size="9.00" fill="#cbd5e1">update status</text>
311
311
  </g>
312
312
  </g>
313
313
  </svg>