@zerwiz/ymir 0.1.4 → 0.1.5

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 (850) hide show
  1. package/.agents/README.md +291 -0
  2. package/.agents/agents/bragi-marketer.md +111 -0
  3. package/.agents/agents/brokk.md +352 -0
  4. package/.agents/agents/forseti-reviewer.md +93 -0
  5. package/.agents/agents/frigg-consent.md +77 -0
  6. package/.agents/agents/groa-update.md +77 -0
  7. package/.agents/agents/hnoss-designer.md +69 -0
  8. package/.agents/agents/huginn-researcher.md +99 -0
  9. package/.agents/agents/jord-projects.md +78 -0
  10. package/.agents/agents/kvasir-scout.md +91 -0
  11. package/.agents/agents/mimir-planner.md +92 -0
  12. package/.agents/agents/muninn-stow.md +77 -0
  13. package/.agents/agents/saga-bearings.md +78 -0
  14. package/.agents/agents/sindri-developer.md +114 -0
  15. package/.agents/agents/snotra-documenter.md +105 -0
  16. package/.agents/agents/syn-recovery.md +78 -0
  17. package/.agents/agents/tyr-check.md +78 -0
  18. package/.agents/agents/urdh-hold.md +77 -0
  19. package/.agents/agents/volundr-smith.md +80 -0
  20. package/.agents/agents/vor-diagnostics.md +77 -0
  21. package/.agents/assets/agents/naming.md +50 -0
  22. package/.agents/assets/agents/registry.md +93 -0
  23. package/.agents/assets/agents/runtime.md +36 -0
  24. package/.agents/assets/agents/toon-tasks-cli.md +42 -0
  25. package/.agents/assets/templates/company_entity.template.md +37 -0
  26. package/.agents/backend/backends/cmux.sh +649 -0
  27. package/.agents/backend/backends/herdr-eventwait.py +157 -0
  28. package/.agents/backend/backends/herdr-workspace-move.py +114 -0
  29. package/.agents/backend/backends/herdr.sh +3386 -0
  30. package/.agents/backend/backends/orca.sh +290 -0
  31. package/.agents/backend/backends/tmux.sh +357 -0
  32. package/.agents/backend/backends/zellij.sh +700 -0
  33. package/.agents/backend/fm-afk-launch.sh +654 -0
  34. package/.agents/backend/fm-afk-return.sh +241 -0
  35. package/.agents/backend/fm-afk-start.sh +172 -0
  36. package/.agents/backend/fm-arm-command-policy.mjs +960 -0
  37. package/.agents/backend/fm-arm-pretool-check.sh +200 -0
  38. package/.agents/backend/fm-backend-hometag-lib.sh +52 -0
  39. package/.agents/backend/fm-backend.sh +981 -0
  40. package/.agents/backend/fm-backlog-handoff.sh +909 -0
  41. package/.agents/backend/fm-backlog-receive.sh +187 -0
  42. package/.agents/backend/fm-backlog-transition-lib.sh +779 -0
  43. package/.agents/backend/fm-bearings-board.sh +204 -0
  44. package/.agents/backend/fm-bearings-snapshot.sh +546 -0
  45. package/.agents/backend/fm-bootstrap.sh +1568 -0
  46. package/.agents/backend/fm-branch-outcome.sh +203 -0
  47. package/.agents/backend/fm-branch-prompt.sh +101 -0
  48. package/.agents/backend/fm-brief.sh +452 -0
  49. package/.agents/backend/fm-busy-event.sh +234 -0
  50. package/.agents/backend/fm-busy-lib.sh +986 -0
  51. package/.agents/backend/fm-captain-hold.sh +1001 -0
  52. package/.agents/backend/fm-cd-command-policy.mjs +153 -0
  53. package/.agents/backend/fm-cd-pretool-check.sh +190 -0
  54. package/.agents/backend/fm-check-lib.sh +74 -0
  55. package/.agents/backend/fm-check-register.sh +42 -0
  56. package/.agents/backend/fm-check-unregister.sh +52 -0
  57. package/.agents/backend/fm-classify-lib.sh +1770 -0
  58. package/.agents/backend/fm-claude-stop-autoarm.sh +334 -0
  59. package/.agents/backend/fm-composer-lib.sh +1416 -0
  60. package/.agents/backend/fm-config-inherit-lib.sh +1202 -0
  61. package/.agents/backend/fm-config-push.sh +254 -0
  62. package/.agents/backend/fm-control-lib.sh +251 -0
  63. package/.agents/backend/fm-control.sh +878 -0
  64. package/.agents/backend/fm-crew-state.sh +625 -0
  65. package/.agents/backend/fm-cursor-lib.sh +243 -0
  66. package/.agents/backend/fm-decision-hold.sh +232 -0
  67. package/.agents/backend/fm-doc-audience-check.sh +269 -0
  68. package/.agents/backend/fm-dod-lib.sh +67 -0
  69. package/.agents/backend/fm-ensure-agents-md.sh +253 -0
  70. package/.agents/backend/fm-extension-launch-barrier.mjs +129 -0
  71. package/.agents/backend/fm-extension.mjs +2577 -0
  72. package/.agents/backend/fm-extension.sh +16 -0
  73. package/.agents/backend/fm-ff-lib.sh +420 -0
  74. package/.agents/backend/fm-fleet-snapshot.sh +1463 -0
  75. package/.agents/backend/fm-fleet-sync.sh +458 -0
  76. package/.agents/backend/fm-fleet-view.sh +96 -0
  77. package/.agents/backend/fm-gate-refuse-lib.sh +102 -0
  78. package/.agents/backend/fm-guard.sh +242 -0
  79. package/.agents/backend/fm-harness.sh +195 -0
  80. package/.agents/backend/fm-herdr-ci-cleanup.sh +115 -0
  81. package/.agents/backend/fm-herdr-lab.sh +346 -0
  82. package/.agents/backend/fm-herdr-session-cleanup.sh +337 -0
  83. package/.agents/backend/fm-home-seed.sh +984 -0
  84. package/.agents/backend/fm-home-summary-refresh.sh +255 -0
  85. package/.agents/backend/fm-hook-host-lib.sh +36 -0
  86. package/.agents/backend/fm-inactive-reconcile.sh +531 -0
  87. package/.agents/backend/fm-inbox.sh +399 -0
  88. package/.agents/backend/fm-install-actionlint.sh +84 -0
  89. package/.agents/backend/fm-install-herdr.sh +96 -0
  90. package/.agents/backend/fm-install-shellcheck.sh +84 -0
  91. package/.agents/backend/fm-install-treehouse.sh +95 -0
  92. package/.agents/backend/fm-kimi-turnend-hook.sh +276 -0
  93. package/.agents/backend/fm-lease-lib.sh +218 -0
  94. package/.agents/backend/fm-lease.sh +189 -0
  95. package/.agents/backend/fm-line-cap-lib.sh +51 -0
  96. package/.agents/backend/fm-lint-workflows.sh +137 -0
  97. package/.agents/backend/fm-lint.sh +591 -0
  98. package/.agents/backend/fm-lock-lib.sh +104 -0
  99. package/.agents/backend/fm-lock.sh +107 -0
  100. package/.agents/backend/fm-marker-lib.sh +12 -0
  101. package/.agents/backend/fm-merge-local.sh +74 -0
  102. package/.agents/backend/fm-merge-outcome-lib.sh +138 -0
  103. package/.agents/backend/fm-nm-run-lib.sh +124 -0
  104. package/.agents/backend/fm-on.sh +125 -0
  105. package/.agents/backend/fm-operational-input.sh +253 -0
  106. package/.agents/backend/fm-peek.sh +46 -0
  107. package/.agents/backend/fm-pending-reply-lib.sh +1409 -0
  108. package/.agents/backend/fm-pr-check.sh +135 -0
  109. package/.agents/backend/fm-pr-lib.sh +1016 -0
  110. package/.agents/backend/fm-pr-merge.sh +707 -0
  111. package/.agents/backend/fm-pr-poll.sh +110 -0
  112. package/.agents/backend/fm-primary-scope-lib.sh +33 -0
  113. package/.agents/backend/fm-procevent-extension-capture.pl +259 -0
  114. package/.agents/backend/fm-procevent-lavish.sh +628 -0
  115. package/.agents/backend/fm-procevent-lib.sh +892 -0
  116. package/.agents/backend/fm-procevent-quota.sh +290 -0
  117. package/.agents/backend/fm-procevent-remote-reply.sh +577 -0
  118. package/.agents/backend/fm-procevent-when.sh +504 -0
  119. package/.agents/backend/fm-procevent.sh +1466 -0
  120. package/.agents/backend/fm-project-mode.sh +92 -0
  121. package/.agents/backend/fm-project-origin-lib.sh +180 -0
  122. package/.agents/backend/fm-promote.sh +282 -0
  123. package/.agents/backend/fm-public-followup-emit.sh +260 -0
  124. package/.agents/backend/fm-public-followup-lib.sh +398 -0
  125. package/.agents/backend/fm-public-followup.sh +1330 -0
  126. package/.agents/backend/fm-push-transition-lib.sh +168 -0
  127. package/.agents/backend/fm-quota-axi-lib.sh +93 -0
  128. package/.agents/backend/fm-quota-choose.sh +384 -0
  129. package/.agents/backend/fm-remote-delta-read.sh +189 -0
  130. package/.agents/backend/fm-remote-doctor.sh +800 -0
  131. package/.agents/backend/fm-remote-entrypoint.sh +193 -0
  132. package/.agents/backend/fm-remote-file.sh +234 -0
  133. package/.agents/backend/fm-remote-home-provision.sh +259 -0
  134. package/.agents/backend/fm-remote-home-seed.sh +259 -0
  135. package/.agents/backend/fm-remote-inherit-push.sh +90 -0
  136. package/.agents/backend/fm-remote-inherit.sh +179 -0
  137. package/.agents/backend/fm-remote-job-lib.sh +1241 -0
  138. package/.agents/backend/fm-remote-job-reap-orphans.sh +137 -0
  139. package/.agents/backend/fm-remote-job-worker.sh +1124 -0
  140. package/.agents/backend/fm-remote-readiness-lib.sh +44 -0
  141. package/.agents/backend/fm-remote-secondmate-control.sh +340 -0
  142. package/.agents/backend/fm-review-diff.sh +158 -0
  143. package/.agents/backend/fm-secondmate-charter-lib.sh +44 -0
  144. package/.agents/backend/fm-secondmate-nudge-lib.sh +68 -0
  145. package/.agents/backend/fm-secondmate-parent-lib.sh +70 -0
  146. package/.agents/backend/fm-secondmate-reconcile.sh +371 -0
  147. package/.agents/backend/fm-secondmate-registry-lib.sh +311 -0
  148. package/.agents/backend/fm-secondmate-report.sh +88 -0
  149. package/.agents/backend/fm-send.sh +1059 -0
  150. package/.agents/backend/fm-session-lock-lib.sh +176 -0
  151. package/.agents/backend/fm-session-start.sh +970 -0
  152. package/.agents/backend/fm-sessionstart-cursor.sh +40 -0
  153. package/.agents/backend/fm-sessionstart-nudge.sh +45 -0
  154. package/.agents/backend/fm-sessionstart-run.sh +145 -0
  155. package/.agents/backend/fm-spawn.sh +3153 -0
  156. package/.agents/backend/fm-startup-memory-budget-lib.sh +224 -0
  157. package/.agents/backend/fm-startup-memory-budget.sh +94 -0
  158. package/.agents/backend/fm-startup-network.sh +642 -0
  159. package/.agents/backend/fm-stow-cascade.sh +251 -0
  160. package/.agents/backend/fm-subagent-pretool-check.sh +207 -0
  161. package/.agents/backend/fm-supervise-daemon.sh +1732 -0
  162. package/.agents/backend/fm-supervision-instructions.sh +215 -0
  163. package/.agents/backend/fm-supervision-lib.sh +90 -0
  164. package/.agents/backend/fm-supervisor-target-lib.sh +78 -0
  165. package/.agents/backend/fm-tangle-lib.sh +53 -0
  166. package/.agents/backend/fm-task-inbox-lib.sh +402 -0
  167. package/.agents/backend/fm-tasks-axi-lib.sh +123 -0
  168. package/.agents/backend/fm-teardown.sh +2922 -0
  169. package/.agents/backend/fm-test-isolation-proof.sh +588 -0
  170. package/.agents/backend/fm-test-run.sh +2191 -0
  171. package/.agents/backend/fm-timeout-lib.sh +141 -0
  172. package/.agents/backend/fm-timing-lib.sh +179 -0
  173. package/.agents/backend/fm-tmux-lib.sh +291 -0
  174. package/.agents/backend/fm-tool-update-check.sh +898 -0
  175. package/.agents/backend/fm-trace-context-lib.sh +227 -0
  176. package/.agents/backend/fm-transition-lib.sh +103 -0
  177. package/.agents/backend/fm-turnend-guard-cursor.sh +391 -0
  178. package/.agents/backend/fm-turnend-guard-grok.sh +90 -0
  179. package/.agents/backend/fm-turnend-guard.sh +432 -0
  180. package/.agents/backend/fm-update.sh +110 -0
  181. package/.agents/backend/fm-vendor-auth-probe.sh +190 -0
  182. package/.agents/backend/fm-voice-client.py +1373 -0
  183. package/.agents/backend/fm-voice-relay.py +1256 -0
  184. package/.agents/backend/fm-wake-drain.sh +592 -0
  185. package/.agents/backend/fm-wake-grant.sh +127 -0
  186. package/.agents/backend/fm-wake-lib.sh +1849 -0
  187. package/.agents/backend/fm-watch-arm.sh +602 -0
  188. package/.agents/backend/fm-watch-checkpoint.sh +109 -0
  189. package/.agents/backend/fm-watch.sh +1962 -0
  190. package/.agents/backend/fm-x-dismiss.sh +116 -0
  191. package/.agents/backend/fm-x-followup.sh +286 -0
  192. package/.agents/backend/fm-x-lib.sh +1000 -0
  193. package/.agents/backend/fm-x-link.sh +234 -0
  194. package/.agents/backend/fm-x-poll.sh +185 -0
  195. package/.agents/backend/fm-x-reply.sh +385 -0
  196. package/.agents/backend/fm_voice_frame.py +166 -0
  197. package/.agents/backend/fm_voice_records.py +574 -0
  198. package/.agents/backend/model-bridge.py +290 -0
  199. package/.agents/backend/opencode-go-bridge.py +30 -0
  200. package/.agents/bus/README.md +12 -0
  201. package/.agents/bus/messages.json +1 -0
  202. package/.agents/config/agents.machine.example.yaml +16 -0
  203. package/.agents/config/agents.yaml +50 -0
  204. package/.agents/config/agents.yaml.example +72 -0
  205. package/.agents/config/crew-dispatch.json +22 -0
  206. package/.agents/config/cron.yaml +9 -0
  207. package/.agents/config/eindri-dispatch.json +67 -0
  208. package/.agents/config/eindri-harness +1 -0
  209. package/.agents/config/startup-memory-budget +1 -0
  210. package/.agents/config/tailscale-sync.yaml +27 -0
  211. package/.agents/filebrowser/.filebrowser.json +6 -0
  212. package/.agents/filebrowser/README.md +11 -0
  213. package/.agents/gateway/README.md +12 -0
  214. package/.agents/github/README.md +15 -0
  215. package/.agents/github/webhooks/.gitkeep +0 -0
  216. package/.agents/github/workflows/.gitkeep +0 -0
  217. package/.agents/harness/opencode/plugins/lib/rodd-operational-input.js +37 -0
  218. package/.agents/harness/opencode/plugins/package.json +4 -0
  219. package/.agents/harness/opencode/plugins/saga-sessionstart.js +77 -0
  220. package/.agents/harness/opencode/plugins/syn-cd-check.js +61 -0
  221. package/.agents/harness/opencode/plugins/syn-pretool-check.js +68 -0
  222. package/.agents/harness/opencode/plugins/syn-turnend-guard.js +105 -0
  223. package/.agents/harness/opencode/plugins/syn-watch-arm.js +521 -0
  224. package/.agents/memory/README.md +46 -0
  225. package/.agents/memory/kaia.engram +0 -0
  226. package/.agents/memory/kaia.engram-shm +0 -0
  227. package/.agents/memory/kaia.engram-wal +0 -0
  228. package/.agents/memory/runes_audit.md +5 -0
  229. package/.agents/memory/well/episodes.jsonl +367 -0
  230. package/.agents/memory/well/workspace.jsonl +27 -0
  231. package/.agents/migrations/0001-hodd-layout.sh +38 -0
  232. package/.agents/migrations/0002-a2a-mcp.sh +27 -0
  233. package/.agents/migrations/0003-private-data-separation.sh +111 -0
  234. package/.agents/migrations/0004-hoard-and-realms.sh +104 -0
  235. package/.agents/sandbox/Dockerfile.utgard +19 -0
  236. package/.agents/sandbox/README.md +14 -0
  237. package/.agents/sandbox/utgard.config.json +14 -0
  238. package/.agents/skills/README.md +59 -0
  239. package/.agents/skills/bragi-marketing/README.md +3 -0
  240. package/.agents/skills/bragi-marketing/SKILL.md +82 -0
  241. package/.agents/skills/eindri-homes/README.md +3 -0
  242. package/.agents/skills/eindri-homes/SKILL.md +291 -0
  243. package/.agents/skills/eindri-homes/assets/control-plane.md +122 -0
  244. package/.agents/skills/eindri-homes/assets/dispatch.md +80 -0
  245. package/.agents/skills/frigg-consent/README.md +3 -0
  246. package/.agents/skills/frigg-consent/SKILL.md +56 -0
  247. package/.agents/skills/galdr-ymirsystem/README.md +3 -0
  248. package/.agents/skills/galdr-ymirsystem/SKILL.md +158 -0
  249. package/.agents/skills/galdr-ymirsystem/assets/README.md +74 -0
  250. package/.agents/skills/galdr-ymirsystem/assets/brokk-distro-runtime.md +390 -0
  251. package/.agents/skills/galdr-ymirsystem/assets/build-method.md +113 -0
  252. package/.agents/skills/galdr-ymirsystem/assets/build-tool-categories.md +178 -0
  253. package/.agents/skills/galdr-ymirsystem/assets/eindri-orchestration.md +518 -0
  254. package/.agents/skills/galdr-ymirsystem/assets/eindri-profiles.md +136 -0
  255. package/.agents/skills/galdr-ymirsystem/assets/harness-integration/README.md +673 -0
  256. package/.agents/skills/galdr-ymirsystem/assets/harness-integration/claude-code.md +197 -0
  257. package/.agents/skills/galdr-ymirsystem/assets/harness-integration/codex.md +191 -0
  258. package/.agents/skills/galdr-ymirsystem/assets/harness-integration/cursor.md +193 -0
  259. package/.agents/skills/galdr-ymirsystem/assets/harness-integration/opencode.md +262 -0
  260. package/.agents/skills/galdr-ymirsystem/assets/harness-integration/pi.md +295 -0
  261. package/.agents/skills/galdr-ymirsystem/assets/hlidskjalf-ui.md +496 -0
  262. package/.agents/skills/galdr-ymirsystem/assets/installation.md +571 -0
  263. package/.agents/skills/galdr-ymirsystem/assets/local-models/HOST-DATA.example.md +72 -0
  264. package/.agents/skills/galdr-ymirsystem/assets/local-models.md +274 -0
  265. package/.agents/skills/galdr-ymirsystem/assets/memory-well.md +161 -0
  266. package/.agents/skills/galdr-ymirsystem/assets/nornir-jobs.md +377 -0
  267. package/.agents/skills/galdr-ymirsystem/assets/norse-naming.md +325 -0
  268. package/.agents/skills/galdr-ymirsystem/assets/odrerir-hall.md +129 -0
  269. package/.agents/skills/galdr-ymirsystem/assets/pi-boot/einherjar-spawn.schema.json +81 -0
  270. package/.agents/skills/galdr-ymirsystem/assets/pi-boot/herdr-profile.toml +75 -0
  271. package/.agents/skills/galdr-ymirsystem/assets/pi-boot/pi-profile.yml +96 -0
  272. package/.agents/skills/galdr-ymirsystem/assets/pi-boot/supervision-tree.yml +163 -0
  273. package/.agents/skills/galdr-ymirsystem/assets/pi-boot-guide.md +58 -0
  274. package/.agents/skills/galdr-ymirsystem/assets/porting-upstream-to-norse.md +301 -0
  275. package/.agents/skills/galdr-ymirsystem/assets/principles.md +385 -0
  276. package/.agents/skills/galdr-ymirsystem/assets/reference-adoption.md +99 -0
  277. package/.agents/skills/galdr-ymirsystem/assets/registry.md +379 -0
  278. package/.agents/skills/galdr-ymirsystem/assets/runtime-compliance.md +463 -0
  279. package/.agents/skills/galdr-ymirsystem/assets/runtime-components.md +553 -0
  280. package/.agents/skills/galdr-ymirsystem/assets/smidja.md +175 -0
  281. package/.agents/skills/galdr-ymirsystem/schemas/toon-schemas.md +190 -0
  282. package/.agents/skills/galdr-ymirsystem/scripts/README.md +45 -0
  283. package/.agents/skills/galdr-ymirsystem/scripts/bench-one.sh +248 -0
  284. package/.agents/skills/galdr-ymirsystem/scripts/compliance-check.sh +360 -0
  285. package/.agents/skills/galdr-ymirsystem/scripts/gpu-sample.sh +43 -0
  286. package/.agents/skills/galdr-ymirsystem/scripts/stop-all.sh +34 -0
  287. package/.agents/skills/galdr-ymirsystem/scripts/toon-check.py +188 -0
  288. package/.agents/skills/gjallarhorn-relay/README.md +3 -0
  289. package/.agents/skills/gjallarhorn-relay/SKILL.md +283 -0
  290. package/.agents/skills/groa-update/SKILL.md +70 -0
  291. package/.agents/skills/hamr-adapters/README.md +3 -0
  292. package/.agents/skills/hamr-adapters/SKILL.md +123 -0
  293. package/.agents/skills/hamr-adapters/references/common/control-and-recovery.md +37 -0
  294. package/.agents/skills/hamr-adapters/references/common/dispatch.md +32 -0
  295. package/.agents/skills/hamr-adapters/references/common/model-and-effort.md +42 -0
  296. package/.agents/skills/hamr-adapters/references/common/primary-hooks.md +40 -0
  297. package/.agents/skills/hamr-adapters/references/harness/claude.md +55 -0
  298. package/.agents/skills/hamr-adapters/references/harness/codex.md +43 -0
  299. package/.agents/skills/hamr-adapters/references/harness/cursor.md +75 -0
  300. package/.agents/skills/hamr-adapters/references/harness/grok.md +69 -0
  301. package/.agents/skills/hamr-adapters/references/harness/kimi.md +51 -0
  302. package/.agents/skills/hamr-adapters/references/harness/muse.md +70 -0
  303. package/.agents/skills/hamr-adapters/references/harness/opencode.md +42 -0
  304. package/.agents/skills/hamr-adapters/references/harness/pi.md +56 -0
  305. package/.agents/skills/herdr-panes/README.md +3 -0
  306. package/.agents/skills/herdr-panes/SKILL.md +92 -0
  307. package/.agents/skills/herdr-panes/assets/herdr-backend.md +346 -0
  308. package/.agents/skills/herdr-panes/assets/tmux-backend.md +115 -0
  309. package/.agents/skills/hnoss-design/DESIGN.md +19 -0
  310. package/.agents/skills/hnoss-design/README.md +3 -0
  311. package/.agents/skills/hnoss-design/SKILL.md +83 -0
  312. package/.agents/skills/hvild-afk/README.md +3 -0
  313. package/.agents/skills/hvild-afk/SKILL.md +241 -0
  314. package/.agents/skills/jord-projects/README.md +3 -0
  315. package/.agents/skills/jord-projects/SKILL.md +92 -0
  316. package/.agents/skills/lifecycle/SKILL.md +56 -0
  317. package/.agents/skills/lifecycle/smoke_test.sh +52 -0
  318. package/.agents/skills/lifecycle/start.sh +21 -0
  319. package/.agents/skills/lifecycle/status.sh +35 -0
  320. package/.agents/skills/lifecycle/stop.sh +16 -0
  321. package/.agents/skills/muninn-stow/README.md +3 -0
  322. package/.agents/skills/muninn-stow/SKILL.md +309 -0
  323. package/.agents/skills/no-mistakes/SKILL.md +379 -0
  324. package/.agents/skills/nornir-schedule/README.md +3 -0
  325. package/.agents/skills/nornir-schedule/SKILL.md +25 -0
  326. package/.agents/skills/nornir-schedule/assets/events.md +137 -0
  327. package/.agents/skills/nornir-schedule/assets/quota.md +131 -0
  328. package/.agents/skills/nsr-compliance/README.md +3 -0
  329. package/.agents/skills/nsr-compliance/SKILL.md +29 -0
  330. package/.agents/skills/nsr-compliance/assets/nsr/README.md +40 -0
  331. package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/README.md +15 -0
  332. package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/git-workflow.md +18 -0
  333. package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/security.md +22 -0
  334. package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/tech-stack.md +8 -0
  335. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/SKILL.md +71 -0
  336. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/config/core_four.yaml +16 -0
  337. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/check_danger.sh +102 -0
  338. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/check_wiring.sh +69 -0
  339. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/validate_code.sh +29 -0
  340. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/verify_docs.py +66 -0
  341. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/generate.sh +109 -0
  342. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/harness/envelopes/result_envelope.json +14 -0
  343. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/harness/envelopes/task_envelope.json +20 -0
  344. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/harness/runner.py +303 -0
  345. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/telemetry/logger.py +112 -0
  346. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/README.md +18 -0
  347. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/config/README.md +10 -0
  348. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/README.md +12 -0
  349. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/check_env.sh +23 -0
  350. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/check_paths.sh +20 -0
  351. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/check_platform.sh +23 -0
  352. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/harness/README.md +11 -0
  353. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/harness/envelopes/README.md +10 -0
  354. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/installer/README.md +10 -0
  355. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/installer/install.sh +125 -0
  356. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/telemetry/README.md +11 -0
  357. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/README.md +20 -0
  358. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/features/README.md +36 -0
  359. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/features/SKILL-template.md +14 -0
  360. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/README.md +25 -0
  361. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/SKILL.md +13 -0
  362. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/create_branch.sh +6 -0
  363. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/safe_commit.sh +9 -0
  364. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/sync_upstream.sh +6 -0
  365. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/README.md +27 -0
  366. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/SKILL.md +15 -0
  367. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/smoke_test.sh +12 -0
  368. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/start.sh +19 -0
  369. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/status.sh +12 -0
  370. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/stop.sh +15 -0
  371. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/README.md +18 -0
  372. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/config/README.md +10 -0
  373. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/config/core_four.yaml +13 -0
  374. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/README.md +12 -0
  375. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_danger.sh +102 -0
  376. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_env.sh +23 -0
  377. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_paths.sh +20 -0
  378. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_platform.sh +23 -0
  379. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_wiring.sh +69 -0
  380. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/README.md +11 -0
  381. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/envelopes/README.md +10 -0
  382. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/envelopes/result_envelope.json +14 -0
  383. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/envelopes/task_envelope.json +20 -0
  384. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/runner.py +303 -0
  385. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/installer/README.md +10 -0
  386. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/installer/install.sh +125 -0
  387. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/telemetry/README.md +11 -0
  388. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/telemetry/logger.py +112 -0
  389. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/README.md +14 -0
  390. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/api.md +17 -0
  391. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/compliance-wiring.md +155 -0
  392. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/frontend.md +15 -0
  393. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/README.md +11 -0
  394. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/README.md +23 -0
  395. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/clients/README.md +16 -0
  396. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/clients/template-README.md +11 -0
  397. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/deploy.sh +49 -0
  398. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/README.md +12 -0
  399. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/development.env.example +17 -0
  400. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/production.env.example +17 -0
  401. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/staging.env.example +17 -0
  402. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/tenants/README.md +11 -0
  403. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/tenants/template.env.example +8 -0
  404. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/README.md +26 -0
  405. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/agent.md +7 -0
  406. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/developers/dev-1.md +20 -0
  407. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/linux.md +9 -0
  408. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/macos.md +10 -0
  409. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/shared.md +19 -0
  410. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/windows.md +14 -0
  411. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/HOSTING/README.md +25 -0
  412. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/HOSTING/_template.md +41 -0
  413. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/HOSTING/hosting-1.md +41 -0
  414. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/README.md +21 -0
  415. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/README.md +15 -0
  416. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/deployment.md +19 -0
  417. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/disaster-recovery.md +15 -0
  418. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/ops-tasks.md +14 -0
  419. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/features/README.md +16 -0
  420. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/project-skills.md +146 -0
  421. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/research/README.md +11 -0
  422. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/research/software-compliance-research.md +269 -0
  423. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/working-with-agents.md +260 -0
  424. package/.agents/skills/nsr-compliance/assets/nsr/assets/root/AGENTS.md +38 -0
  425. package/.agents/skills/nsr-compliance/assets/nsr/assets/root/ARCHITECTURE.md +36 -0
  426. package/.agents/skills/nsr-compliance/assets/nsr/assets/root/BEST_PRACTICES.md +27 -0
  427. package/.agents/skills/nsr-compliance/assets/nsr/assets/root/CI_CD.md +23 -0
  428. package/.agents/skills/nsr-compliance/assets/nsr/assets/root/FEATURES.md +15 -0
  429. package/.agents/skills/nsr-compliance/assets/nsr/assets/root/README.md +22 -0
  430. package/.agents/skills/nsr-compliance/assets/nsr/assets/root/RULES.md +37 -0
  431. package/.agents/skills/nsr-compliance/assets/nsr/assets/root/STRUCTURE.md +45 -0
  432. package/.agents/skills/nsr-compliance/assets/nsr/assets/root/TECH_STACK.md +28 -0
  433. package/.agents/skills/nsr-compliance/assets/nsr/scaffold-spec.md +63 -0
  434. package/.agents/skills/nsr-compliance/assets/nsr/scripts/scaffold.sh +103 -0
  435. package/.agents/skills/nsr-compliance/assets/nsr/scripts/validate.sh +52 -0
  436. package/.agents/skills/nsr-compliance/assets/nsrcompliance/SKILL.md +71 -0
  437. package/.agents/skills/nsr-compliance/assets/nsrcompliance/config/core_four.yaml +16 -0
  438. package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/check_danger.sh +102 -0
  439. package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/check_wiring.sh +69 -0
  440. package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/validate_code.sh +29 -0
  441. package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/verify_docs.py +66 -0
  442. package/.agents/skills/nsr-compliance/assets/nsrcompliance/generate.sh +109 -0
  443. package/.agents/skills/nsr-compliance/assets/nsrcompliance/harness/envelopes/result_envelope.json +14 -0
  444. package/.agents/skills/nsr-compliance/assets/nsrcompliance/harness/envelopes/task_envelope.json +20 -0
  445. package/.agents/skills/nsr-compliance/assets/nsrcompliance/harness/runner.py +303 -0
  446. package/.agents/skills/nsr-compliance/assets/nsrcompliance/telemetry/logger.py +112 -0
  447. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/README.md +18 -0
  448. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/config/README.md +10 -0
  449. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/README.md +12 -0
  450. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/check_env.sh +23 -0
  451. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/check_paths.sh +20 -0
  452. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/check_platform.sh +23 -0
  453. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/harness/README.md +11 -0
  454. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/harness/envelopes/README.md +10 -0
  455. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/installer/README.md +10 -0
  456. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/installer/install.sh +125 -0
  457. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/telemetry/README.md +11 -0
  458. package/.agents/skills/pr-ops/README.md +3 -0
  459. package/.agents/skills/pr-ops/SKILL.md +109 -0
  460. package/.agents/skills/ratatoskr-a2a/README.md +3 -0
  461. package/.agents/skills/ratatoskr-a2a/SKILL.md +148 -0
  462. package/.agents/skills/rules-check-drift/SKILL.md +81 -0
  463. package/.agents/skills/saga-bearings/README.md +3 -0
  464. package/.agents/skills/saga-bearings/SKILL.md +26 -0
  465. package/.agents/skills/saga-bearings/assets/bearings.md +161 -0
  466. package/.agents/skills/saga-bearings/assets/board-template.html +731 -0
  467. package/.agents/skills/saga-bearings/assets/recap.md +56 -0
  468. package/.agents/skills/syn-recovery/README.md +3 -0
  469. package/.agents/skills/syn-recovery/SKILL.md +54 -0
  470. package/.agents/skills/tyr-check/README.md +3 -0
  471. package/.agents/skills/tyr-check/SKILL.md +218 -0
  472. package/.agents/skills/urdh-hold/README.md +3 -0
  473. package/.agents/skills/urdh-hold/SKILL.md +25 -0
  474. package/.agents/skills/urdh-hold/assets/decisions.md +15 -0
  475. package/.agents/skills/urdh-hold/assets/hold.md +54 -0
  476. package/.agents/skills/vor-diagnostics/README.md +3 -0
  477. package/.agents/skills/vor-diagnostics/SKILL.md +68 -0
  478. package/.agents/skills/ymir-host/README.md +3 -0
  479. package/.agents/skills/ymir-host/SKILL.md +34 -0
  480. package/.agents/skills/ymir-host/assets/desktop.md +36 -0
  481. package/.agents/skills/ymir-host/assets/omarchy.md +297 -0
  482. package/.agents/skills/ymir-host/assets/runbooks.md +15 -0
  483. package/.agents/skills/ymir-host/assets/thjazi.md +220 -0
  484. package/.agents/skills/ymir-host/assets/update.md +64 -0
  485. package/.agents/tests/assets/board-render-harness.mjs +117 -0
  486. package/.agents/tests/cmux-test-safety.sh +51 -0
  487. package/.agents/tests/fixtures.sh +291 -0
  488. package/.agents/tests/fm-afk-inject-e2e.test.sh +428 -0
  489. package/.agents/tests/fm-afk-inject-herdr-e2e.test.sh +536 -0
  490. package/.agents/tests/fm-afk-launch.test.sh +961 -0
  491. package/.agents/tests/fm-afk-pi-herdr-return-e2e.test.sh +297 -0
  492. package/.agents/tests/fm-afk-return.test.sh +283 -0
  493. package/.agents/tests/fm-arm-pretool-check.test.sh +482 -0
  494. package/.agents/tests/fm-ask-user-authority.test.sh +42 -0
  495. package/.agents/tests/fm-backend-autodetect-smoke.test.sh +176 -0
  496. package/.agents/tests/fm-backend-cmux-smoke.test.sh +188 -0
  497. package/.agents/tests/fm-backend-cmux.test.sh +1166 -0
  498. package/.agents/tests/fm-backend-herdr-eventwait-smoke.test.sh +136 -0
  499. package/.agents/tests/fm-backend-herdr-eventwait.test.py +106 -0
  500. package/.agents/tests/fm-backend-herdr-focus-flash-e2e.test.sh +409 -0
  501. package/.agents/tests/fm-backend-herdr-launcher-workspace-e2e.test.sh +437 -0
  502. package/.agents/tests/fm-backend-herdr-presentation-e2e.test.sh +1424 -0
  503. package/.agents/tests/fm-backend-herdr-prune-safety-e2e.test.sh +180 -0
  504. package/.agents/tests/fm-backend-herdr-respawn-idem-e2e.test.sh +182 -0
  505. package/.agents/tests/fm-backend-herdr-smoke.test.sh +355 -0
  506. package/.agents/tests/fm-backend-herdr-workspace-per-home-e2e.test.sh +251 -0
  507. package/.agents/tests/fm-backend-herdr.test.sh +4606 -0
  508. package/.agents/tests/fm-backend-orca.test.sh +1357 -0
  509. package/.agents/tests/fm-backend-tmux-smoke.test.sh +173 -0
  510. package/.agents/tests/fm-backend-zellij-smoke.test.sh +205 -0
  511. package/.agents/tests/fm-backend-zellij.test.sh +1360 -0
  512. package/.agents/tests/fm-backend.test.sh +1142 -0
  513. package/.agents/tests/fm-backlog-atomicity.test.sh +2302 -0
  514. package/.agents/tests/fm-backlog-handoff.test.sh +1360 -0
  515. package/.agents/tests/fm-bearings-board-render.test.sh +135 -0
  516. package/.agents/tests/fm-bearings-board.test.sh +414 -0
  517. package/.agents/tests/fm-bearings-snapshot.test.sh +1990 -0
  518. package/.agents/tests/fm-bootstrap-network-parallel.test.sh +316 -0
  519. package/.agents/tests/fm-bootstrap.test.sh +1178 -0
  520. package/.agents/tests/fm-branch-supervision.test.sh +552 -0
  521. package/.agents/tests/fm-brief.test.sh +785 -0
  522. package/.agents/tests/fm-busy-adapter-wiring.test.sh +324 -0
  523. package/.agents/tests/fm-busy-state.test.sh +465 -0
  524. package/.agents/tests/fm-calm-pi-extension.test.sh +3979 -0
  525. package/.agents/tests/fm-captain-hold-lifecycle.test.sh +1187 -0
  526. package/.agents/tests/fm-cd-pretool-check.test.sh +400 -0
  527. package/.agents/tests/fm-check-unregister.test.sh +198 -0
  528. package/.agents/tests/fm-classify-corr-token.test.sh +543 -0
  529. package/.agents/tests/fm-classify-decision-key.test.sh +340 -0
  530. package/.agents/tests/fm-claude-stop-autoarm-live-e2e.test.sh +164 -0
  531. package/.agents/tests/fm-claude-stop-autoarm.test.sh +1190 -0
  532. package/.agents/tests/fm-cmux-claude-composer-live-e2e.test.sh +110 -0
  533. package/.agents/tests/fm-codex-continuity-live-e2e.test.sh +55 -0
  534. package/.agents/tests/fm-composer-ghost.test.sh +716 -0
  535. package/.agents/tests/fm-composer-lib.test.sh +666 -0
  536. package/.agents/tests/fm-composer-matrix-live-e2e.test.sh +220 -0
  537. package/.agents/tests/fm-control-herdr-smoke.test.sh +149 -0
  538. package/.agents/tests/fm-control-relaunch.test.sh +1530 -0
  539. package/.agents/tests/fm-control.test.sh +910 -0
  540. package/.agents/tests/fm-crew-state.test.sh +1610 -0
  541. package/.agents/tests/fm-cursor-harness.test.sh +404 -0
  542. package/.agents/tests/fm-cursor-primary-live-e2e.test.sh +217 -0
  543. package/.agents/tests/fm-cursor-primary.test.sh +708 -0
  544. package/.agents/tests/fm-daemon.test.sh +2740 -0
  545. package/.agents/tests/fm-documentation-audiences.test.sh +141 -0
  546. package/.agents/tests/fm-ensure-agents-md.test.sh +371 -0
  547. package/.agents/tests/fm-extension-binding.test.sh +2187 -0
  548. package/.agents/tests/fm-fleet-snapshot-view.test.sh +816 -0
  549. package/.agents/tests/fm-fleet-sync.test.sh +721 -0
  550. package/.agents/tests/fm-gate-refuse.test.sh +356 -0
  551. package/.agents/tests/fm-gitignore-config.test.sh +89 -0
  552. package/.agents/tests/fm-gotmp.test.sh +230 -0
  553. package/.agents/tests/fm-grok-continuity-live-e2e.test.sh +112 -0
  554. package/.agents/tests/fm-grok-harness.test.sh +117 -0
  555. package/.agents/tests/fm-grok-stop-live-e2e.test.sh +219 -0
  556. package/.agents/tests/fm-guard-stale-banner.test.sh +709 -0
  557. package/.agents/tests/fm-harness-adapter-instructions-live-e2e.test.sh +134 -0
  558. package/.agents/tests/fm-harness-adapter-references.test.sh +30 -0
  559. package/.agents/tests/fm-harness-liveness-drift-live-e2e.test.sh +151 -0
  560. package/.agents/tests/fm-herdr-lab.test.sh +243 -0
  561. package/.agents/tests/fm-herdr-session-cleanup-e2e.test.sh +146 -0
  562. package/.agents/tests/fm-herdr-session-cleanup.test.sh +329 -0
  563. package/.agents/tests/fm-herdr-submit-confirm-live-e2e.test.sh +125 -0
  564. package/.agents/tests/fm-herdr-version-floor-live-e2e.test.sh +144 -0
  565. package/.agents/tests/fm-home-summary-refresh.test.sh +971 -0
  566. package/.agents/tests/fm-inactive-reconcile.test.sh +485 -0
  567. package/.agents/tests/fm-kimi-harness.test.sh +687 -0
  568. package/.agents/tests/fm-lint-workflows.test.sh +532 -0
  569. package/.agents/tests/fm-lint.test.sh +1023 -0
  570. package/.agents/tests/fm-muse-harness.test.sh +932 -0
  571. package/.agents/tests/fm-muse-signals-live-e2e.test.sh +205 -0
  572. package/.agents/tests/fm-no-mistakes-required.test.sh +72 -0
  573. package/.agents/tests/fm-on.test.sh +507 -0
  574. package/.agents/tests/fm-opencode-primary-live-e2e.test.sh +357 -0
  575. package/.agents/tests/fm-operational-input.test.sh +160 -0
  576. package/.agents/tests/fm-peek-remote.test.sh +110 -0
  577. package/.agents/tests/fm-pending-reply.test.sh +1288 -0
  578. package/.agents/tests/fm-pi-branch-extension.test.sh +3182 -0
  579. package/.agents/tests/fm-pi-branch-live-e2e.test.sh +527 -0
  580. package/.agents/tests/fm-pi-primary-live-e2e.test.sh +345 -0
  581. package/.agents/tests/fm-pi-primary-types.test.sh +68 -0
  582. package/.agents/tests/fm-pi-watch-extension.test.sh +2843 -0
  583. package/.agents/tests/fm-pr-check-security.test.sh +2140 -0
  584. package/.agents/tests/fm-pr-merge.test.sh +2135 -0
  585. package/.agents/tests/fm-procevent-quota.test.sh +225 -0
  586. package/.agents/tests/fm-procevent-when.test.sh +406 -0
  587. package/.agents/tests/fm-procevent.test.sh +1745 -0
  588. package/.agents/tests/fm-project-origin.test.sh +110 -0
  589. package/.agents/tests/fm-public-followup.test.sh +2272 -0
  590. package/.agents/tests/fm-quota-array-dispatch-live-e2e.test.sh +526 -0
  591. package/.agents/tests/fm-quota-choose.test.sh +626 -0
  592. package/.agents/tests/fm-remote-backlog-handoff.test.sh +453 -0
  593. package/.agents/tests/fm-remote-doctor.test.sh +625 -0
  594. package/.agents/tests/fm-remote-entrypoint.test.sh +59 -0
  595. package/.agents/tests/fm-remote-job-orphan-reap.test.sh +205 -0
  596. package/.agents/tests/fm-remote-job.test.sh +768 -0
  597. package/.agents/tests/fm-remote-reply.test.sh +520 -0
  598. package/.agents/tests/fm-remote-secondmate-lifecycle-e2e.test.sh +1256 -0
  599. package/.agents/tests/fm-remote-secondmate-parent-binding.test.sh +326 -0
  600. package/.agents/tests/fm-remote-secondmate-trace-context.test.sh +310 -0
  601. package/.agents/tests/fm-remote-transport-lanes.test.sh +431 -0
  602. package/.agents/tests/fm-review-diff.test.sh +176 -0
  603. package/.agents/tests/fm-secondmate-harness.test.sh +2600 -0
  604. package/.agents/tests/fm-secondmate-lifecycle-e2e.test.sh +259 -0
  605. package/.agents/tests/fm-secondmate-liveness.test.sh +559 -0
  606. package/.agents/tests/fm-secondmate-reconcile.test.sh +732 -0
  607. package/.agents/tests/fm-secondmate-safety.test.sh +2972 -0
  608. package/.agents/tests/fm-secondmate-sync.test.sh +913 -0
  609. package/.agents/tests/fm-send-inbox-doorbell-live-e2e.test.sh +206 -0
  610. package/.agents/tests/fm-send-inbox.test.sh +352 -0
  611. package/.agents/tests/fm-send-popup-settle.test.sh +167 -0
  612. package/.agents/tests/fm-send-remote-delivery.test.sh +796 -0
  613. package/.agents/tests/fm-send-resolve-key.test.sh +551 -0
  614. package/.agents/tests/fm-send-secondmate-marker-herdr-e2e.test.sh +187 -0
  615. package/.agents/tests/fm-send-secondmate-marker.test.sh +278 -0
  616. package/.agents/tests/fm-send-settle.test.sh +147 -0
  617. package/.agents/tests/fm-send-strict.test.sh +241 -0
  618. package/.agents/tests/fm-session-lock-ancestry.test.sh +365 -0
  619. package/.agents/tests/fm-session-start.test.sh +2515 -0
  620. package/.agents/tests/fm-sessionstart-hook-live-e2e.test.sh +631 -0
  621. package/.agents/tests/fm-sessionstart-instruction-refresh-live-e2e.test.sh +230 -0
  622. package/.agents/tests/fm-sessionstart-nudge.test.sh +1039 -0
  623. package/.agents/tests/fm-shared-captain-inheritance.test.sh +404 -0
  624. package/.agents/tests/fm-spawn-batch.test.sh +148 -0
  625. package/.agents/tests/fm-spawn-dispatch-profile.test.sh +827 -0
  626. package/.agents/tests/fm-spawn-pool-base-freshen.test.sh +440 -0
  627. package/.agents/tests/fm-spawn-worktree-settle.test.sh +147 -0
  628. package/.agents/tests/fm-startup-memory-budget.test.sh +333 -0
  629. package/.agents/tests/fm-startup-network.test.sh +712 -0
  630. package/.agents/tests/fm-stow-cascade.test.sh +370 -0
  631. package/.agents/tests/fm-subagent-pretool-check.test.sh +291 -0
  632. package/.agents/tests/fm-supervision-events.test.sh +156 -0
  633. package/.agents/tests/fm-supervision-instructions.test.sh +189 -0
  634. package/.agents/tests/fm-tangle-guard.test.sh +277 -0
  635. package/.agents/tests/fm-task-delivery.test.sh +420 -0
  636. package/.agents/tests/fm-task-inbox.test.sh +513 -0
  637. package/.agents/tests/fm-teardown-endpoint-safety.test.sh +374 -0
  638. package/.agents/tests/fm-teardown.test.sh +2665 -0
  639. package/.agents/tests/fm-test-fixture-cleanup.test.sh +172 -0
  640. package/.agents/tests/fm-test-fixtures.test.sh +132 -0
  641. package/.agents/tests/fm-test-isolation-proof.test.sh +278 -0
  642. package/.agents/tests/fm-test-run.test.sh +1196 -0
  643. package/.agents/tests/fm-tmux-agent-liveness.test.sh +354 -0
  644. package/.agents/tests/fm-tmux-submit-busy.test.sh +340 -0
  645. package/.agents/tests/fm-tool-update-check.test.sh +1044 -0
  646. package/.agents/tests/fm-trace-context-lib.test.sh +253 -0
  647. package/.agents/tests/fm-trace-context-spawn.test.sh +581 -0
  648. package/.agents/tests/fm-transition-lib.test.sh +54 -0
  649. package/.agents/tests/fm-turnend-guard.test.sh +1822 -0
  650. package/.agents/tests/fm-update.test.sh +304 -0
  651. package/.agents/tests/fm-vendor-auth-probe.test.sh +395 -0
  652. package/.agents/tests/fm-voice-relay.test.sh +4741 -0
  653. package/.agents/tests/fm-wake-daemon-lifecycle-e2e.test.sh +171 -0
  654. package/.agents/tests/fm-wake-drain-open-decisions-cursor.test.sh +356 -0
  655. package/.agents/tests/fm-wake-drain-open-decisions.test.sh +226 -0
  656. package/.agents/tests/fm-wake-drain-unread-status.test.sh +379 -0
  657. package/.agents/tests/fm-wake-queue.test.sh +1224 -0
  658. package/.agents/tests/fm-watch-arm.test.sh +821 -0
  659. package/.agents/tests/fm-watch-checkpoint.test.sh +87 -0
  660. package/.agents/tests/fm-watch-recovery-loop.test.sh +223 -0
  661. package/.agents/tests/fm-watch-triage.test.sh +3889 -0
  662. package/.agents/tests/fm-watcher-lock.test.sh +1133 -0
  663. package/.agents/tests/fm-x-mode.test.sh +3042 -0
  664. package/.agents/tests/gleipnir-guard-pretool-check.test.sh +51 -0
  665. package/.agents/tests/gleipnir-machine-lock.test.sh +130 -0
  666. package/.agents/tests/herdr-test-safety.sh +42 -0
  667. package/.agents/tests/lib.sh +315 -0
  668. package/.agents/tests/remote-herdr-fixture.sh +125 -0
  669. package/.agents/tests/secondmate-helpers.sh +193 -0
  670. package/.agents/tests/smoke.test.sh +93 -0
  671. package/.agents/tests/wake-helpers.sh +338 -0
  672. package/.agents/tests/zellij-test-safety.sh +60 -0
  673. package/.agents/tools/README.md +10 -0
  674. package/.agents/tools/bin/tasks-cli +267 -0
  675. package/.agents/tools/tasks-cli.ts +216 -0
  676. package/AGENTS.md +454 -0
  677. package/CHANGELOG.md +881 -0
  678. package/LICENSE +1 -1
  679. package/NOTICE +63 -0
  680. package/README.md +113 -59
  681. package/RULES/01-domains.md +51 -0
  682. package/RULES/02-agents.md +78 -0
  683. package/RULES/03-houses.md +61 -0
  684. package/RULES/04-hoard.md +65 -0
  685. package/RULES/05-platforms.md +67 -0
  686. package/RULES/06-append-only.md +58 -0
  687. package/RULES/07-config.md +45 -0
  688. package/RULES/08-delivery-gate.md +75 -0
  689. package/RULES/README.md +20 -0
  690. package/bin/README.md +107 -0
  691. package/bin/a2a-mcp.sh +98 -0
  692. package/bin/a2a-serve.py +103 -0
  693. package/bin/a2a-serve.sh +8 -0
  694. package/bin/a2a-talk.sh +50 -0
  695. package/bin/a2abridge-ensure.sh +108 -0
  696. package/bin/agent-run.sh +43 -0
  697. package/bin/agents-config.sh +233 -0
  698. package/bin/apodex-smoke-test.sh +92 -0
  699. package/bin/bifrost-bridge.sh +112 -0
  700. package/bin/bifrost-ingress.sh +77 -0
  701. package/bin/bootstrap-macos.sh +107 -0
  702. package/bin/bootstrap-windows.ps1 +112 -0
  703. package/bin/branch-guard.sh +64 -0
  704. package/bin/brokk +73 -0
  705. package/bin/brokk-classify-lib.sh +1770 -0
  706. package/bin/brokk-lease-lib.sh +222 -0
  707. package/bin/brokk-lease.sh +193 -0
  708. package/bin/brokk-lint.sh +65 -0
  709. package/bin/brokk-send.sh +38 -0
  710. package/bin/brokk-update.sh +9 -0
  711. package/bin/brokk-wake-grant.sh +127 -0
  712. package/bin/brokk-wake-lib.sh +1849 -0
  713. package/bin/changelog-guard.sh +165 -0
  714. package/bin/crash-sense.sh +160 -0
  715. package/bin/desktop-place.sh +224 -0
  716. package/bin/docs-guard.sh +39 -0
  717. package/bin/editor-place.sh +207 -0
  718. package/bin/eindri-acclaim.sh +34 -0
  719. package/bin/eindri-control.sh +28 -0
  720. package/bin/eindri-role.sh +83 -0
  721. package/bin/eindri-seen.sh +41 -0
  722. package/bin/eindri-send.sh +15 -0
  723. package/bin/eindri-start.sh +85 -0
  724. package/bin/eindri-watch.sh +57 -0
  725. package/bin/einherjar-spawn.sh +576 -0
  726. package/bin/eir-doctor.sh +112 -0
  727. package/bin/erindi-brief.sh +271 -0
  728. package/bin/fleet-apply.sh +68 -0
  729. package/bin/github-deploy.sh +81 -0
  730. package/bin/gjallarhorn-expose.sh +102 -0
  731. package/bin/gjallarhorn-notify.sh +58 -0
  732. package/bin/gjallarhorn-purge.sh +54 -0
  733. package/bin/gjallarhorn-tunnel.sh +72 -0
  734. package/bin/gleipnir-lock-lib.sh +284 -0
  735. package/bin/groa-update.sh +122 -0
  736. package/bin/hall-snapshot.sh +92 -0
  737. package/bin/hamr-harness.sh +246 -0
  738. package/bin/heimdall-ssh-keys.sh +374 -0
  739. package/bin/herdr-agents.py +44 -0
  740. package/bin/herdr-ensure.sh +104 -0
  741. package/bin/herdr-run.sh +431 -0
  742. package/bin/hermes-ensure.sh +88 -0
  743. package/bin/hoard-lib.sh +25 -0
  744. package/bin/hodd.sh +78 -0
  745. package/bin/host-sense.sh +199 -0
  746. package/bin/huginn-research-worker.sh +108 -0
  747. package/bin/local-model-lock.sh +51 -0
  748. package/bin/mimir-bridge.py +226 -0
  749. package/bin/mimir-bridge.sh +87 -0
  750. package/bin/mimir-ingest.sh +131 -0
  751. package/bin/mimir.sh +113 -0
  752. package/bin/mjollnir-webhook.sh +59 -0
  753. package/bin/mjollnir.sh +85 -0
  754. package/bin/model-hardware.sh +82 -0
  755. package/bin/model-resolve.sh +147 -0
  756. package/bin/models-detect.sh +178 -0
  757. package/bin/nornir-cron-start.sh +162 -0
  758. package/bin/nornir-job-daily-briefing.sh +191 -0
  759. package/bin/nornir-job-git-sync.sh +152 -0
  760. package/bin/nornir-job-memory-housekeeping.sh +114 -0
  761. package/bin/nornir-job-observer.sh +166 -0
  762. package/bin/nornir-job-skillopt-sleep.sh +76 -0
  763. package/bin/omarchy-hook-install.sh +60 -0
  764. package/bin/omarchy-install.sh +148 -0
  765. package/bin/omarchy-plugins.sh +174 -0
  766. package/bin/omarchy-sense.sh +149 -0
  767. package/bin/perm-guard.sh +30 -0
  768. package/bin/pi-agent.sh +68 -0
  769. package/bin/pi-ensure.sh +77 -0
  770. package/bin/pi-local.sh +37 -0
  771. package/bin/pi-seat.sh +63 -0
  772. package/bin/prereq-ensure.sh +166 -0
  773. package/bin/private-guard.sh +38 -0
  774. package/bin/project-git.sh +55 -0
  775. package/bin/public-guard.sh +70 -0
  776. package/bin/ratatoskr.sh +49 -0
  777. package/bin/realm-lib.sh +32 -0
  778. package/bin/repo-scrub.sh +62 -0
  779. package/bin/rodd-operational-input.sh +250 -0
  780. package/bin/runes-append.sh +198 -0
  781. package/bin/saga-session-start.sh +172 -0
  782. package/bin/saga-sessionstart-run.sh +79 -0
  783. package/bin/saga-wake-drain.sh +41 -0
  784. package/bin/secret-guard.sh +63 -0
  785. package/bin/sessrumnir-ensure.sh +100 -0
  786. package/bin/sessrumnir-sync.sh +237 -0
  787. package/bin/sessrumnir.sh +91 -0
  788. package/bin/skillopt-setup.sh +76 -0
  789. package/bin/skuld-branch-outcome.sh +203 -0
  790. package/bin/skuld-branch-prompt.sh +101 -0
  791. package/bin/smidja-bootstrap.sh +90 -0
  792. package/bin/smidja-observe.sh +86 -0
  793. package/bin/syn-arm-pretool-check.sh +57 -0
  794. package/bin/syn-asset-pretool-check.sh +76 -0
  795. package/bin/syn-cd-pretool-check.sh +28 -0
  796. package/bin/syn-guard-pretool-check.sh +83 -0
  797. package/bin/syn-turnend-guard.sh +36 -0
  798. package/bin/syn-watch-arm.sh +99 -0
  799. package/bin/tailscale-sync.sh +190 -0
  800. package/bin/telegram-bot.sh +69 -0
  801. package/bin/toolchain.sh +74 -0
  802. package/bin/utgard.sh +111 -0
  803. package/bin/valhalla.sh +115 -0
  804. package/bin/valknut-load.sh +260 -0
  805. package/bin/vor-crew-state.sh +124 -0
  806. package/bin/wedge-notify.sh +47 -0
  807. package/bin/workspace-provision.sh +80 -0
  808. package/bin/workspace-rag.sh +150 -0
  809. package/bin/wyrd-db.sh +47 -0
  810. package/bin/yggdrasil.sh +152 -0
  811. package/bin/ymir-edit.sh +145 -0
  812. package/bin/ymir-install.sh +641 -0
  813. package/bin/ymir-invite.sh +93 -0
  814. package/bin/ymir-isolation.sh +88 -0
  815. package/bin/ymir-migrate.sh +61 -0
  816. package/bin/ymir-platform.sh +348 -0
  817. package/bin/ymir-say.sh +97 -0
  818. package/bin/ymir-setup-auth.sh +108 -0
  819. package/bin/ymir-validate.sh +173 -0
  820. package/bin/ymir.js +74 -16
  821. package/docs/Architecture.md +339 -0
  822. package/docs/design.md +351 -0
  823. package/docs/installations/README.md +63 -0
  824. package/docs/installations/ymir-home.md +93 -0
  825. package/docs/integration.md +105 -0
  826. package/docs/lore.md +1056 -0
  827. package/docs/research/agent-harnesses.md +290 -0
  828. package/docs/runbooks/README.md +19 -0
  829. package/docs/runbooks/a2a.md +91 -0
  830. package/docs/runbooks/agent-permissions.md +99 -0
  831. package/docs/runbooks/agents.md +57 -0
  832. package/docs/runbooks/models.md +69 -0
  833. package/docs/runbooks/realm-onboarding.md +60 -0
  834. package/docs/runbooks/secrets-and-hoard.md +60 -0
  835. package/docs/runbooks/updates-and-migrations.md +110 -0
  836. package/docs/runbooks/worktrees-isolation.md +72 -0
  837. package/docs/session-start.md +105 -0
  838. package/docs/skillopt-integration.md +321 -0
  839. package/docs/sync-system.md +66 -0
  840. package/docs/workspaces.md +104 -0
  841. package/docs/ymir-rut.md +260 -0
  842. package/package.json +44 -14
  843. package/packaging/build.sh +74 -0
  844. package/packaging/macos/Ymir Installer.command +43 -0
  845. package/packaging/windows/ymir-setup.nsi +74 -0
  846. package/scripts/README.md +22 -0
  847. package/scripts/electron.sh +210 -0
  848. package/scripts/start.sh +167 -0
  849. package/scripts/stop.sh +113 -0
  850. package/install.sh +0 -35
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env bash
2
+ # gjallarhorn-notify.sh — the horn (W0036). Unified push: Telegram + a web/WS
3
+ # sink, and a Runes line for every send. Secrets from `.env.local`; no prompts.
4
+ # Galdr-style TOON.
5
+ #
6
+ # Usage:
7
+ # gjallarhorn-notify.sh <text> [--channel telegram|web|all] [--dry-run]
8
+ # gjallarhorn-notify.sh --version
9
+ #
10
+ # Env: TELEGRAM_BOT_TOKEN, TELEGRAM_OWNER_ID (chat id)
11
+ set -u
12
+
13
+ VERSION="1.0.0"
14
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
15
+ ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
16
+ ENV_FILE="${BROKK_ENV_FILE:-$ROOT/.env.local}"
17
+
18
+ usage() { sed -n '2,11p' "$0" | sed 's/^# \{0,1\}//'; }
19
+
20
+ if [ "${1-}" = "-v" ] || [ "${1-}" = "--version" ] || [ "${1-}" = "-V" ]; then printf '%s\n' "$VERSION"; exit 0; fi
21
+ if [ "${1-}" = "-h" ] || [ "${1-}" = "--help" ] || [ -z "${1-}" ]; then usage; exit 0; fi
22
+
23
+ TEXT="$1"; shift || true
24
+ CHANNEL=telegram; DRY=0
25
+ while [ $# -gt 0 ]; do case "$1" in --channel) CHANNEL=${2-telegram}; shift 2 ;; --dry-run) DRY=1; shift ;; *) shift ;; esac; done
26
+
27
+ [ -n "$TEXT" ] || { printf 'error: notify needs text\nhelp: bin/gjallarhorn-notify.sh "<text>"\n' >&2; exit 2; }
28
+ [ -r "$ENV_FILE" ] || { printf 'error: env file not found: %s\n' "$ENV_FILE" >&2; exit 1; }
29
+ # shellcheck disable=SC1090
30
+ TOKEN=$(grep -E '^TELEGRAM_BOT_TOKEN=' "$ENV_FILE" 2>/dev/null | head -1 | cut -d= -f2-)
31
+ CHAT=$(grep -E '^TELEGRAM_OWNER_ID=' "$ENV_FILE" 2>/dev/null | head -1 | cut -d= -f2-)
32
+
33
+ send() {
34
+ local text=$1
35
+ if [ "$DRY" = 1 ]; then printf 'notify[1]{channel,target,status}:\n "telegram","%s","dry-run"\n' "${CHAT:-unset}"; return 0; fi
36
+ [ -n "$TOKEN" ] && [ -n "$CHAT" ] || { printf 'error: TELEGRAM_BOT_TOKEN / TELEGRAM_OWNER_ID unset in .env.local\n' >&2; return 1; }
37
+ # The bot token rides in the URL path; a stdin config keeps it out of argv.
38
+ resp=$(curl -fsS --max-time 10 --config - \
39
+ -d "chat_id=${CHAT}" --data-urlencode "text=${text}" 2>/dev/null <<EOF
40
+ url = "https://api.telegram.org/bot${TOKEN}/sendMessage"
41
+ EOF
42
+ ) || { printf 'error: telegram send failed\n' >&2; return 1; }
43
+ printf '%s' "$resp" | python3 -c 'import json,sys
44
+ try: d=json.load(sys.stdin); ok=d.get("ok",False)
45
+ except: ok=False
46
+ print(f"notify[1]{{channel,target,status}}:\n \"telegram\",\"'"${CHAT}"'\",\"{ \"sent\" if ok else \"failed\" }\"")'
47
+ }
48
+
49
+ case "$CHANNEL" in
50
+ telegram|all) send "$TEXT" ;;
51
+ web) printf 'notify[1]{channel,target,status}:\n "web","stream","queued"\n' ;;
52
+ *) printf 'error: unknown channel %s\nhelp: use telegram|web|all\n' "$CHANNEL" >&2; exit 2 ;;
53
+ esac
54
+
55
+ # Carve a Rune (best-effort; the ledger is the record).
56
+ if [ -x "$SCRIPT_DIR/runes-append.sh" ]; then
57
+ "$SCRIPT_DIR/runes-append.sh" brokk notify.reply --message "${TEXT:0:200}" >/dev/null 2>&1 || true
58
+ fi
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env bash
2
+ # gjallarhorn-purge.sh — purge the Cloudflare edge cache for a hostname.
3
+ # Needs CLOUDFLARE_API_TOKEN (Zone → Cache Purge) in .env.local; the zone id is
4
+ # found automatically (or set CLOUDFLARE_ZONE_ID). Galdr-style TOON.
5
+ #
6
+ # Usage:
7
+ # gjallarhorn-purge.sh [hostname] [--everything]
8
+ # gjallarhorn-purge.sh --version
9
+ set -u
10
+
11
+ VERSION="1.0.0"
12
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
13
+ ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
14
+ ENV_FILE="${BROKK_ENV_FILE:-$ROOT/.env.local}"
15
+ DOMAIN="${YMIR_DOMAIN:-${YMIR_TUNNEL_HOST:-}}"
16
+ [ -n "$DOMAIN" ] || { printf 'gjallarhorn-purge: set YMIR_DOMAIN (or YMIR_TUNNEL_HOST)\n' >&2; exit 2; }
17
+ ZONE_NAME="${CLOUDFLARE_ZONE_NAME:-}"
18
+
19
+ case "${1-}" in -v|-V|--version) printf '%s\n' "$VERSION"; exit 0 ;; -h|--help) sed -n '2,8p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;; esac
20
+ HOST="${1:-$DOMAIN}"; [ "$HOST" = "--everything" ] && HOST=""
21
+ EVERYTHING=0; [ "${1-}" = "--everything" ] && EVERYTHING=1
22
+
23
+ # Load CLOUDFLARE_API_TOKEN from .env.local (never printed).
24
+ if [ -r "$ENV_FILE" ]; then set -a; . "$ENV_FILE"; set +a; fi
25
+ TOKEN="${CLOUDFLARE_API_TOKEN:-}"
26
+ if [ -z "$TOKEN" ]; then
27
+ printf 'gjallarhorn[1]{purge,status}:\n "cache","NO TOKEN"\n'
28
+ printf 'help: add CLOUDFLARE_API_TOKEN (Zone.Cache Purge) to %s\n' "${ENV_FILE#"$ROOT"/}" >&2
29
+ printf 'note: the cloudflared cert.pem (Argo token) cannot purge; wrangler OAuth lacks the scope\n' >&2
30
+ exit 1
31
+ fi
32
+
33
+ # The bearer token is fed to curl as a header read from stdin (`-H @-`), so it is
34
+ # never an argv element visible in `ps`/`/proc/*/cmdline`.
35
+ api() { printf 'Authorization: Bearer %s\n' "$TOKEN" | curl -fsS -H @- -H 'content-type: application/json' "$@"; }
36
+
37
+ ZONE="${CLOUDFLARE_ZONE_ID:-}"
38
+ if [ -z "$ZONE" ]; then
39
+ ZONE="$(api "https://api.cloudflare.com/client/v4/zones?name=$ZONE_NAME" | python3 -c 'import sys,json; d=json.load(sys.stdin); r=d.get("result") or []; print(r[0]["id"] if r else "")' 2>/dev/null)"
40
+ fi
41
+ [ -n "$ZONE" ] || { printf 'gjallarhorn[1]{purge,status}:\n "zone","NOT FOUND (%s)"\n' "$ZONE_NAME" >&2; exit 1; }
42
+
43
+ if [ "$EVERYTHING" = 1 ]; then
44
+ payload='{"purge_everything":true}'
45
+ what="everything"
46
+ else
47
+ payload="{\"hosts\":[\"$HOST\"]}"
48
+ what="$HOST"
49
+ fi
50
+
51
+ resp="$(api -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE/purge_cache" -d "$payload" || true)"
52
+ ok="$(printf '%s' "$resp" | python3 -c 'import sys,json; print(json.load(sys.stdin).get("success",False))' 2>/dev/null || echo False)"
53
+ printf 'gjallarhorn[1]{purge,status,zone}:\n "%s","%s","%s"\n' "$what" "$([ "$ok" = True ] && echo purged || echo failed)" "${ZONE:0:8}…"
54
+ [ "$ok" = True ] || printf '%s\n' "$resp" >&2
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env bash
2
+ # gjallarhorn-tunnel.sh — raise/lower the `ymir` Cloudflare tunnel (Gjallarhorn).
3
+ # Exposes Hlidskjalf from this machine at the operator's own hostname
4
+ # (YMIR_TUNNEL_HOST, or read from the cloudflared config).
5
+ #
6
+ # Usage:
7
+ # gjallarhorn-tunnel.sh [start|stop|status] [--config <path>] [--tunnel <name>]
8
+ # gjallarhorn-tunnel.sh --version
9
+ set -u
10
+
11
+ # --- portability shim: bin/ymir-platform.sh --------------------------------
12
+ if [ -z "${YMIR_PLATFORM_LOADED:-}" ]; then
13
+ for _ymir_c in "$(git rev-parse --show-toplevel 2>/dev/null)/bin/ymir-platform.sh" "$(cd "$(dirname "${BASH_SOURCE[0]}")/.." 2>/dev/null && pwd)/bin/ymir-platform.sh"; do
14
+ [ -n "$_ymir_c" ] && [ -r "$_ymir_c" ] && { . "$_ymir_c"; YMIR_PLATFORM_LOADED=1; break; }
15
+ done
16
+ unset _ymir_c
17
+ fi
18
+
19
+ VERSION="1.0.0"
20
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
21
+ ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
22
+ CONFIG="${YMIR_TUNNEL_CONFIG:-$HOME/.cloudflared/config-ymir.yml}"
23
+ TUNNEL="${YMIR_TUNNEL_NAME:-ymir}"
24
+ PID_FILE="$ROOT/state/gjallarhorn.pid"
25
+ LOG_FILE="$ROOT/state/gjallarhorn.log"
26
+
27
+ case "${1-}" in -v|-V|--version) printf '%s\n' "$VERSION"; exit 0 ;; -h|--help|"") sed -n '2,10p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;; esac
28
+ ACTION="${1:-status}"; shift || true
29
+ while [ $# -gt 0 ]; do case "$1" in --config) CONFIG=${2-}; shift 2 ;; --tunnel) TUNNEL=${2-}; shift 2 ;; *) shift ;; esac; done
30
+
31
+ running() { [ -r "$PID_FILE" ] && kill -0 "$(tr -d '[:space:]' <"$PID_FILE")" 2>/dev/null; }
32
+
33
+ # The public hostname is a fact about THIS machine, not about Ymir: take it from
34
+ # the environment, or read it out of the tunnel's own config. Never a fixed
35
+ # domain — the previous default handed every other operator this one's host.
36
+ tunnel_host() {
37
+ if [ -n "${YMIR_TUNNEL_HOST:-}" ]; then printf '%s' "$YMIR_TUNNEL_HOST"; return; fi
38
+ if [ -r "$CONFIG" ]; then
39
+ grep -oE '^[[:space:]]*-[[:space:]]*hostname:[[:space:]]*[^[:space:]]+' "$CONFIG" 2>/dev/null \
40
+ | head -1 | awk '{print $NF}'
41
+ fi
42
+ }
43
+ HOST="$(tunnel_host)"
44
+ [ -n "$HOST" ] || HOST='<unset: set YMIR_TUNNEL_HOST>'
45
+
46
+ case "$ACTION" in
47
+ status)
48
+ state=down
49
+ if running; then state=up; fi
50
+ printf 'gjallarhorn[1]{state,host,pid,config}:\n "%s","%s",%s,"%s"\n' "$state" "$HOST" "$(running && tr -d '[:space:]' <"$PID_FILE" || echo 0)" "${CONFIG#"$HOME"/}"
51
+ command -v cloudflared >/dev/null 2>&1 && cloudflared tunnel info "$TUNNEL" 2>/dev/null | rg -m1 "CONNECTOR|does not have" || true
52
+ exit 0 ;;
53
+ stop)
54
+ if running; then pid=$(tr -d '[:space:]' <"$PID_FILE"); kill "$pid" 2>/dev/null || true; rm -f "$PID_FILE"; printf 'gjallarhorn: stopped pid=%s\n' "$pid"; else ymir_kill_matching "config-ymir.yml" 2>/dev/null && printf 'gjallarhorn: stopped (matched process)\n' || printf 'gjallarhorn: already stopped\n'; fi
55
+ exit 0 ;;
56
+ start) ;;
57
+ *) printf 'error: unknown action %s\nhelp: gjallarhorn-tunnel.sh [start|stop|status]\n' "$ACTION" >&2; exit 2 ;;
58
+ esac
59
+
60
+ command -v cloudflared >/dev/null 2>&1 || { printf 'error: cloudflared not found\nhelp: install cloudflared\n' >&2; exit 1; }
61
+ [ -r "$CONFIG" ] || { printf 'error: tunnel config not found: %s\nhelp: cp midgard/infrastructure/ingress/cloudflared-ymir.yml ~/.cloudflared/config-ymir.yml\n' "$CONFIG" >&2; exit 1; }
62
+ mkdir -p "$ROOT/state"
63
+ if running; then printf 'gjallarhorn[1]{state,host}:\n "already up","%s"\n' "$HOST"; exit 0; fi
64
+
65
+ nohup cloudflared tunnel --config "$CONFIG" run "$TUNNEL" >"$LOG_FILE" 2>&1 &
66
+ echo $! >"$PID_FILE"
67
+ sleep 4
68
+ if running; then
69
+ printf 'gjallarhorn[1]{state,host,pid}:\n "up","%s",%s\n' "$HOST" "$(cat "$PID_FILE")"
70
+ # Bust the edge cache for the hostname (no-op without CLOUDFLARE_API_TOKEN).
71
+ [ -x "$SCRIPT_DIR/gjallarhorn-purge.sh" ] && "$SCRIPT_DIR/gjallarhorn-purge.sh" "$HOST" >/dev/null 2>&1 || true
72
+ else printf 'error: tunnel failed to start; see %s\n' "${LOG_FILE#"$ROOT"/}" >&2; tail -3 "$LOG_FILE" >&2; exit 1; fi
@@ -0,0 +1,284 @@
1
+ #!/usr/bin/env bash
2
+ # gleipnir-lock-lib.sh - session lock for the Brokk runtime.
3
+ #
4
+ # Gleipnir is the impossible chain that bound Fenrir: here it binds ONE live
5
+ # Brokk primary per MACHINE. The primary's lock lives at a machine-global path
6
+ # (`${XDG_STATE_HOME:-$HOME/.local/state}/ymir/brokk.lock`), not inside the
7
+ # checkout, so a stray second checkout of the same machine cannot masquerade as
8
+ # its own home and run a competing session. Eindri-homes are worker homes and
9
+ # are EXEMPT: each keeps its own `<home>/state/.lock` so workers still run in
10
+ # parallel with the primary (and with each other).
11
+ #
12
+ # Non-bash readers (the `.pi` / `.opencode` harness extensions) read the
13
+ # resolved path from `state/.lock-path`, which `gleipnir_lock_acquire` writes,
14
+ # and fall back to the legacy `state/.lock` for a session that started before
15
+ # this contract. Source-safe.
16
+ set -u
17
+
18
+ gleipnir_root() { # <result-var>
19
+ local result_var=${1-}
20
+ local root="${BROKK_ROOT_OVERRIDE:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
21
+ printf -v "$result_var" '%s' "$root"
22
+ }
23
+
24
+ # An Eindri-home is a worker home; it keeps a per-home lock so it can run beside
25
+ # the primary. Identified by an explicit marker the seed writes, or by the
26
+ # launcher's `BROKK_HOME_KIND=eindri` environment marker.
27
+ gleipnir_is_eindri_home() {
28
+ [ "${BROKK_HOME_KIND:-}" = "eindri" ] && return 0
29
+ local home="${BROKK_HOME:-${BROKK_ROOT_OVERRIDE:-}}"
30
+ [ -n "$home" ] || gleipnir_root home
31
+ [ -f "$home/data/eindri-home" ] && return 0
32
+ return 1
33
+ }
34
+
35
+ gleipnir_state_dir() { # <result-var>
36
+ local result_var=${1-}
37
+ local home="${BROKK_HOME:-${BROKK_ROOT_OVERRIDE:-}}"
38
+ [ -n "$home" ] || gleipnir_root home
39
+ printf -v "$result_var" '%s' "${BROKK_STATE_OVERRIDE:-$home/state}"
40
+ }
41
+
42
+ # /proc/<pid>/stat fields after the closing paren of the comm field: state,
43
+ # then the remaining fields so field N (1-indexed) sits at index N-3.
44
+ gleipnir_proc_stat_rest() { # <pid> <result-var> (empty when /proc unavailable)
45
+ local result_var=${2-} __gleipnir_rest
46
+ [ -r "/proc/$1/stat" ] || { printf -v "$result_var" ''; return 1; }
47
+ __gleipnir_rest=$(tr ')' '\n' <"/proc/$1/stat" | tail -n 1)
48
+ printf -v "$result_var" '%s' "$__gleipnir_rest"
49
+ }
50
+
51
+ # Starttime (field 22) is clock ticks since boot, stable for a pid's whole
52
+ # life: a mismatch with the starttime recorded at acquire means the original
53
+ # lock owner is gone and the kernel has recycled the pid to another process.
54
+ gleipnir_proc_starttime() { # <pid> <result-var> (empty when unavailable)
55
+ local result_var=${2-} _rest
56
+ gleipnir_proc_stat_rest "$1" _rest
57
+ if [ -n "$_rest" ]; then
58
+ local __gleipnir_fields=()
59
+ read -r -a __gleipnir_fields <<<"$_rest" || true
60
+ if [ "${#__gleipnir_fields[@]}" -ge 20 ]; then
61
+ printf -v "$result_var" '%s' "${__gleipnir_fields[19]}"
62
+ return 0
63
+ fi
64
+ fi
65
+ printf -v "$result_var" ''
66
+ return 1
67
+ }
68
+
69
+ # A pid is alive to Gleipnir only when the process genuinely exists. kill -0
70
+ # alone is blind: it also "succeeds" for a zombie (dead but unreaped) and for a
71
+ # pid the kernel has since recycled. /proc/<pid>/stat resolves both — the state
72
+ # character (Z/X = zombie/dead) and the starttime (see gleipnir_proc_starttime).
73
+ gleipnir_pid_alive() { # <pid> [<recorded-starttime>]
74
+ local pid=${1-} expect=${2-} rest state current
75
+ case "$pid" in
76
+ ''|*[!0-9]*) return 1 ;;
77
+ esac
78
+ gleipnir_proc_stat_rest "$pid" rest
79
+ if [ -n "$rest" ]; then
80
+ state=$(printf '%s' "$rest" | awk '{print substr($1,1,1)}')
81
+ case "$state" in
82
+ Z|X) return 1 ;;
83
+ esac
84
+ if [ -n "$expect" ]; then
85
+ gleipnir_proc_starttime "$pid" current
86
+ [ -n "$current" ] && [ "$current" != "$expect" ] && return 1
87
+ fi
88
+ fi
89
+ kill -0 "$pid" 2>/dev/null
90
+ }
91
+
92
+ # The session pid to record. The lock must bind to the LIVE HARNESS process, not
93
+ # the short-lived helper that happens to run the digest — a helper's pid is dead
94
+ # a second later, which leaves an orphan lock that blocks supervision. When the
95
+ # harness passes BROKK_SESSION_PID we use it; otherwise we walk the ancestry to
96
+ # find the harness itself (pi / opencode / claude / cursor / codex / ...). Only a
97
+ # run with no harness ancestor (a real cron/headless job) falls back to $$.
98
+ gleipnir_session_pid() { # <result-var>
99
+ local result_var=${1-}
100
+ if [ -n "${BROKK_SESSION_PID:-}" ]; then
101
+ printf -v "$result_var" '%s' "$BROKK_SESSION_PID"
102
+ return 0
103
+ fi
104
+ local pid=$$ comm parent i
105
+ for i in 1 2 3 4 5 6 7 8; do
106
+ parent=$(ps -o ppid= -p "$pid" 2>/dev/null | tr -d '[:space:]')
107
+ [ -n "$parent" ] && [ "$parent" != "1" ] || break
108
+ comm=$(ps -o comm= -p "$parent" 2>/dev/null | tr -d '[:space:]')
109
+ case "$comm" in
110
+ pi|opencode|claude|cursor|codex|grok|kimi|muse|hermes)
111
+ if gleipnir_pid_alive "$parent"; then
112
+ printf -v "$result_var" '%s' "$parent"
113
+ return 0
114
+ fi
115
+ ;;
116
+ esac
117
+ pid=$parent
118
+ done
119
+ printf -v "$result_var" '%s' "$$"
120
+ }
121
+
122
+ # The machine-global state dir for the primary lock. Overridable for tests and
123
+ # for a host that keeps machine state elsewhere.
124
+ gleipnir_machine_state_dir() { # <result-var>
125
+ local result_var=${1-}
126
+ printf -v "$result_var" '%s' "${BROKK_MACHINE_STATE_DIR:-${XDG_STATE_HOME:-$HOME/.local/state}/ymir}"
127
+ }
128
+
129
+ # The pre-machine-lock per-home path. Kept so a session that started before this
130
+ # contract still resolves its own lock, and so the pointer can be migrated.
131
+ gleipnir_legacy_lock_path() { # <result-var>
132
+ local result_var=${1-} state
133
+ gleipnir_state_dir state
134
+ printf -v "$result_var" '%s/.lock' "$state"
135
+ }
136
+
137
+ # The resolved lock path: machine-global for the primary, per-home for an
138
+ # Eindri-home.
139
+ gleipnir_lock_path() { # <result-var>
140
+ local result_var=${1-} dir
141
+ if gleipnir_is_eindri_home; then
142
+ gleipnir_legacy_lock_path "$result_var"
143
+ return 0
144
+ fi
145
+ gleipnir_machine_state_dir dir
146
+ printf -v "$result_var" '%s/brokk.lock' "$dir"
147
+ }
148
+
149
+ # Pointer file the non-bash harness readers consult so they never re-derive the
150
+ # machine/Eindri branch; it records whatever `gleipnir_lock_path` resolved.
151
+ gleipnir_lock_pointer_path() { # <result-var>
152
+ local result_var=${1-} state
153
+ gleipnir_state_dir state
154
+ printf -v "$result_var" '%s/.lock-path' "$state"
155
+ }
156
+
157
+ gleipnir_lock_owner() { # <result-var>
158
+ local result_var=${1-} lock legacy val
159
+ gleipnir_lock_path lock
160
+ val=""
161
+ if [ -r "$lock" ]; then
162
+ val=$(tr -d '[:space:]' <"$lock")
163
+ fi
164
+ if [ -z "$val" ]; then
165
+ # Migration read: a session that started before the machine lock lived at
166
+ # the legacy home path; honor it until that session restarts.
167
+ gleipnir_legacy_lock_path legacy
168
+ if [ "$legacy" != "$lock" ] && [ -r "$legacy" ]; then
169
+ val=$(tr -d '[:space:]' <"$legacy")
170
+ fi
171
+ fi
172
+ printf -v "$result_var" '%s' "$val"
173
+ }
174
+
175
+ gleipnir_lock_owned() { # exit 0 when this shell's session owns the lock
176
+ local owner
177
+ gleipnir_lock_owner owner
178
+ [ -n "$owner" ] && [ "$owner" = "$$" ] && return 0
179
+ # Walk up the ancestry; the lock is held by a session process, not this
180
+ # short-lived helper.
181
+ local pid=$$ parent i
182
+ for i in 1 2 3 4 5 6 7 8; do
183
+ parent=$(ps -o ppid= -p "$pid" 2>/dev/null | tr -d '[:space:]')
184
+ [ -n "$parent" ] && [ "$parent" != "1" ] || return 1
185
+ [ "$parent" = "$owner" ] && return 0
186
+ pid=$parent
187
+ done
188
+ return 1
189
+ }
190
+
191
+ gleipnir_write_lock_pointer() { # <resolved-lock-path>
192
+ local ptr
193
+ gleipnir_lock_pointer_path ptr
194
+ mkdir -p "$(dirname "$ptr")" 2>/dev/null || true
195
+ printf '%s\n' "$1" >"$ptr" 2>/dev/null || true
196
+ }
197
+
198
+ # Drop the legacy home lock once the resolved lock holds the same session, so a
199
+ # stale per-home file cannot make the old path look live during hand-off.
200
+ gleipnir_lock_drop_legacy() { # <want-pid>
201
+ local legacy lock owner
202
+ gleipnir_legacy_lock_path legacy
203
+ gleipnir_lock_path lock
204
+ [ "$legacy" = "$lock" ] && return 0
205
+ [ -r "$legacy" ] || return 0
206
+ owner=$(tr -d '[:space:]' <"$legacy")
207
+ [ "$owner" = "$1" ] && rm -f "$legacy"
208
+ return 0
209
+ }
210
+
211
+ gleipnir_lock_acquire() {
212
+ local state lock owner want dir expect starttime
213
+ GLEIPNIR_LOCK_ACQUIRED=0
214
+ gleipnir_state_dir state
215
+ mkdir -p "$state"
216
+ gleipnir_lock_path lock
217
+ gleipnir_lock_reap # a dead owner's lock is not a lock — clear it first
218
+ gleipnir_session_pid want
219
+ gleipnir_lock_owner owner
220
+ expect=""
221
+ if [ -n "$owner" ] && [ -r "$lock.starttime" ]; then
222
+ expect=$(tr -d '[:space:]' <"$lock.starttime")
223
+ fi
224
+ if [ -n "$owner" ] && [ "$owner" != "$want" ] && gleipnir_pid_alive "$owner" "$expect"; then
225
+ return 1
226
+ fi
227
+ dir=$(dirname "$lock")
228
+ mkdir -p "$dir" || return 1
229
+ printf '%s\n' "$want" >"$lock" || return 1
230
+ # Record the owner's starttime beside the lock so a later pid reuse is
231
+ # visible as death instead of a live (but unrelated) holder.
232
+ gleipnir_proc_starttime "$want" starttime
233
+ if [ -n "$starttime" ]; then
234
+ printf '%s\n' "$starttime" >"$lock.starttime"
235
+ else
236
+ rm -f "$lock.starttime"
237
+ fi
238
+ gleipnir_write_lock_pointer "$lock"
239
+ gleipnir_lock_drop_legacy "$want"
240
+ GLEIPNIR_LOCK_ACQUIRED=1
241
+ return 0
242
+ }
243
+
244
+ # A lock whose owner is dead is NOT a lock. Remove it so an abnormal session
245
+ # close (crash, kill, closing the terminal) can never leave a stale lock —
246
+ # resolved or legacy — holding supervision and lighting the blind turn-end guard.
247
+ gleipnir_lock_reap() {
248
+ local lock legacy owner p expect
249
+ gleipnir_lock_path lock
250
+ gleipnir_legacy_lock_path legacy
251
+ for p in "$lock" "$legacy"; do
252
+ [ -n "$p" ] && [ -e "$p" ] || continue
253
+ owner=$(tr -d '[:space:]' <"$p" 2>/dev/null || true)
254
+ [ -n "$owner" ] || continue
255
+ expect=""
256
+ [ -r "$p.starttime" ] && expect=$(tr -d '[:space:]' <"$p.starttime" 2>/dev/null || true)
257
+ # A lock whose owner is verifiably gone — dead, a zombie (killed but not
258
+ # yet reaped), or a pid the kernel reused — is NOT a lock. Gleipnir only
259
+ # refuses a holder that is genuinely alive.
260
+ if ! gleipnir_pid_alive "$owner" "$expect"; then
261
+ rm -f "$p" "$p.starttime"
262
+ printf 'gleipnir: reaped stale lock (dead pid %s)\n' "$owner" >&2
263
+ fi
264
+ done
265
+ return 0
266
+ }
267
+
268
+ gleipnir_lock_release() {
269
+ local lock legacy ptr owner want
270
+ gleipnir_lock_path lock
271
+ gleipnir_legacy_lock_path legacy
272
+ gleipnir_session_pid want
273
+ gleipnir_lock_owner owner
274
+ if [ "$owner" = "$want" ]; then
275
+ rm -f "$lock" "$lock.starttime"
276
+ [ "$legacy" != "$lock" ] && rm -f "$legacy" "$legacy.starttime"
277
+ gleipnir_lock_pointer_path ptr
278
+ rm -f "$ptr"
279
+ GLEIPNIR_LOCK_ACQUIRED=0
280
+ fi
281
+ }
282
+
283
+ # shellcheck disable=SC2034 # Public source-library variable used by callers.
284
+ GLEIPNIR_LOCK_ACQUIRED=0
@@ -0,0 +1,122 @@
1
+ #!/usr/bin/env bash
2
+ # groa-update.sh — Gróa, the völva who renews.
3
+ #
4
+ # Gróa is the updater shaman: she fast-forwards Brokk and every registered
5
+ # Eindri-home to the latest, then mends the tree forward (migrations, fleet
6
+ # preferences). Brokk runs her; Galdr owns the assets she must be reflected in
7
+ # when the instruction surface moves; the `groa-update` skill is her door.
8
+ #
9
+ # Fast-forward only. Never forces, never stashes, never creates a merge commit.
10
+ # Anything dirty, diverged, offline, or on a non-default branch is skipped and
11
+ # reported. Touches only Brokk repos and their worktrees — never projects/.
12
+ #
13
+ # Usage:
14
+ # groa-update.sh [--check] [--remote <name>] [--branch <name>]
15
+ # groa-update.sh --version
16
+ #
17
+ # The `groa-update` skill invokes her; `bin/brokk-update.sh` is a back-compat
18
+ # alias. Prints one row per target, then the action lines:
19
+ # reread-Brokk: yes|no
20
+ # galdr-reread: yes|no (Galdr must refresh the owning assets)
21
+ # nudge-eindri-homes: <id> ...|none
22
+ set -u
23
+
24
+ VERSION="2.0.0"
25
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
26
+ ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
27
+ YMIR_HOME="${YMIR_HOME:-$HOME/Documents/Ymir}"
28
+ REG="${BROKK_EINDRI_HOMES:-$YMIR_HOME/data/eindri-homes.md}"
29
+ REMOTE=""; BRANCH=""; CHECK=0
30
+
31
+ case "${1-}" in -v|-V|--version) printf '%s\n' "$VERSION"; exit 0 ;; -h|--help) sed -n '2,21p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;; esac
32
+ while [ $# -gt 0 ]; do
33
+ case "$1" in
34
+ --check) CHECK=1; shift ;;
35
+ --remote) REMOTE=${2-}; shift 2 ;;
36
+ --branch) BRANCH=${2-}; shift 2 ;;
37
+ *) printf 'error: unknown flag %s\nhelp: bin/groa-update.sh [--check|--remote|--branch]\n' "$1" >&2; exit 2 ;;
38
+ esac
39
+ done
40
+
41
+ # Resolve remote/branch from the master registry when the resolver is present.
42
+ if [ -x "$SCRIPT_DIR/project-git.sh" ] && "$SCRIPT_DIR/project-git.sh" list 2>/dev/null | grep -q 'ymir-platform'; then
43
+ [ -n "$REMOTE" ] || REMOTE="$("$SCRIPT_DIR/project-git.sh" ymir-platform --field remote 2>/dev/null)"
44
+ [ -n "$BRANCH" ] || BRANCH="$("$SCRIPT_DIR/project-git.sh" ymir-platform --field default_branch 2>/dev/null)"
45
+ fi
46
+ REMOTE="${REMOTE:-origin}"
47
+ BRANCH="${BRANCH:-main}"
48
+
49
+ declare -a ROWS; NUDGE_IDS=""
50
+ reread=no
51
+ changed_surface=0
52
+
53
+ # Guarded fast-forward of one Brokk home. Sets FF_STATE/FF_DETAIL.
54
+ ff_home() { # <path> <label>
55
+ local p="$1" label="$2"
56
+ if [ ! -d "$p" ]; then FF_STATE="skipped"; FF_DETAIL="not found: $p"; return; fi
57
+ if ! git -C "$p" rev-parse --is-inside-work-tree >/dev/null 2>&1; then FF_STATE="skipped"; FF_DETAIL="not a git repo"; return; fi
58
+ local cur; cur="$(git -C "$p" branch --show-current 2>/dev/null || echo '')"
59
+ if [ -n "$cur" ] && [ "$cur" != "$BRANCH" ]; then FF_STATE="skipped"; FF_DETAIL="on branch $cur"; return; fi
60
+ local dirty; dirty="$(git -C "$p" status --porcelain | wc -l | tr -d ' ')"
61
+ if [ "$dirty" != "0" ]; then FF_STATE="skipped"; FF_DETAIL="dirty ($dirty)"; return; fi
62
+ git -C "$p" fetch --quiet --prune "$REMOTE" 2>/dev/null || { FF_STATE="skipped"; FF_DETAIL="offline ($REMOTE)"; return; }
63
+ local local_h target
64
+ local_h="$(git -C "$p" rev-parse HEAD)"
65
+ target="$(git -C "$p" rev-parse "$REMOTE/$BRANCH" 2>/dev/null)" || { FF_STATE="skipped"; FF_DETAIL="$REMOTE/$BRANCH missing"; return; }
66
+ if [ "$local_h" = "$target" ]; then FF_STATE="current"; FF_DETAIL="${local_h:0:8}"; return; fi
67
+ if ! git -C "$p" merge-base --is-ancestor "$local_h" "$target"; then FF_STATE="skipped"; FF_DETAIL="diverged"; return; fi
68
+ if [ "$CHECK" = 1 ]; then FF_STATE="behind"; FF_DETAIL="$(git -C "$p" rev-list --count "$local_h..$target") behind"; return; fi
69
+ if git -C "$p" merge --ff-only -q "$target" 2>/dev/null; then
70
+ FF_STATE="updated"; FF_DETAIL="${local_h:0:8}..$(git -C "$p" rev-parse --short HEAD)"
71
+ if [ -n "$(git -C "$p" diff --name-only "$local_h" "$target" -- AGENTS.md bin .agents/skills 2>/dev/null)" ]; then
72
+ [ "$label" = "$ROOT" ] && changed_surface=1
73
+ fi
74
+ else FF_STATE="skipped"; FF_DETAIL="fast-forward failed"; fi
75
+ }
76
+
77
+ add_row() { ROWS+=("$1"); }
78
+
79
+ # 1. This home.
80
+ ff_home "$ROOT" "$ROOT"
81
+ add_row " \"$ROOT\",\"this Brokk home\",\"$FF_STATE\",\"$FF_DETAIL\""
82
+
83
+ # 2. Registered Eindri-homes.
84
+ if [ -f "$REG" ]; then
85
+ while IFS= read -r line; do
86
+ case "$line" in '- '*) ;; *) continue ;; esac
87
+ id="$(printf '%s' "$line" | sed -nE 's/^- ([^ ]+).*/\1/p')"
88
+ host="$(printf '%s' "$line" | sed -nE 's/.*\(host: ([^;)]+).*/\1/p' | tr -d ' ')"
89
+ home="$(printf '%s' "$line" | sed -nE 's/.*\(.*home: ([^;)]+).*/\1/p' | sed -E 's/ *(host:.*)?$//' | tr -d ' ')"
90
+ [ -n "$id" ] || continue
91
+ if [ -n "$host" ]; then
92
+ root="$(printf '%s' "$line" | sed -nE 's/.*root: ([^;)]+).*/\1/p' | tr -d ' ')"
93
+ add_row " \"$id\",\"remote $host:${root:-$home}\",\"skipped\",\"remote route — run bin/groa-update.sh on $host\""
94
+ continue
95
+ fi
96
+ [ -n "$home" ] || home="$id"
97
+ ff_home "$home" "$home"
98
+ add_row " \"$id\",\"$home\",\"$FF_STATE\",\"$FF_DETAIL\""
99
+ [ "$FF_STATE" = "updated" ] && NUDGE_IDS="$NUDGE_IDS $id"
100
+ done <"$REG"
101
+ else
102
+ add_row " \"-\",\"registry\",\"absent\",\"$REG (no Eindri-homes registered)\""
103
+ fi
104
+
105
+ # reread-Brokk: yes when this home's instruction surface advanced.
106
+ [ "$changed_surface" = 1 ] && reread=yes
107
+
108
+ printf 'groa[1]{state,root,remote,branch,mode}:\n "renew","%s","%s","%s","%s"\n' "$ROOT" "$REMOTE" "$BRANCH" "$([ "$CHECK" = 1 ] && echo check || echo apply)"
109
+ printf 'update[%d]{id,target,state,detail}:\n' "${#ROWS[@]}"
110
+ printf '%s\n' "${ROWS[@]}"
111
+ printf 'reread-Brokk: %s\n' "$reread"
112
+ # Galdr owns the assets; when the instruction surface moved she must be reflected
113
+ # in the same pass (the code/plan/asset agreement law).
114
+ printf 'galdr-reread: %s\n' "$reread"
115
+ if [ -n "${NUDGE_IDS# }" ]; then printf 'nudge-eindri-homes: %s\n' "${NUDGE_IDS# }"; else printf 'nudge-eindri-homes: none\n'; fi
116
+
117
+ # Keep the whole fleet on the fleet preferences (writes each home's gitignored
118
+ # state/; never touches a tracked tree).
119
+ [ -x "$SCRIPT_DIR/fleet-apply.sh" ] && "$SCRIPT_DIR/fleet-apply.sh" >/dev/null 2>&1 || true
120
+
121
+ # Heal this home forward (structure migrations) after every update.
122
+ [ -x "$SCRIPT_DIR/ymir-migrate.sh" ] && "$SCRIPT_DIR/ymir-migrate.sh" apply >/dev/null 2>&1 || true