@zerwiz/ymir 0.1.3 → 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 -39
  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,222 @@
1
+ #!/usr/bin/env bash
2
+ # brokk-lease-lib.sh - the per-task supervision lease contract (one owner).
3
+ #
4
+ # WHY. On the Pi supervision branch (docs/pi-supervision-branch.md), two LLM
5
+ # actors share one brokk home inside one pi process: MAIN (the Allfather's
6
+ # chat) and BRANCH (the persistent supervision conversation). Most records have
7
+ # exactly one natural owner, but the overlap set - steering or stopping a
8
+ # worker, post-landing cleanup, backlog status for a task, stuck-worker
9
+ # recovery - could otherwise be mutated by both actors at once. The lease is
10
+ # the merge-conflict analog: a small per-task file saying which actor is
11
+ # changing that task right now, and the mutating entrypoints refuse the other
12
+ # actor while it exists.
13
+ #
14
+ # CONTRACT.
15
+ # - Lease file: $STATE/.lease-<task>, one line "<actor>\t<pid>\t<epoch>".
16
+ # Written atomically (temp + ln for claim, temp + mv for a same-actor
17
+ # refresh), with inspection and mutation serialized by the home-local
18
+ # lease-command lock; leases never coordinate across brokk homes.
19
+ # - Actors: exactly "main" and "branch". The current actor is
20
+ # $BROKK_SUPERVISION_ACTOR when set, else "main". The branch's shell gets
21
+ # BROKK_SUPERVISION_ACTOR=branch injected deterministically by the Pi branch
22
+ # extension's bash tool, not by agent memory. Any other value is refused
23
+ # loudly - an unknown actor is a wiring bug, not a third role.
24
+ # - Staleness: the recorded pid is the long-lived supervising process (the
25
+ # session-lock holder, or BROKK_LEASE_HOLDER_PID - see bin/brokk-lease.sh), and
26
+ # both actors live inside that one pi process, so a dead recorded pid
27
+ # means the process died; the lease is cleared at the next claim, guard,
28
+ # or sweep. Liveness requires a Pi calling context plus state/.lock, and
29
+ # the recorded pid must BE its current holder, so a lease left by an exited
30
+ # Pi session goes stale even if its pid was recycled by an unrelated
31
+ # process, and a non-Pi home never honors a leftover Pi lease. A lease held by the
32
+ # live current session but an abandoned branch conversation is recovered
33
+ # by the branch extension's generation-activation cleanup.
34
+ #
35
+ # THREAT MODEL (deliberate, Allfather-decided): these guards are
36
+ # CONFUSED-AGENT-GRADE, the same grade bin/brokk-gate-refuse-lib.sh documents
37
+ # for the gate refusal. They stop non-deliberate misuse - the injected actor
38
+ # identity, the loud refusals, and the session-bound staleness make every
39
+ # accidental cross-actor mutation fail loudly. A deliberately forging shell
40
+ # running as the same uid inside the same pi process can evade any in-process
41
+ # discriminator (it can rewrite env, spawn fresh shells, and edit state
42
+ # files), so adversarial-grade separation is explicitly out of scope here and
43
+ # tracked as separate follow-up design work. The branch's shell prelude makes
44
+ # the actor variables readonly (see the Pi branch extension), so an
45
+ # ACCIDENTAL override fails loudly inside the branch's own shell as well.
46
+ # - Guard semantics (fm_lease_guard): no lease, a same-actor lease, or a
47
+ # provably stale lease passes; a live lease held by the OTHER actor
48
+ # refuses with exit BROKK_LEASE_REFUSE_EXIT. In a Pi supervision context the
49
+ # guard retains the lease-command lock until fm_lease_guard_release, so the
50
+ # other actor cannot claim between the check and the guarded mutation. A
51
+ # home without the current Pi session lock cannot have a live lease, so
52
+ # the guard is a no-op there - non-Pi behavior is unchanged by construction.
53
+ # - Role partition (fm_lease_forbid_branch): actions MAIN alone owns -
54
+ # merging a PR, landing local-only work, spawning workers - refuse the
55
+ # branch actor outright, lease or no lease.
56
+ # - "backlog" is a reserved claimable resource name used by the branch
57
+ # prompt around its own data/backlog.md writes. This is deliberately
58
+ # branch-side containment only; main's tasks-axi path has no executable
59
+ # backlog lease guard in this scope.
60
+ #
61
+ # Sourced by bin/brokk-send.sh, bin/brokk-control.sh, bin/brokk-teardown.sh,
62
+ # bin/brokk-pr-merge.sh, bin/brokk-merge-local.sh, bin/einherjar-spawn.sh, and
63
+ # bin/brokk-lease.sh. Callers must have $STATE resolved before calling. No side
64
+ # effects on source. set -u / set -e safe.
65
+
66
+ # Distinct from usage errors (2), the gate refusal (3), and brokk-send's
67
+ # unconfirmed submit (3): recognizable as "the other supervision actor holds
68
+ # this task right now - retry after the lease clears".
69
+ BROKK_LEASE_REFUSE_EXIT=6
70
+ BROKK_LEASE_LIB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
71
+ BROKK_LEASE_GUARD_LOCK=
72
+
73
+ fm_lease_lock_helpers() {
74
+ command -v fm_lock_acquire_wait >/dev/null 2>&1 && return 0
75
+ # brokk-wake-lib.sh is a canonical lint root in its own right and is already
76
+ # sourced directly by every caller of this lazy fallback; keep this an
77
+ # analysis boundary so ShellCheck's external-source traversal does not
78
+ # recursively duplicate that large graph for every lease-lib consumer.
79
+ # shellcheck source=/dev/null
80
+ . "$BROKK_LEASE_LIB_DIR/brokk-wake-lib.sh"
81
+ }
82
+
83
+ # fm_lease_actor: print the current actor after validating it. Returns 1 (with
84
+ # stderr) for an unknown BROKK_SUPERVISION_ACTOR value.
85
+ fm_lease_actor() {
86
+ local actor=${BROKK_SUPERVISION_ACTOR:-main}
87
+ case "$actor" in
88
+ main|branch) printf '%s\n' "$actor" ;;
89
+ *)
90
+ echo "error: unknown BROKK_SUPERVISION_ACTOR '$actor' (expected main or branch)" >&2
91
+ return 1
92
+ ;;
93
+ esac
94
+ }
95
+
96
+ # fm_lease_valid_id <id>: 0 iff the task/resource id is safe to embed in a
97
+ # state filename.
98
+ fm_lease_valid_id() {
99
+ case "${1:-}" in
100
+ '' | *[!A-Za-z0-9._-]*) return 1 ;;
101
+ *) return 0 ;;
102
+ esac
103
+ }
104
+
105
+ fm_lease_path() {
106
+ printf '%s/.lease-%s\n' "$STATE" "$1"
107
+ }
108
+
109
+ # fm_lease_read <task>: read the lease into BROKK_LEASE_ACTOR/BROKK_LEASE_PID/
110
+ # BROKK_LEASE_EPOCH. Returns 1 when no lease file exists. A malformed lease
111
+ # (unreadable actor or pid) reads as actor "" so callers treat it as stale
112
+ # rather than blocking forever on a torn record.
113
+ fm_lease_read() {
114
+ local file line
115
+ file=$(fm_lease_path "$1")
116
+ BROKK_LEASE_ACTOR=
117
+ BROKK_LEASE_PID=
118
+ BROKK_LEASE_EPOCH=
119
+ [ -e "$file" ] || return 1
120
+ IFS= read -r line < "$file" 2>/dev/null || line=
121
+ BROKK_LEASE_ACTOR=$(printf '%s' "$line" | cut -f1)
122
+ BROKK_LEASE_PID=$(printf '%s' "$line" | cut -f2)
123
+ # shellcheck disable=SC2034 # Consumed by sourcing callers (bin/brokk-lease.sh check).
124
+ BROKK_LEASE_EPOCH=$(printf '%s' "$line" | cut -f3)
125
+ case "$BROKK_LEASE_ACTOR" in
126
+ main|branch) ;;
127
+ *) BROKK_LEASE_ACTOR= ;;
128
+ esac
129
+ case "$BROKK_LEASE_PID" in
130
+ '' | *[!0-9]*) BROKK_LEASE_PID= ;;
131
+ esac
132
+ return 0
133
+ }
134
+
135
+ # fm_lease_live <task>: 0 iff a well-formed lease exists in a Pi context, its
136
+ # recorded pid is alive, and that pid IS the current session-lock holder (see
137
+ # the staleness contract above).
138
+ fm_lease_live() {
139
+ local lock_pid
140
+ case "${PI_CODING_AGENT:-}:${BROKK_SUPERVISION_ACTOR:-}" in
141
+ true:*|*:main|*:branch) ;;
142
+ *) return 1 ;;
143
+ esac
144
+ fm_lease_read "$1" || return 1
145
+ [ -n "$BROKK_LEASE_ACTOR" ] || return 1
146
+ [ -n "$BROKK_LEASE_PID" ] || return 1
147
+ kill -0 "$BROKK_LEASE_PID" 2>/dev/null || return 1
148
+ # The session lock is machine-global for the primary; state/.lock-path records
149
+ # the resolved path (per-home for an Eindri-home, legacy state/.lock otherwise).
150
+ local lock_file="$STATE/.lock"
151
+ [ -r "$STATE/.lock-path" ] && lock_file=$(tr -d '[:space:]' <"$STATE/.lock-path")
152
+ lock_pid=$(head -n 1 "$lock_file" 2>/dev/null || true)
153
+ case "$lock_pid" in ''|0|1|*[!0-9]*) return 1 ;; esac
154
+ [ "$BROKK_LEASE_PID" = "$lock_pid" ]
155
+ }
156
+
157
+ # fm_lease_clear_stale <task>: remove the lease file when it exists but is not
158
+ # live. Silent; never touches a live lease.
159
+ fm_lease_clear_stale() {
160
+ local file
161
+ file=$(fm_lease_path "$1")
162
+ [ -e "$file" ] || return 0
163
+ fm_lease_live "$1" && return 0
164
+ rm -f -- "$file"
165
+ }
166
+
167
+ # fm_lease_guard <task> <action-label>: refuse (exit BROKK_LEASE_REFUSE_EXIT) when
168
+ # a live lease held by the OTHER actor exists for <task>. In a Pi supervision
169
+ # context, a successful guard retains the command lock across the caller's
170
+ # mutation; the caller must invoke fm_lease_guard_release from its EXIT cleanup.
171
+ # This closes the check/use race with a concurrent claim. Outside Pi, stale
172
+ # records are still cleaned but the lock is released before returning.
173
+ fm_lease_guard() {
174
+ local task=$1 action=$2 actor lock lease_actor active=0
175
+ fm_lease_valid_id "$task" || return 0
176
+ actor=$(fm_lease_actor) || exit "$BROKK_LEASE_REFUSE_EXIT"
177
+ case "${PI_CODING_AGENT:-}:${BROKK_SUPERVISION_ACTOR:-}" in
178
+ true:*|*:main|*:branch) active=1 ;;
179
+ esac
180
+ [ "$active" = 1 ] || [ -e "$(fm_lease_path "$task")" ] || return 0
181
+ fm_lease_lock_helpers
182
+ lock="$STATE/.brokk-lease-command.lock"
183
+ # A caller with more than one guarded phase already excludes claims until
184
+ # its shared cleanup; do not recursively acquire the non-reentrant lock.
185
+ if [ "$BROKK_LEASE_GUARD_LOCK" != "$lock" ]; then
186
+ fm_lock_acquire_wait "$lock"
187
+ BROKK_LEASE_GUARD_LOCK=$lock
188
+ fi
189
+ if ! fm_lease_live "$task"; then
190
+ fm_lease_clear_stale "$task" || { fm_lease_guard_release; return 1; }
191
+ if [ "$active" != 1 ]; then
192
+ fm_lease_guard_release
193
+ fi
194
+ return 0
195
+ fi
196
+ lease_actor=$BROKK_LEASE_ACTOR
197
+ if [ "$lease_actor" != "$actor" ]; then
198
+ fm_lease_guard_release
199
+ echo "error: $action refused - task '$task' is leased to the $lease_actor supervision actor (state/.lease-$task); retry after that actor releases it" >&2
200
+ exit "$BROKK_LEASE_REFUSE_EXIT"
201
+ fi
202
+ }
203
+
204
+ # Release the claim/guard serialization lock retained by fm_lease_guard.
205
+ # Idempotent so callers can use it unconditionally from existing EXIT cleanup.
206
+ fm_lease_guard_release() {
207
+ local lock=$BROKK_LEASE_GUARD_LOCK
208
+ [ -n "$lock" ] || return 0
209
+ BROKK_LEASE_GUARD_LOCK=
210
+ fm_lock_release "$lock"
211
+ }
212
+
213
+ # fm_lease_forbid_branch <action-label>: refuse (exit BROKK_LEASE_REFUSE_EXIT)
214
+ # when the current actor is the supervision branch. Guards the main-owned role
215
+ # partition; a home with no branch never sets the actor and always passes.
216
+ fm_lease_forbid_branch() {
217
+ local action=$1 actor
218
+ actor=$(fm_lease_actor) || exit "$BROKK_LEASE_REFUSE_EXIT"
219
+ [ "$actor" = branch ] || return 0
220
+ echo "error: $action refused - the supervision branch never performs this action; report the outcome and leave it to main (role partition: docs/pi-supervision-branch.md)" >&2
221
+ exit "$BROKK_LEASE_REFUSE_EXIT"
222
+ }
@@ -0,0 +1,193 @@
1
+ #!/usr/bin/env bash
2
+ # brokk-lease.sh - claim, release, inspect, and sweep per-task supervision leases.
3
+ #
4
+ # The lease contract itself (file format, actors, staleness, guard semantics)
5
+ # is owned by bin/brokk-lease-lib.sh; this is the command surface the two
6
+ # supervision actors use around the overlap set (steering, stopping, cleanup,
7
+ # backlog status, stuck-worker recovery). "backlog" is the reserved resource
8
+ # the branch prompt claims around its own backlog writes; main's tasks-axi path
9
+ # is deliberately unguarded in this scope.
10
+ #
11
+ # Usage:
12
+ # brokk-lease.sh claim <task> [--actor main|branch]
13
+ # Take the lease for the calling actor. Idempotent for the holder (the
14
+ # claim refreshes its own lease). Refuses with exit 6 while the other
15
+ # actor holds a live lease. A stale lease (dead pid, or a torn record)
16
+ # is cleared and re-claimed.
17
+ # brokk-lease.sh release <task> [--actor main|branch]
18
+ # Drop the calling actor's lease. Releasing a lease the actor does not
19
+ # hold is a silent no-op, so a retry after a partial failure is safe.
20
+ # Naming the other actor is refused loudly.
21
+ # brokk-lease.sh check <task>
22
+ # Print "<actor> <pid> <epoch> <live|stale>" for a held lease, or
23
+ # nothing (exit 1) when the task is unleased.
24
+ # brokk-lease.sh release-actor --actor main|branch
25
+ # Drop every lease the named actor holds; the Pi branch extension runs
26
+ # this at generation activation so a replaced branch conversation's
27
+ # leases never outlive it.
28
+ # brokk-lease.sh sweep
29
+ # Remove every provably stale lease in this home. Run at session start
30
+ # (a lease held by a dead actor is cleared at session start); safe to
31
+ # run any time - a live lease is never touched.
32
+ #
33
+ # The default actor is $BROKK_SUPERVISION_ACTOR (else main); when --actor is
34
+ # supplied for a mutation, it must name that calling actor. Exit codes: 0 ok,
35
+ # 1 check-miss, 2 usage, 6 refused (other actor holds or actor mismatch).
36
+ set -eu
37
+
38
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
39
+ BROKK_ROOT="${BROKK_ROOT_OVERRIDE:-${BROKK_ROOT:-$(cd "$SCRIPT_DIR/.." && pwd)}}"
40
+ BROKK_HOME="${BROKK_HOME:-${BROKK_ROOT_OVERRIDE:-$BROKK_ROOT}}"
41
+ STATE="${BROKK_STATE_OVERRIDE:-$BROKK_HOME/state}"
42
+ # shellcheck source=bin/brokk-lease-lib.sh
43
+ . "$SCRIPT_DIR/brokk-lease-lib.sh"
44
+ # shellcheck source=bin/brokk-wake-lib.sh
45
+ . "$SCRIPT_DIR/brokk-wake-lib.sh"
46
+
47
+ mkdir -p "$STATE"
48
+ LEASE_COMMAND_LOCK="$STATE/.brokk-lease-command.lock"
49
+ fm_lock_acquire_wait "$LEASE_COMMAND_LOCK"
50
+ trap 'fm_lock_release "$LEASE_COMMAND_LOCK"' EXIT
51
+
52
+ usage() {
53
+ echo "usage: brokk-lease.sh claim|release <task> [--actor main|branch] | release-actor --actor main|branch | check <task> | sweep" >&2
54
+ exit 2
55
+ }
56
+
57
+ CMD=${1:-}
58
+ shift 2>/dev/null || true
59
+
60
+ case "$CMD" in
61
+ claim|release)
62
+ TASK=${1:-}
63
+ shift 2>/dev/null || true
64
+ fm_lease_valid_id "$TASK" || usage
65
+ ACTOR=
66
+ while [ "$#" -gt 0 ]; do
67
+ case "$1" in
68
+ --actor)
69
+ ACTOR=${2:-}
70
+ shift 2 || usage
71
+ ;;
72
+ *) usage ;;
73
+ esac
74
+ done
75
+ if [ -z "$ACTOR" ]; then
76
+ ACTOR=$(fm_lease_actor) || exit 2
77
+ fi
78
+ case "$ACTOR" in main|branch) ;; *) usage ;; esac
79
+ ;;
80
+ check)
81
+ TASK=${1:-}
82
+ [ "$#" -le 1 ] || usage
83
+ fm_lease_valid_id "$TASK" || usage
84
+ ;;
85
+ release-actor)
86
+ ACTOR=
87
+ while [ "$#" -gt 0 ]; do
88
+ case "$1" in
89
+ --actor)
90
+ ACTOR=${2:-}
91
+ shift 2 || usage
92
+ ;;
93
+ *) usage ;;
94
+ esac
95
+ done
96
+ case "$ACTOR" in main|branch) ;; *) usage ;; esac
97
+ ;;
98
+ sweep)
99
+ [ "$#" -eq 0 ] || usage
100
+ ;;
101
+ *) usage ;;
102
+ esac
103
+
104
+ case "$CMD" in
105
+ claim)
106
+ # Loud accidental-override guard: a claim naming the OTHER actor than the
107
+ # caller's own injected identity is a wiring mistake, never a role change.
108
+ # Release and bulk release enforce the same caller authorization below.
109
+ CALLER=$(fm_lease_actor) || exit "$BROKK_LEASE_REFUSE_EXIT"
110
+ if [ "$ACTOR" != "$CALLER" ]; then
111
+ echo "error: claim refused - the $CALLER supervision actor cannot claim a lease as $ACTOR on '$TASK'" >&2
112
+ exit "$BROKK_LEASE_REFUSE_EXIT"
113
+ fi
114
+ LEASE=$(fm_lease_path "$TASK")
115
+ if fm_lease_live "$TASK" && [ "$BROKK_LEASE_ACTOR" != "$ACTOR" ]; then
116
+ echo "error: claim refused - task '$TASK' is leased to the $BROKK_LEASE_ACTOR supervision actor (state/.lease-$TASK)" >&2
117
+ exit "$BROKK_LEASE_REFUSE_EXIT"
118
+ fi
119
+ # The lease outlives this CLI call, so its liveness pid must be the
120
+ # long-lived supervising process: BROKK_LEASE_HOLDER_PID when the caller
121
+ # provides one (the Pi branch extension passes the session-lock holder),
122
+ # else the session-lock holder (state/.lock is the harness pid), else this
123
+ # shell; without a matching session lock the resulting lease is stale.
124
+ HOLDER_PID=${BROKK_LEASE_HOLDER_PID:-}
125
+ case "$HOLDER_PID" in *[!0-9]*) HOLDER_PID= ;; esac
126
+ if [ -z "$HOLDER_PID" ]; then
127
+ # state/.lock-path records the resolved session lock (machine-global for
128
+ # the primary, per-home for an Eindri-home); fall back to the legacy path.
129
+ lock_file="$STATE/.lock"
130
+ [ -r "$STATE/.lock-path" ] && lock_file=$(tr -d '[:space:]' <"$STATE/.lock-path")
131
+ HOLDER_PID=$(head -n 1 "$lock_file" 2>/dev/null | tr -cd '0-9' || true)
132
+ fi
133
+ [ -n "$HOLDER_PID" ] || HOLDER_PID=$$
134
+ TMP=$(mktemp "$STATE/.brokk-lease-tmp.XXXXXX")
135
+ printf '%s\t%s\t%s\n' "$ACTOR" "$HOLDER_PID" "$(date +%s)" > "$TMP"
136
+ if [ -e "$LEASE" ]; then
137
+ # Same-actor refresh, or a stale/torn record: replace atomically.
138
+ mv -f -- "$TMP" "$LEASE"
139
+ elif ! ln -- "$TMP" "$LEASE" 2>/dev/null; then
140
+ # Lost the create race to the sibling actor; re-check who won.
141
+ rm -f -- "$TMP"
142
+ if fm_lease_live "$TASK" && [ "$BROKK_LEASE_ACTOR" != "$ACTOR" ]; then
143
+ echo "error: claim refused - task '$TASK' was just leased to the $BROKK_LEASE_ACTOR supervision actor" >&2
144
+ exit "$BROKK_LEASE_REFUSE_EXIT"
145
+ fi
146
+ TMP=$(mktemp "$STATE/.brokk-lease-tmp.XXXXXX")
147
+ printf '%s\t%s\t%s\n' "$ACTOR" "$HOLDER_PID" "$(date +%s)" > "$TMP"
148
+ mv -f -- "$TMP" "$LEASE"
149
+ else
150
+ rm -f -- "$TMP"
151
+ fi
152
+ ;;
153
+ release)
154
+ CALLER=$(fm_lease_actor) || exit "$BROKK_LEASE_REFUSE_EXIT"
155
+ if [ "$ACTOR" != "$CALLER" ]; then
156
+ echo "error: release refused - the $CALLER supervision actor cannot release a lease as $ACTOR on '$TASK'" >&2
157
+ exit "$BROKK_LEASE_REFUSE_EXIT"
158
+ fi
159
+ if fm_lease_read "$TASK" && { [ "$BROKK_LEASE_ACTOR" = "$ACTOR" ] || [ -z "$BROKK_LEASE_ACTOR" ]; }; then
160
+ rm -f -- "$(fm_lease_path "$TASK")"
161
+ fi
162
+ ;;
163
+ check)
164
+ fm_lease_read "$TASK" || exit 1
165
+ if fm_lease_live "$TASK"; then LIVENESS=live; else LIVENESS=stale; fi
166
+ printf '%s %s %s %s\n' "${BROKK_LEASE_ACTOR:-unreadable}" "${BROKK_LEASE_PID:-0}" "${BROKK_LEASE_EPOCH:-0}" "$LIVENESS"
167
+ ;;
168
+ release-actor)
169
+ CALLER=$(fm_lease_actor) || exit "$BROKK_LEASE_REFUSE_EXIT"
170
+ if [ "$ACTOR" != "$CALLER" ]; then
171
+ echo "error: release-actor refused - the $CALLER supervision actor cannot release leases as $ACTOR" >&2
172
+ exit "$BROKK_LEASE_REFUSE_EXIT"
173
+ fi
174
+ for LEASE in "$STATE"/.lease-*; do
175
+ [ -e "$LEASE" ] || continue
176
+ case "$LEASE" in *.lock) continue ;; esac
177
+ TASK=${LEASE##*/.lease-}
178
+ fm_lease_valid_id "$TASK" || continue
179
+ if fm_lease_read "$TASK" && [ "$BROKK_LEASE_ACTOR" = "$ACTOR" ]; then
180
+ rm -f -- "$LEASE"
181
+ fi
182
+ done
183
+ ;;
184
+ sweep)
185
+ for LEASE in "$STATE"/.lease-*; do
186
+ [ -e "$LEASE" ] || continue
187
+ case "$LEASE" in *.lock) continue ;; esac
188
+ TASK=${LEASE##*/.lease-}
189
+ fm_lease_valid_id "$TASK" || continue
190
+ fm_lease_clear_stale "$TASK"
191
+ done
192
+ ;;
193
+ esac
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env bash
2
+ # brokk-lint.sh — the Brokk lint gate. Single owner of lint for CI and
3
+ # no-mistakes; run by .github/workflows and `commands.lint` in .no-mistakes.yaml.
4
+ # Galdr-style: TOON output, structured errors, no prompts, idempotent.
5
+ #
6
+ # Usage: bin/brokk-lint.sh [--quiet] ; bin/brokk-lint.sh --version
7
+ # Exit: 0 clean, 1 findings, 2 usage.
8
+ set -u
9
+
10
+ VERSION="1.0.0"
11
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
12
+ ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
13
+
14
+ case "${1-}" in
15
+ -v|-V|--version) printf '%s\n' "$VERSION"; exit 0 ;;
16
+ -h|--help) sed -n '2,10p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
17
+ esac
18
+ QUIET=0
19
+ [ "${1-}" = "--quiet" ] && QUIET=1
20
+
21
+ declare -a N S; fails=0
22
+ add() { N+=("$1"); S+=("$2"); [ "$2" = FAIL ] && fails=$((fails + 1)); }
23
+
24
+ # 1. shell syntax
25
+ shell=OK
26
+ for f in "$ROOT"/bin/*.sh; do
27
+ [ -e "$f" ] || continue
28
+ bash -n "$f" 2>/dev/null || shell=FAIL
29
+ done
30
+ add "shell syntax" "$shell"
31
+
32
+ # 2. plugin JS
33
+ js=OK
34
+ if command -v node >/dev/null 2>&1; then
35
+ while IFS= read -r f; do
36
+ node --check "$f" 2>/dev/null || js=FAIL
37
+ done < <(find "$ROOT/.opencode/plugins" -name '*.js' 2>/dev/null)
38
+ fi
39
+ add "plugin syntax" "$js"
40
+
41
+ # 3. JSON parse
42
+ json=OK
43
+ for f in "$ROOT/opencode.json" "$ROOT"/.agents/config/*.json "$ROOT"/.claude/settings.json "$ROOT"/.codex/hooks.json "$ROOT"/.cursor/hooks.json "$ROOT"/.opencode/plugins/package.json; do
44
+ [ -e "$f" ] || continue
45
+ python3 -m json.tool "$f" >/dev/null 2>&1 || json=FAIL
46
+ done
47
+ add "json parse" "$json"
48
+
49
+ # 4. Galdr/Tyr compliance gates
50
+ if bash "$ROOT/.agents/skills/galdr-ymirsystem/scripts/compliance-check.sh" >/dev/null 2>&1; then
51
+ add "galdr compliance" OK
52
+ else
53
+ add "galdr compliance" FAIL
54
+ fi
55
+
56
+ if [ "$QUIET" = 0 ]; then
57
+ printf 'lint[%s]{check,status}:\n' "${#N[@]}"
58
+ for i in "${!N[@]}"; do printf ' "%s","%s"\n' "${N[$i]}" "${S[$i]}"; done
59
+ fi
60
+ if [ "$fails" -gt 0 ]; then
61
+ printf 'error: %s lint check(s) failed\n' "$fails" >&2
62
+ printf 'help: run bin/brokk-lint.sh to see the failing check\n' >&2
63
+ exit 1
64
+ fi
65
+ exit 0
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env bash
2
+ # brokk-send.sh — send a one-line steer to a running Brokk/Eindri-home.
3
+ # Resolves the target's home from data/eindri-homes.md and appends a wake line to
4
+ # its state/.wake-queue (the drain prints it as `WAKE <line>`). Local routes only;
5
+ # a remote route must be nudged on its own host. Galdr-style TOON.
6
+ #
7
+ # Usage: brokk-send.sh <id> <message>
8
+ set -u
9
+
10
+ VERSION="1.0.0"
11
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
12
+ ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
13
+ REG="${BROKK_EINDRI_HOMES:-$ROOT/data/eindri-homes.md}"
14
+
15
+ case "${1-}" in -v|-V|--version) printf '%s\n' "$VERSION"; exit 0 ;; -h|--help|"") sed -n '2,9p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;; esac
16
+ ID="${1-}"; shift || true
17
+ MSG="${*:-}"
18
+ [ -n "$ID" ] && [ -n "$MSG" ] || { printf 'error: usage: brokk-send.sh <id> <message>\n' >&2; exit 2; }
19
+
20
+ if [ "$ID" = "this" ] || [ "$ID" = "brokk" ]; then HOME_DIR="$ROOT"; HOST=""; else
21
+ HOME_DIR=""; HOST=""
22
+ if [ -f "$REG" ]; then
23
+ line="$(grep -E "^- ${ID} " "$REG" | head -1)"
24
+ HOST="$(printf '%s' "$line" | sed -nE 's/.*\(host: ([^;)]+).*/\1/p' | tr -d ' ')"
25
+ HOME_DIR="$(printf '%s' "$line" | sed -nE 's/.*\(.*home: ([^;)]+).*/\1/p' | tr -d ' ')"
26
+ fi
27
+ fi
28
+
29
+ if [ -n "$HOST" ]; then
30
+ printf 'send[1]{id,state,detail}:\n "%s","remote","run bin/brokk-send.sh %s on host %s"\n' "$ID" "$ID" "$HOST"
31
+ exit 1
32
+ fi
33
+ [ -n "$HOME_DIR" ] && [ -d "$HOME_DIR" ] || { printf 'send[1]{id,state,detail}:\n "%s","unknown","no home for id (see %s)"\n' "$ID" "${REG#"$ROOT"/}"; exit 1; }
34
+
35
+ mkdir -p "$HOME_DIR/state"
36
+ ts="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
37
+ printf 'from=brokk to=%s at=%s msg=%s\n' "$ID" "$ts" "$MSG" >>"$HOME_DIR/state/.wake-queue"
38
+ printf 'send[1]{id,state,detail}:\n "%s","queued","%s/state/.wake-queue"\n' "$ID" "${HOME_DIR#"$ROOT"/}"
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env bash
2
+ # brokk-update.sh — back-compat alias.
3
+ #
4
+ # The updater shaman is Gróa; see bin/groa-update.sh. This thin alias keeps old
5
+ # callers working (and the `groa-update` skill now names her).
6
+ set -u
7
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8
+ printf 'note: brokk-update.sh is an alias; the updater is Gróa (bin/groa-update.sh)\n' >&2
9
+ exec "$SCRIPT_DIR/groa-update.sh" "$@"
@@ -0,0 +1,127 @@
1
+ #!/usr/bin/env bash
2
+ set -u
3
+
4
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
+ # shellcheck source=bin/brokk-wake-lib.sh
6
+ . "$SCRIPT_DIR/brokk-wake-lib.sh"
7
+
8
+ BRANCH_ROWS="$STATE/.branch-eligible-rows"
9
+ BRANCH_OWNER="$STATE/.branch-eligible-owner"
10
+ MAIN_ROWS="$STATE/.main-eligible-rows"
11
+ TMP=
12
+ LOCK_HELD=false
13
+
14
+ # shellcheck disable=SC2329 # Registered by the EXIT trap below.
15
+ cleanup() {
16
+ local status=$?
17
+ [ -z "$TMP" ] || rm -f -- "$TMP" 2>/dev/null || true
18
+ [ "$LOCK_HELD" = false ] || fm_lock_release "$BROKK_WAKE_QUEUE_LOCK"
19
+ exit "$status"
20
+ }
21
+ trap cleanup EXIT
22
+ trap 'exit 130' INT
23
+ trap 'exit 143' TERM
24
+
25
+ rows_valid() {
26
+ [ -s "$1" ] && awk 'BEGIN { ok=1 } !/^[0-9]+$/ || seen[$0]++ { ok=0 } END { exit !ok }' "$1"
27
+ }
28
+
29
+ owner_matches() {
30
+ local expected_pid=${1:-} expected_generation=${2:-} version pid identity generation current
31
+ [ -f "$BRANCH_OWNER" ] && [ ! -L "$BRANCH_OWNER" ] || return 1
32
+ exec 8< "$BRANCH_OWNER" || return 1
33
+ IFS= read -r version <&8 || { exec 8<&-; return 1; }
34
+ IFS= read -r pid <&8 || { exec 8<&-; return 1; }
35
+ IFS= read -r identity <&8 || { exec 8<&-; return 1; }
36
+ IFS= read -r generation <&8 || { exec 8<&-; return 1; }
37
+ if IFS= read -r _extra <&8; then exec 8<&-; return 1; fi
38
+ exec 8<&-
39
+ [ "$version" = brokk-branch-eligible-owner-v1 ] || return 1
40
+ case "$pid" in ''|*[!0-9]*|1) return 1 ;; esac
41
+ case "$generation" in ''|*[!A-Za-z0-9._-]*) return 1 ;; esac
42
+ [ -z "$expected_pid" ] || [ "$pid" = "$expected_pid" ] || return 1
43
+ [ -z "$expected_generation" ] || [ "$generation" = "$expected_generation" ] || return 1
44
+ current=$(fm_pid_identity "$pid" 2>/dev/null) || return 1
45
+ [ -n "$current" ] && [ "$current" = "$identity" ]
46
+ }
47
+
48
+ case "${1:-}" in
49
+ activate)
50
+ pid=${2:-}
51
+ generation=${3:-}
52
+ [ "$#" -eq 3 ] || exit 2
53
+ case "$pid" in ''|*[!0-9]*|1) exit 2 ;; esac
54
+ case "$generation" in ''|*[!A-Za-z0-9._-]*) exit 2 ;; esac
55
+ identity=$(fm_pid_identity "$pid" 2>/dev/null) || exit 1
56
+ [ -n "$identity" ] || exit 1
57
+ TMP=$(mktemp "$STATE/.branch-eligible-owner.tmp.XXXXXX") || exit 1
58
+ printf '%s\n%s\n%s\n%s\n' brokk-branch-eligible-owner-v1 "$pid" "$identity" "$generation" > "$TMP" || exit 1
59
+ chmod 0600 "$TMP" || exit 1
60
+ fm_lock_acquire_wait "$BROKK_WAKE_QUEUE_LOCK"
61
+ LOCK_HELD=true
62
+ [ "$(fm_pid_identity "$pid" 2>/dev/null || true)" = "$identity" ] || exit 1
63
+ rm -f -- "$BRANCH_ROWS" || exit 1
64
+ _fm_atomic_replace "$TMP" "$BRANCH_OWNER" || exit 1
65
+ TMP=
66
+ ;;
67
+ publish)
68
+ generation=${2:-}
69
+ [ "$#" -gt 2 ] || exit 2
70
+ case "$generation" in ''|*[!A-Za-z0-9._-]*) exit 2 ;; esac
71
+ shift 2
72
+ TMP=$(mktemp "$STATE/.branch-eligible-rows.tmp.XXXXXX") || exit 1
73
+ printf '%s\n' "$@" > "$TMP" || exit 1
74
+ chmod 0600 "$TMP" || exit 1
75
+ rows_valid "$TMP" || exit 2
76
+ fm_lock_acquire_wait "$BROKK_WAKE_QUEUE_LOCK"
77
+ LOCK_HELD=true
78
+ owner_matches '' "$generation" || exit 1
79
+ replace=1
80
+ if [ -e "$BRANCH_ROWS" ] || [ -L "$BRANCH_ROWS" ]; then
81
+ rows_valid "$BRANCH_ROWS" && cmp -s "$TMP" "$BRANCH_ROWS" || exit 1
82
+ replace=0
83
+ fi
84
+ awk -F '\t' -v requested="$TMP" -v main="$MAIN_ROWS" '
85
+ BEGIN {
86
+ while ((getline line < requested) > 0) wanted[line]=1
87
+ while ((getline line < main) > 0) owned[line]=1
88
+ }
89
+ NF >= 5 && $2 ~ /^[0-9]+$/ && $2 in wanted { present[$2]=1 }
90
+ END {
91
+ for (seq in wanted) if (seq in owned) exit 3
92
+ for (seq in wanted) if (!(seq in present)) exit 1
93
+ }
94
+ ' "$BROKK_WAKE_QUEUE"
95
+ rc=$?
96
+ [ "$rc" -eq 0 ] || exit "$rc"
97
+ if [ "$replace" -eq 1 ]; then
98
+ _fm_atomic_replace "$TMP" "$BRANCH_ROWS" || exit 1
99
+ TMP=
100
+ fi
101
+ ;;
102
+ release)
103
+ generation=${2:-}
104
+ [ "$#" -eq 2 ] || exit 2
105
+ fm_lock_acquire_wait "$BROKK_WAKE_QUEUE_LOCK"
106
+ LOCK_HELD=true
107
+ owner_matches '' "$generation" || exit 1
108
+ rm -f -- "$BRANCH_ROWS" || exit 1
109
+ ;;
110
+ deactivate)
111
+ pid=${2:-}
112
+ generation=${3:-}
113
+ [ "$#" -eq 3 ] || exit 2
114
+ fm_lock_acquire_wait "$BROKK_WAKE_QUEUE_LOCK"
115
+ LOCK_HELD=true
116
+ owner_matches "$pid" "$generation" || exit 1
117
+ rm -f -- "$BRANCH_ROWS" "$BRANCH_OWNER" || exit 1
118
+ ;;
119
+ *)
120
+ echo "usage: brokk-wake-grant.sh activate PID GENERATION | publish GENERATION SEQUENCE... | release GENERATION | deactivate PID GENERATION" >&2
121
+ exit 2
122
+ ;;
123
+ esac
124
+
125
+ fm_lock_release "$BROKK_WAKE_QUEUE_LOCK"
126
+ LOCK_HELD=false
127
+ exit 0