@zerwiz/ymir 0.1.4 → 0.1.7

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 (865) 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/README.md +74 -0
  27. package/.agents/backend/backends/cmux.sh +649 -0
  28. package/.agents/backend/backends/herdr-eventwait.py +157 -0
  29. package/.agents/backend/backends/herdr-workspace-move.py +114 -0
  30. package/.agents/backend/backends/herdr.sh +3386 -0
  31. package/.agents/backend/backends/orca.sh +290 -0
  32. package/.agents/backend/backends/tmux.sh +357 -0
  33. package/.agents/backend/backends/zellij.sh +700 -0
  34. package/.agents/backend/fm-afk-launch.sh +654 -0
  35. package/.agents/backend/fm-afk-return.sh +241 -0
  36. package/.agents/backend/fm-afk-start.sh +172 -0
  37. package/.agents/backend/fm-arm-command-policy.mjs +960 -0
  38. package/.agents/backend/fm-arm-pretool-check.sh +200 -0
  39. package/.agents/backend/fm-backend-hometag-lib.sh +52 -0
  40. package/.agents/backend/fm-backend.sh +981 -0
  41. package/.agents/backend/fm-backlog-handoff.sh +909 -0
  42. package/.agents/backend/fm-backlog-receive.sh +187 -0
  43. package/.agents/backend/fm-backlog-transition-lib.sh +779 -0
  44. package/.agents/backend/fm-bearings-board.sh +204 -0
  45. package/.agents/backend/fm-bearings-snapshot.sh +546 -0
  46. package/.agents/backend/fm-bootstrap.sh +1568 -0
  47. package/.agents/backend/fm-branch-outcome.sh +203 -0
  48. package/.agents/backend/fm-branch-prompt.sh +101 -0
  49. package/.agents/backend/fm-brief.sh +452 -0
  50. package/.agents/backend/fm-busy-event.sh +234 -0
  51. package/.agents/backend/fm-busy-lib.sh +986 -0
  52. package/.agents/backend/fm-captain-hold.sh +1001 -0
  53. package/.agents/backend/fm-cd-command-policy.mjs +153 -0
  54. package/.agents/backend/fm-cd-pretool-check.sh +190 -0
  55. package/.agents/backend/fm-check-lib.sh +74 -0
  56. package/.agents/backend/fm-check-register.sh +42 -0
  57. package/.agents/backend/fm-check-unregister.sh +52 -0
  58. package/.agents/backend/fm-classify-lib.sh +1770 -0
  59. package/.agents/backend/fm-claude-stop-autoarm.sh +334 -0
  60. package/.agents/backend/fm-composer-lib.sh +1416 -0
  61. package/.agents/backend/fm-config-inherit-lib.sh +1202 -0
  62. package/.agents/backend/fm-config-push.sh +254 -0
  63. package/.agents/backend/fm-control-lib.sh +251 -0
  64. package/.agents/backend/fm-control.sh +878 -0
  65. package/.agents/backend/fm-crew-state.sh +625 -0
  66. package/.agents/backend/fm-cursor-lib.sh +243 -0
  67. package/.agents/backend/fm-decision-hold.sh +232 -0
  68. package/.agents/backend/fm-doc-audience-check.sh +269 -0
  69. package/.agents/backend/fm-dod-lib.sh +67 -0
  70. package/.agents/backend/fm-ensure-agents-md.sh +253 -0
  71. package/.agents/backend/fm-extension-launch-barrier.mjs +129 -0
  72. package/.agents/backend/fm-extension.mjs +2577 -0
  73. package/.agents/backend/fm-extension.sh +16 -0
  74. package/.agents/backend/fm-ff-lib.sh +420 -0
  75. package/.agents/backend/fm-fleet-snapshot.sh +1463 -0
  76. package/.agents/backend/fm-fleet-sync.sh +458 -0
  77. package/.agents/backend/fm-fleet-view.sh +96 -0
  78. package/.agents/backend/fm-gate-refuse-lib.sh +102 -0
  79. package/.agents/backend/fm-guard.sh +242 -0
  80. package/.agents/backend/fm-harness.sh +195 -0
  81. package/.agents/backend/fm-herdr-ci-cleanup.sh +115 -0
  82. package/.agents/backend/fm-herdr-lab.sh +346 -0
  83. package/.agents/backend/fm-herdr-session-cleanup.sh +337 -0
  84. package/.agents/backend/fm-home-seed.sh +984 -0
  85. package/.agents/backend/fm-home-summary-refresh.sh +255 -0
  86. package/.agents/backend/fm-hook-host-lib.sh +36 -0
  87. package/.agents/backend/fm-inactive-reconcile.sh +531 -0
  88. package/.agents/backend/fm-inbox.sh +399 -0
  89. package/.agents/backend/fm-install-actionlint.sh +84 -0
  90. package/.agents/backend/fm-install-herdr.sh +96 -0
  91. package/.agents/backend/fm-install-shellcheck.sh +84 -0
  92. package/.agents/backend/fm-install-treehouse.sh +95 -0
  93. package/.agents/backend/fm-kimi-turnend-hook.sh +276 -0
  94. package/.agents/backend/fm-lease-lib.sh +218 -0
  95. package/.agents/backend/fm-lease.sh +189 -0
  96. package/.agents/backend/fm-line-cap-lib.sh +51 -0
  97. package/.agents/backend/fm-lint-workflows.sh +137 -0
  98. package/.agents/backend/fm-lint.sh +591 -0
  99. package/.agents/backend/fm-lock-lib.sh +104 -0
  100. package/.agents/backend/fm-lock.sh +107 -0
  101. package/.agents/backend/fm-marker-lib.sh +12 -0
  102. package/.agents/backend/fm-merge-local.sh +74 -0
  103. package/.agents/backend/fm-merge-outcome-lib.sh +138 -0
  104. package/.agents/backend/fm-nm-run-lib.sh +124 -0
  105. package/.agents/backend/fm-on.sh +125 -0
  106. package/.agents/backend/fm-operational-input.sh +253 -0
  107. package/.agents/backend/fm-peek.sh +46 -0
  108. package/.agents/backend/fm-pending-reply-lib.sh +1409 -0
  109. package/.agents/backend/fm-pr-check.sh +135 -0
  110. package/.agents/backend/fm-pr-lib.sh +1016 -0
  111. package/.agents/backend/fm-pr-merge.sh +707 -0
  112. package/.agents/backend/fm-pr-poll.sh +110 -0
  113. package/.agents/backend/fm-primary-scope-lib.sh +33 -0
  114. package/.agents/backend/fm-procevent-extension-capture.pl +259 -0
  115. package/.agents/backend/fm-procevent-lavish.sh +628 -0
  116. package/.agents/backend/fm-procevent-lib.sh +892 -0
  117. package/.agents/backend/fm-procevent-quota.sh +290 -0
  118. package/.agents/backend/fm-procevent-remote-reply.sh +577 -0
  119. package/.agents/backend/fm-procevent-when.sh +504 -0
  120. package/.agents/backend/fm-procevent.sh +1466 -0
  121. package/.agents/backend/fm-project-mode.sh +92 -0
  122. package/.agents/backend/fm-project-origin-lib.sh +180 -0
  123. package/.agents/backend/fm-promote.sh +282 -0
  124. package/.agents/backend/fm-public-followup-emit.sh +260 -0
  125. package/.agents/backend/fm-public-followup-lib.sh +398 -0
  126. package/.agents/backend/fm-public-followup.sh +1330 -0
  127. package/.agents/backend/fm-push-transition-lib.sh +168 -0
  128. package/.agents/backend/fm-quota-axi-lib.sh +93 -0
  129. package/.agents/backend/fm-quota-choose.sh +384 -0
  130. package/.agents/backend/fm-remote-delta-read.sh +189 -0
  131. package/.agents/backend/fm-remote-doctor.sh +800 -0
  132. package/.agents/backend/fm-remote-entrypoint.sh +193 -0
  133. package/.agents/backend/fm-remote-file.sh +234 -0
  134. package/.agents/backend/fm-remote-home-provision.sh +259 -0
  135. package/.agents/backend/fm-remote-home-seed.sh +259 -0
  136. package/.agents/backend/fm-remote-inherit-push.sh +90 -0
  137. package/.agents/backend/fm-remote-inherit.sh +179 -0
  138. package/.agents/backend/fm-remote-job-lib.sh +1241 -0
  139. package/.agents/backend/fm-remote-job-reap-orphans.sh +137 -0
  140. package/.agents/backend/fm-remote-job-worker.sh +1124 -0
  141. package/.agents/backend/fm-remote-readiness-lib.sh +44 -0
  142. package/.agents/backend/fm-remote-secondmate-control.sh +340 -0
  143. package/.agents/backend/fm-review-diff.sh +158 -0
  144. package/.agents/backend/fm-secondmate-charter-lib.sh +44 -0
  145. package/.agents/backend/fm-secondmate-nudge-lib.sh +68 -0
  146. package/.agents/backend/fm-secondmate-parent-lib.sh +70 -0
  147. package/.agents/backend/fm-secondmate-reconcile.sh +371 -0
  148. package/.agents/backend/fm-secondmate-registry-lib.sh +311 -0
  149. package/.agents/backend/fm-secondmate-report.sh +88 -0
  150. package/.agents/backend/fm-send.sh +1059 -0
  151. package/.agents/backend/fm-session-lock-lib.sh +176 -0
  152. package/.agents/backend/fm-session-start.sh +970 -0
  153. package/.agents/backend/fm-sessionstart-cursor.sh +40 -0
  154. package/.agents/backend/fm-sessionstart-nudge.sh +45 -0
  155. package/.agents/backend/fm-sessionstart-run.sh +145 -0
  156. package/.agents/backend/fm-spawn.sh +3153 -0
  157. package/.agents/backend/fm-startup-memory-budget-lib.sh +224 -0
  158. package/.agents/backend/fm-startup-memory-budget.sh +94 -0
  159. package/.agents/backend/fm-startup-network.sh +642 -0
  160. package/.agents/backend/fm-stow-cascade.sh +251 -0
  161. package/.agents/backend/fm-subagent-pretool-check.sh +207 -0
  162. package/.agents/backend/fm-supervise-daemon.sh +1732 -0
  163. package/.agents/backend/fm-supervision-instructions.sh +215 -0
  164. package/.agents/backend/fm-supervision-lib.sh +90 -0
  165. package/.agents/backend/fm-supervisor-target-lib.sh +78 -0
  166. package/.agents/backend/fm-tangle-lib.sh +53 -0
  167. package/.agents/backend/fm-task-inbox-lib.sh +402 -0
  168. package/.agents/backend/fm-tasks-axi-lib.sh +123 -0
  169. package/.agents/backend/fm-teardown.sh +2922 -0
  170. package/.agents/backend/fm-test-isolation-proof.sh +588 -0
  171. package/.agents/backend/fm-test-run.sh +2191 -0
  172. package/.agents/backend/fm-timeout-lib.sh +141 -0
  173. package/.agents/backend/fm-timing-lib.sh +179 -0
  174. package/.agents/backend/fm-tmux-lib.sh +291 -0
  175. package/.agents/backend/fm-tool-update-check.sh +898 -0
  176. package/.agents/backend/fm-trace-context-lib.sh +227 -0
  177. package/.agents/backend/fm-transition-lib.sh +103 -0
  178. package/.agents/backend/fm-turnend-guard-cursor.sh +391 -0
  179. package/.agents/backend/fm-turnend-guard-grok.sh +90 -0
  180. package/.agents/backend/fm-turnend-guard.sh +432 -0
  181. package/.agents/backend/fm-update.sh +110 -0
  182. package/.agents/backend/fm-vendor-auth-probe.sh +190 -0
  183. package/.agents/backend/fm-voice-client.py +1373 -0
  184. package/.agents/backend/fm-voice-relay.py +1256 -0
  185. package/.agents/backend/fm-wake-drain.sh +592 -0
  186. package/.agents/backend/fm-wake-grant.sh +127 -0
  187. package/.agents/backend/fm-wake-lib.sh +1849 -0
  188. package/.agents/backend/fm-watch-arm.sh +602 -0
  189. package/.agents/backend/fm-watch-checkpoint.sh +109 -0
  190. package/.agents/backend/fm-watch.sh +1962 -0
  191. package/.agents/backend/fm-x-dismiss.sh +116 -0
  192. package/.agents/backend/fm-x-followup.sh +286 -0
  193. package/.agents/backend/fm-x-lib.sh +1000 -0
  194. package/.agents/backend/fm-x-link.sh +234 -0
  195. package/.agents/backend/fm-x-poll.sh +185 -0
  196. package/.agents/backend/fm-x-reply.sh +385 -0
  197. package/.agents/backend/fm_voice_frame.py +166 -0
  198. package/.agents/backend/fm_voice_records.py +574 -0
  199. package/.agents/backend/model-bridge.py +360 -0
  200. package/.agents/backend/opencode-go-bridge.py +30 -0
  201. package/.agents/bus/README.md +12 -0
  202. package/.agents/bus/messages.json +1 -0
  203. package/.agents/config/agents.machine.example.yaml +16 -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 +11 -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/filebrowser/.filebrowser.json +6 -0
  211. package/.agents/filebrowser/README.md +11 -0
  212. package/.agents/gateway/README.md +12 -0
  213. package/.agents/github/README.md +15 -0
  214. package/.agents/github/webhooks/.gitkeep +0 -0
  215. package/.agents/github/workflows/.gitkeep +0 -0
  216. package/.agents/harness/opencode/plugins/lib/rodd-operational-input.js +37 -0
  217. package/.agents/harness/opencode/plugins/package.json +4 -0
  218. package/.agents/harness/opencode/plugins/saga-sessionstart.js +77 -0
  219. package/.agents/harness/opencode/plugins/syn-cd-check.js +61 -0
  220. package/.agents/harness/opencode/plugins/syn-pretool-check.js +68 -0
  221. package/.agents/harness/opencode/plugins/syn-turnend-guard.js +105 -0
  222. package/.agents/harness/opencode/plugins/syn-watch-arm.js +521 -0
  223. package/.agents/memory/README.md +46 -0
  224. package/.agents/memory/runes_audit.md +5 -0
  225. package/.agents/migrations/0001-hodd-layout.sh +38 -0
  226. package/.agents/migrations/0002-a2a-mcp.sh +27 -0
  227. package/.agents/migrations/0003-private-data-separation.sh +121 -0
  228. package/.agents/migrations/0004-hoard-and-realms.sh +104 -0
  229. package/.agents/migrations/0005-roots-out-of-tree.sh +158 -0
  230. package/.agents/sandbox/Dockerfile.utgard +19 -0
  231. package/.agents/sandbox/README.md +14 -0
  232. package/.agents/sandbox/utgard.config.json +14 -0
  233. package/.agents/skills/README.md +59 -0
  234. package/.agents/skills/bragi-marketing/README.md +3 -0
  235. package/.agents/skills/bragi-marketing/SKILL.md +82 -0
  236. package/.agents/skills/eindri-homes/README.md +3 -0
  237. package/.agents/skills/eindri-homes/SKILL.md +291 -0
  238. package/.agents/skills/eindri-homes/assets/control-plane.md +122 -0
  239. package/.agents/skills/eindri-homes/assets/dispatch.md +80 -0
  240. package/.agents/skills/frigg-consent/README.md +3 -0
  241. package/.agents/skills/frigg-consent/SKILL.md +56 -0
  242. package/.agents/skills/galdr-ymirsystem/README.md +3 -0
  243. package/.agents/skills/galdr-ymirsystem/SKILL.md +159 -0
  244. package/.agents/skills/galdr-ymirsystem/assets/README.md +74 -0
  245. package/.agents/skills/galdr-ymirsystem/assets/brokk-distro-runtime.md +390 -0
  246. package/.agents/skills/galdr-ymirsystem/assets/build-method.md +113 -0
  247. package/.agents/skills/galdr-ymirsystem/assets/build-tool-categories.md +178 -0
  248. package/.agents/skills/galdr-ymirsystem/assets/eindri-orchestration.md +518 -0
  249. package/.agents/skills/galdr-ymirsystem/assets/eindri-profiles.md +136 -0
  250. package/.agents/skills/galdr-ymirsystem/assets/harness-integration/README.md +736 -0
  251. package/.agents/skills/galdr-ymirsystem/assets/harness-integration/claude-code.md +197 -0
  252. package/.agents/skills/galdr-ymirsystem/assets/harness-integration/codex.md +191 -0
  253. package/.agents/skills/galdr-ymirsystem/assets/harness-integration/cursor.md +193 -0
  254. package/.agents/skills/galdr-ymirsystem/assets/harness-integration/opencode.md +262 -0
  255. package/.agents/skills/galdr-ymirsystem/assets/harness-integration/pi.md +295 -0
  256. package/.agents/skills/galdr-ymirsystem/assets/hlidskjalf-ui.md +539 -0
  257. package/.agents/skills/galdr-ymirsystem/assets/installation.md +763 -0
  258. package/.agents/skills/galdr-ymirsystem/assets/local-models/HOST-DATA.example.md +72 -0
  259. package/.agents/skills/galdr-ymirsystem/assets/local-models.md +274 -0
  260. package/.agents/skills/galdr-ymirsystem/assets/memory-well.md +163 -0
  261. package/.agents/skills/galdr-ymirsystem/assets/nornir-jobs.md +415 -0
  262. package/.agents/skills/galdr-ymirsystem/assets/norse-naming.md +325 -0
  263. package/.agents/skills/galdr-ymirsystem/assets/odrerir-hall.md +133 -0
  264. package/.agents/skills/galdr-ymirsystem/assets/pi-boot/einherjar-spawn.schema.json +81 -0
  265. package/.agents/skills/galdr-ymirsystem/assets/pi-boot/herdr-profile.toml +75 -0
  266. package/.agents/skills/galdr-ymirsystem/assets/pi-boot/pi-profile.yml +101 -0
  267. package/.agents/skills/galdr-ymirsystem/assets/pi-boot/supervision-tree.yml +163 -0
  268. package/.agents/skills/galdr-ymirsystem/assets/pi-boot-guide.md +58 -0
  269. package/.agents/skills/galdr-ymirsystem/assets/porting-upstream-to-norse.md +301 -0
  270. package/.agents/skills/galdr-ymirsystem/assets/principles.md +385 -0
  271. package/.agents/skills/galdr-ymirsystem/assets/reference-adoption.md +99 -0
  272. package/.agents/skills/galdr-ymirsystem/assets/registry.md +379 -0
  273. package/.agents/skills/galdr-ymirsystem/assets/runtime-compliance.md +463 -0
  274. package/.agents/skills/galdr-ymirsystem/assets/runtime-components.md +553 -0
  275. package/.agents/skills/galdr-ymirsystem/assets/smidja.md +180 -0
  276. package/.agents/skills/galdr-ymirsystem/schemas/toon-schemas.md +190 -0
  277. package/.agents/skills/galdr-ymirsystem/scripts/README.md +45 -0
  278. package/.agents/skills/galdr-ymirsystem/scripts/bench-one.sh +248 -0
  279. package/.agents/skills/galdr-ymirsystem/scripts/compliance-check.sh +503 -0
  280. package/.agents/skills/galdr-ymirsystem/scripts/gpu-sample.sh +43 -0
  281. package/.agents/skills/galdr-ymirsystem/scripts/stop-all.sh +34 -0
  282. package/.agents/skills/galdr-ymirsystem/scripts/toon-check.py +188 -0
  283. package/.agents/skills/gjallarhorn-relay/README.md +3 -0
  284. package/.agents/skills/gjallarhorn-relay/SKILL.md +283 -0
  285. package/.agents/skills/groa-update/SKILL.md +90 -0
  286. package/.agents/skills/hamr-adapters/README.md +3 -0
  287. package/.agents/skills/hamr-adapters/SKILL.md +123 -0
  288. package/.agents/skills/hamr-adapters/references/common/control-and-recovery.md +37 -0
  289. package/.agents/skills/hamr-adapters/references/common/dispatch.md +32 -0
  290. package/.agents/skills/hamr-adapters/references/common/model-and-effort.md +42 -0
  291. package/.agents/skills/hamr-adapters/references/common/primary-hooks.md +40 -0
  292. package/.agents/skills/hamr-adapters/references/harness/claude.md +55 -0
  293. package/.agents/skills/hamr-adapters/references/harness/codex.md +43 -0
  294. package/.agents/skills/hamr-adapters/references/harness/cursor.md +75 -0
  295. package/.agents/skills/hamr-adapters/references/harness/grok.md +69 -0
  296. package/.agents/skills/hamr-adapters/references/harness/kimi.md +51 -0
  297. package/.agents/skills/hamr-adapters/references/harness/muse.md +70 -0
  298. package/.agents/skills/hamr-adapters/references/harness/opencode.md +42 -0
  299. package/.agents/skills/hamr-adapters/references/harness/pi.md +56 -0
  300. package/.agents/skills/herdr-panes/README.md +3 -0
  301. package/.agents/skills/herdr-panes/SKILL.md +92 -0
  302. package/.agents/skills/herdr-panes/assets/herdr-backend.md +346 -0
  303. package/.agents/skills/herdr-panes/assets/tmux-backend.md +115 -0
  304. package/.agents/skills/hnoss-design/DESIGN.md +19 -0
  305. package/.agents/skills/hnoss-design/README.md +3 -0
  306. package/.agents/skills/hnoss-design/SKILL.md +83 -0
  307. package/.agents/skills/hvild-afk/README.md +3 -0
  308. package/.agents/skills/hvild-afk/SKILL.md +241 -0
  309. package/.agents/skills/jord-projects/README.md +3 -0
  310. package/.agents/skills/jord-projects/SKILL.md +92 -0
  311. package/.agents/skills/lifecycle/SKILL.md +56 -0
  312. package/.agents/skills/lifecycle/smoke_test.sh +57 -0
  313. package/.agents/skills/lifecycle/start.sh +21 -0
  314. package/.agents/skills/lifecycle/status.sh +35 -0
  315. package/.agents/skills/lifecycle/stop.sh +16 -0
  316. package/.agents/skills/muninn-stow/README.md +3 -0
  317. package/.agents/skills/muninn-stow/SKILL.md +309 -0
  318. package/.agents/skills/no-mistakes/SKILL.md +379 -0
  319. package/.agents/skills/nornir-schedule/README.md +3 -0
  320. package/.agents/skills/nornir-schedule/SKILL.md +25 -0
  321. package/.agents/skills/nornir-schedule/assets/events.md +137 -0
  322. package/.agents/skills/nornir-schedule/assets/quota.md +131 -0
  323. package/.agents/skills/nsr-compliance/README.md +3 -0
  324. package/.agents/skills/nsr-compliance/SKILL.md +29 -0
  325. package/.agents/skills/nsr-compliance/assets/nsr/README.md +40 -0
  326. package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/README.md +15 -0
  327. package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/git-workflow.md +18 -0
  328. package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/security.md +22 -0
  329. package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/tech-stack.md +8 -0
  330. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/SKILL.md +71 -0
  331. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/config/core_four.yaml +16 -0
  332. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/check_danger.sh +102 -0
  333. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/check_wiring.sh +69 -0
  334. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/validate_code.sh +29 -0
  335. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/verify_docs.py +66 -0
  336. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/generate.sh +109 -0
  337. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/harness/envelopes/result_envelope.json +14 -0
  338. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/harness/envelopes/task_envelope.json +20 -0
  339. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/harness/runner.py +303 -0
  340. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/telemetry/logger.py +112 -0
  341. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/README.md +18 -0
  342. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/config/README.md +10 -0
  343. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/README.md +12 -0
  344. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/check_env.sh +23 -0
  345. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/check_paths.sh +20 -0
  346. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/check_platform.sh +23 -0
  347. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/harness/README.md +11 -0
  348. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/harness/envelopes/README.md +10 -0
  349. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/installer/README.md +10 -0
  350. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/installer/install.sh +125 -0
  351. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/telemetry/README.md +11 -0
  352. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/README.md +20 -0
  353. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/features/README.md +36 -0
  354. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/features/SKILL-template.md +14 -0
  355. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/README.md +25 -0
  356. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/SKILL.md +13 -0
  357. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/create_branch.sh +6 -0
  358. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/safe_commit.sh +9 -0
  359. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/sync_upstream.sh +6 -0
  360. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/README.md +27 -0
  361. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/SKILL.md +15 -0
  362. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/smoke_test.sh +12 -0
  363. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/start.sh +19 -0
  364. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/status.sh +12 -0
  365. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/stop.sh +15 -0
  366. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/README.md +18 -0
  367. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/config/README.md +10 -0
  368. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/config/core_four.yaml +13 -0
  369. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/README.md +12 -0
  370. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_danger.sh +102 -0
  371. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_env.sh +23 -0
  372. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_paths.sh +20 -0
  373. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_platform.sh +23 -0
  374. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_wiring.sh +69 -0
  375. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/README.md +11 -0
  376. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/envelopes/README.md +10 -0
  377. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/envelopes/result_envelope.json +14 -0
  378. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/envelopes/task_envelope.json +20 -0
  379. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/runner.py +303 -0
  380. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/installer/README.md +10 -0
  381. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/installer/install.sh +125 -0
  382. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/telemetry/README.md +11 -0
  383. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/telemetry/logger.py +112 -0
  384. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/README.md +14 -0
  385. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/api.md +17 -0
  386. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/compliance-wiring.md +155 -0
  387. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/frontend.md +15 -0
  388. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/README.md +11 -0
  389. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/README.md +23 -0
  390. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/clients/README.md +16 -0
  391. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/clients/template-README.md +11 -0
  392. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/deploy.sh +49 -0
  393. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/README.md +12 -0
  394. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/development.env.example +17 -0
  395. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/production.env.example +17 -0
  396. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/staging.env.example +17 -0
  397. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/tenants/README.md +11 -0
  398. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/tenants/template.env.example +8 -0
  399. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/README.md +26 -0
  400. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/agent.md +7 -0
  401. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/developers/dev-1.md +20 -0
  402. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/linux.md +9 -0
  403. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/macos.md +10 -0
  404. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/shared.md +19 -0
  405. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/windows.md +14 -0
  406. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/HOSTING/README.md +25 -0
  407. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/HOSTING/_template.md +41 -0
  408. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/HOSTING/hosting-1.md +41 -0
  409. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/README.md +21 -0
  410. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/README.md +15 -0
  411. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/deployment.md +19 -0
  412. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/disaster-recovery.md +15 -0
  413. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/ops-tasks.md +14 -0
  414. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/features/README.md +16 -0
  415. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/project-skills.md +146 -0
  416. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/research/README.md +11 -0
  417. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/research/software-compliance-research.md +269 -0
  418. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/working-with-agents.md +260 -0
  419. package/.agents/skills/nsr-compliance/assets/nsr/assets/root/AGENTS.md +38 -0
  420. package/.agents/skills/nsr-compliance/assets/nsr/assets/root/ARCHITECTURE.md +36 -0
  421. package/.agents/skills/nsr-compliance/assets/nsr/assets/root/BEST_PRACTICES.md +27 -0
  422. package/.agents/skills/nsr-compliance/assets/nsr/assets/root/CI_CD.md +23 -0
  423. package/.agents/skills/nsr-compliance/assets/nsr/assets/root/FEATURES.md +15 -0
  424. package/.agents/skills/nsr-compliance/assets/nsr/assets/root/README.md +22 -0
  425. package/.agents/skills/nsr-compliance/assets/nsr/assets/root/RULES.md +37 -0
  426. package/.agents/skills/nsr-compliance/assets/nsr/assets/root/STRUCTURE.md +45 -0
  427. package/.agents/skills/nsr-compliance/assets/nsr/assets/root/TECH_STACK.md +28 -0
  428. package/.agents/skills/nsr-compliance/assets/nsr/scaffold-spec.md +63 -0
  429. package/.agents/skills/nsr-compliance/assets/nsr/scripts/scaffold.sh +103 -0
  430. package/.agents/skills/nsr-compliance/assets/nsr/scripts/validate.sh +52 -0
  431. package/.agents/skills/nsr-compliance/assets/nsrcompliance/SKILL.md +71 -0
  432. package/.agents/skills/nsr-compliance/assets/nsrcompliance/config/core_four.yaml +16 -0
  433. package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/check_danger.sh +102 -0
  434. package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/check_wiring.sh +69 -0
  435. package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/validate_code.sh +29 -0
  436. package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/verify_docs.py +66 -0
  437. package/.agents/skills/nsr-compliance/assets/nsrcompliance/generate.sh +109 -0
  438. package/.agents/skills/nsr-compliance/assets/nsrcompliance/harness/envelopes/result_envelope.json +14 -0
  439. package/.agents/skills/nsr-compliance/assets/nsrcompliance/harness/envelopes/task_envelope.json +20 -0
  440. package/.agents/skills/nsr-compliance/assets/nsrcompliance/harness/runner.py +303 -0
  441. package/.agents/skills/nsr-compliance/assets/nsrcompliance/telemetry/logger.py +112 -0
  442. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/README.md +18 -0
  443. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/config/README.md +10 -0
  444. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/README.md +12 -0
  445. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/check_env.sh +23 -0
  446. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/check_paths.sh +20 -0
  447. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/check_platform.sh +23 -0
  448. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/harness/README.md +11 -0
  449. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/harness/envelopes/README.md +10 -0
  450. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/installer/README.md +10 -0
  451. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/installer/install.sh +125 -0
  452. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/telemetry/README.md +11 -0
  453. package/.agents/skills/pr-ops/README.md +3 -0
  454. package/.agents/skills/pr-ops/SKILL.md +109 -0
  455. package/.agents/skills/ratatoskr-a2a/README.md +3 -0
  456. package/.agents/skills/ratatoskr-a2a/SKILL.md +148 -0
  457. package/.agents/skills/rules-check-drift/SKILL.md +81 -0
  458. package/.agents/skills/saga-bearings/README.md +3 -0
  459. package/.agents/skills/saga-bearings/SKILL.md +26 -0
  460. package/.agents/skills/saga-bearings/assets/bearings.md +161 -0
  461. package/.agents/skills/saga-bearings/assets/board-template.html +731 -0
  462. package/.agents/skills/saga-bearings/assets/recap.md +56 -0
  463. package/.agents/skills/syn-recovery/README.md +3 -0
  464. package/.agents/skills/syn-recovery/SKILL.md +54 -0
  465. package/.agents/skills/tyr-check/README.md +3 -0
  466. package/.agents/skills/tyr-check/SKILL.md +218 -0
  467. package/.agents/skills/urdh-hold/README.md +3 -0
  468. package/.agents/skills/urdh-hold/SKILL.md +25 -0
  469. package/.agents/skills/urdh-hold/assets/decisions.md +15 -0
  470. package/.agents/skills/urdh-hold/assets/hold.md +54 -0
  471. package/.agents/skills/vor-diagnostics/README.md +3 -0
  472. package/.agents/skills/vor-diagnostics/SKILL.md +68 -0
  473. package/.agents/skills/ymir-host/README.md +3 -0
  474. package/.agents/skills/ymir-host/SKILL.md +35 -0
  475. package/.agents/skills/ymir-host/assets/desktop.md +36 -0
  476. package/.agents/skills/ymir-host/assets/install.md +69 -0
  477. package/.agents/skills/ymir-host/assets/omarchy.md +297 -0
  478. package/.agents/skills/ymir-host/assets/runbooks.md +15 -0
  479. package/.agents/skills/ymir-host/assets/thjazi.md +220 -0
  480. package/.agents/skills/ymir-host/assets/update.md +64 -0
  481. package/.agents/tests/assets/board-render-harness.mjs +117 -0
  482. package/.agents/tests/cmux-test-safety.sh +51 -0
  483. package/.agents/tests/fixtures.sh +291 -0
  484. package/.agents/tests/fm-afk-inject-e2e.test.sh +428 -0
  485. package/.agents/tests/fm-afk-inject-herdr-e2e.test.sh +536 -0
  486. package/.agents/tests/fm-afk-launch.test.sh +961 -0
  487. package/.agents/tests/fm-afk-pi-herdr-return-e2e.test.sh +297 -0
  488. package/.agents/tests/fm-afk-return.test.sh +283 -0
  489. package/.agents/tests/fm-arm-pretool-check.test.sh +482 -0
  490. package/.agents/tests/fm-ask-user-authority.test.sh +42 -0
  491. package/.agents/tests/fm-backend-autodetect-smoke.test.sh +176 -0
  492. package/.agents/tests/fm-backend-cmux-smoke.test.sh +188 -0
  493. package/.agents/tests/fm-backend-cmux.test.sh +1166 -0
  494. package/.agents/tests/fm-backend-herdr-eventwait-smoke.test.sh +136 -0
  495. package/.agents/tests/fm-backend-herdr-eventwait.test.py +106 -0
  496. package/.agents/tests/fm-backend-herdr-focus-flash-e2e.test.sh +409 -0
  497. package/.agents/tests/fm-backend-herdr-launcher-workspace-e2e.test.sh +437 -0
  498. package/.agents/tests/fm-backend-herdr-presentation-e2e.test.sh +1424 -0
  499. package/.agents/tests/fm-backend-herdr-prune-safety-e2e.test.sh +180 -0
  500. package/.agents/tests/fm-backend-herdr-respawn-idem-e2e.test.sh +182 -0
  501. package/.agents/tests/fm-backend-herdr-smoke.test.sh +355 -0
  502. package/.agents/tests/fm-backend-herdr-workspace-per-home-e2e.test.sh +251 -0
  503. package/.agents/tests/fm-backend-herdr.test.sh +4606 -0
  504. package/.agents/tests/fm-backend-orca.test.sh +1357 -0
  505. package/.agents/tests/fm-backend-tmux-smoke.test.sh +173 -0
  506. package/.agents/tests/fm-backend-zellij-smoke.test.sh +205 -0
  507. package/.agents/tests/fm-backend-zellij.test.sh +1360 -0
  508. package/.agents/tests/fm-backend.test.sh +1142 -0
  509. package/.agents/tests/fm-backlog-atomicity.test.sh +2302 -0
  510. package/.agents/tests/fm-backlog-handoff.test.sh +1360 -0
  511. package/.agents/tests/fm-bearings-board-render.test.sh +135 -0
  512. package/.agents/tests/fm-bearings-board.test.sh +414 -0
  513. package/.agents/tests/fm-bearings-snapshot.test.sh +1990 -0
  514. package/.agents/tests/fm-bootstrap-network-parallel.test.sh +316 -0
  515. package/.agents/tests/fm-bootstrap.test.sh +1178 -0
  516. package/.agents/tests/fm-branch-supervision.test.sh +552 -0
  517. package/.agents/tests/fm-brief.test.sh +785 -0
  518. package/.agents/tests/fm-busy-adapter-wiring.test.sh +324 -0
  519. package/.agents/tests/fm-busy-state.test.sh +465 -0
  520. package/.agents/tests/fm-calm-pi-extension.test.sh +3979 -0
  521. package/.agents/tests/fm-captain-hold-lifecycle.test.sh +1187 -0
  522. package/.agents/tests/fm-cd-pretool-check.test.sh +400 -0
  523. package/.agents/tests/fm-check-unregister.test.sh +198 -0
  524. package/.agents/tests/fm-classify-corr-token.test.sh +543 -0
  525. package/.agents/tests/fm-classify-decision-key.test.sh +340 -0
  526. package/.agents/tests/fm-claude-stop-autoarm-live-e2e.test.sh +164 -0
  527. package/.agents/tests/fm-claude-stop-autoarm.test.sh +1190 -0
  528. package/.agents/tests/fm-cmux-claude-composer-live-e2e.test.sh +110 -0
  529. package/.agents/tests/fm-codex-continuity-live-e2e.test.sh +55 -0
  530. package/.agents/tests/fm-composer-ghost.test.sh +716 -0
  531. package/.agents/tests/fm-composer-lib.test.sh +666 -0
  532. package/.agents/tests/fm-composer-matrix-live-e2e.test.sh +220 -0
  533. package/.agents/tests/fm-control-herdr-smoke.test.sh +149 -0
  534. package/.agents/tests/fm-control-relaunch.test.sh +1530 -0
  535. package/.agents/tests/fm-control.test.sh +910 -0
  536. package/.agents/tests/fm-crew-state.test.sh +1610 -0
  537. package/.agents/tests/fm-cursor-harness.test.sh +404 -0
  538. package/.agents/tests/fm-cursor-primary-live-e2e.test.sh +217 -0
  539. package/.agents/tests/fm-cursor-primary.test.sh +708 -0
  540. package/.agents/tests/fm-daemon.test.sh +2740 -0
  541. package/.agents/tests/fm-documentation-audiences.test.sh +141 -0
  542. package/.agents/tests/fm-ensure-agents-md.test.sh +371 -0
  543. package/.agents/tests/fm-extension-binding.test.sh +2187 -0
  544. package/.agents/tests/fm-fleet-snapshot-view.test.sh +816 -0
  545. package/.agents/tests/fm-fleet-sync.test.sh +721 -0
  546. package/.agents/tests/fm-gate-refuse.test.sh +356 -0
  547. package/.agents/tests/fm-gitignore-config.test.sh +89 -0
  548. package/.agents/tests/fm-gotmp.test.sh +230 -0
  549. package/.agents/tests/fm-grok-continuity-live-e2e.test.sh +112 -0
  550. package/.agents/tests/fm-grok-harness.test.sh +117 -0
  551. package/.agents/tests/fm-grok-stop-live-e2e.test.sh +219 -0
  552. package/.agents/tests/fm-guard-stale-banner.test.sh +709 -0
  553. package/.agents/tests/fm-harness-adapter-instructions-live-e2e.test.sh +134 -0
  554. package/.agents/tests/fm-harness-adapter-references.test.sh +30 -0
  555. package/.agents/tests/fm-harness-liveness-drift-live-e2e.test.sh +151 -0
  556. package/.agents/tests/fm-herdr-lab.test.sh +243 -0
  557. package/.agents/tests/fm-herdr-session-cleanup-e2e.test.sh +146 -0
  558. package/.agents/tests/fm-herdr-session-cleanup.test.sh +329 -0
  559. package/.agents/tests/fm-herdr-submit-confirm-live-e2e.test.sh +125 -0
  560. package/.agents/tests/fm-herdr-version-floor-live-e2e.test.sh +144 -0
  561. package/.agents/tests/fm-home-summary-refresh.test.sh +971 -0
  562. package/.agents/tests/fm-inactive-reconcile.test.sh +485 -0
  563. package/.agents/tests/fm-kimi-harness.test.sh +687 -0
  564. package/.agents/tests/fm-lint-workflows.test.sh +532 -0
  565. package/.agents/tests/fm-lint.test.sh +1023 -0
  566. package/.agents/tests/fm-muse-harness.test.sh +932 -0
  567. package/.agents/tests/fm-muse-signals-live-e2e.test.sh +205 -0
  568. package/.agents/tests/fm-no-mistakes-required.test.sh +72 -0
  569. package/.agents/tests/fm-on.test.sh +507 -0
  570. package/.agents/tests/fm-opencode-primary-live-e2e.test.sh +357 -0
  571. package/.agents/tests/fm-operational-input.test.sh +160 -0
  572. package/.agents/tests/fm-peek-remote.test.sh +110 -0
  573. package/.agents/tests/fm-pending-reply.test.sh +1288 -0
  574. package/.agents/tests/fm-pi-branch-extension.test.sh +3182 -0
  575. package/.agents/tests/fm-pi-branch-live-e2e.test.sh +527 -0
  576. package/.agents/tests/fm-pi-primary-live-e2e.test.sh +345 -0
  577. package/.agents/tests/fm-pi-primary-types.test.sh +68 -0
  578. package/.agents/tests/fm-pi-watch-extension.test.sh +2843 -0
  579. package/.agents/tests/fm-pr-check-security.test.sh +2140 -0
  580. package/.agents/tests/fm-pr-merge.test.sh +2135 -0
  581. package/.agents/tests/fm-procevent-quota.test.sh +225 -0
  582. package/.agents/tests/fm-procevent-when.test.sh +406 -0
  583. package/.agents/tests/fm-procevent.test.sh +1745 -0
  584. package/.agents/tests/fm-project-origin.test.sh +110 -0
  585. package/.agents/tests/fm-public-followup.test.sh +2272 -0
  586. package/.agents/tests/fm-quota-array-dispatch-live-e2e.test.sh +526 -0
  587. package/.agents/tests/fm-quota-choose.test.sh +626 -0
  588. package/.agents/tests/fm-remote-backlog-handoff.test.sh +453 -0
  589. package/.agents/tests/fm-remote-doctor.test.sh +625 -0
  590. package/.agents/tests/fm-remote-entrypoint.test.sh +59 -0
  591. package/.agents/tests/fm-remote-job-orphan-reap.test.sh +205 -0
  592. package/.agents/tests/fm-remote-job.test.sh +768 -0
  593. package/.agents/tests/fm-remote-reply.test.sh +520 -0
  594. package/.agents/tests/fm-remote-secondmate-lifecycle-e2e.test.sh +1256 -0
  595. package/.agents/tests/fm-remote-secondmate-parent-binding.test.sh +326 -0
  596. package/.agents/tests/fm-remote-secondmate-trace-context.test.sh +310 -0
  597. package/.agents/tests/fm-remote-transport-lanes.test.sh +431 -0
  598. package/.agents/tests/fm-review-diff.test.sh +176 -0
  599. package/.agents/tests/fm-secondmate-harness.test.sh +2600 -0
  600. package/.agents/tests/fm-secondmate-lifecycle-e2e.test.sh +259 -0
  601. package/.agents/tests/fm-secondmate-liveness.test.sh +559 -0
  602. package/.agents/tests/fm-secondmate-reconcile.test.sh +732 -0
  603. package/.agents/tests/fm-secondmate-safety.test.sh +2972 -0
  604. package/.agents/tests/fm-secondmate-sync.test.sh +913 -0
  605. package/.agents/tests/fm-send-inbox-doorbell-live-e2e.test.sh +206 -0
  606. package/.agents/tests/fm-send-inbox.test.sh +352 -0
  607. package/.agents/tests/fm-send-popup-settle.test.sh +167 -0
  608. package/.agents/tests/fm-send-remote-delivery.test.sh +796 -0
  609. package/.agents/tests/fm-send-resolve-key.test.sh +551 -0
  610. package/.agents/tests/fm-send-secondmate-marker-herdr-e2e.test.sh +187 -0
  611. package/.agents/tests/fm-send-secondmate-marker.test.sh +278 -0
  612. package/.agents/tests/fm-send-settle.test.sh +147 -0
  613. package/.agents/tests/fm-send-strict.test.sh +241 -0
  614. package/.agents/tests/fm-session-lock-ancestry.test.sh +365 -0
  615. package/.agents/tests/fm-session-start.test.sh +2515 -0
  616. package/.agents/tests/fm-sessionstart-hook-live-e2e.test.sh +631 -0
  617. package/.agents/tests/fm-sessionstart-instruction-refresh-live-e2e.test.sh +230 -0
  618. package/.agents/tests/fm-sessionstart-nudge.test.sh +1039 -0
  619. package/.agents/tests/fm-shared-captain-inheritance.test.sh +404 -0
  620. package/.agents/tests/fm-spawn-batch.test.sh +148 -0
  621. package/.agents/tests/fm-spawn-dispatch-profile.test.sh +827 -0
  622. package/.agents/tests/fm-spawn-pool-base-freshen.test.sh +440 -0
  623. package/.agents/tests/fm-spawn-worktree-settle.test.sh +147 -0
  624. package/.agents/tests/fm-startup-memory-budget.test.sh +333 -0
  625. package/.agents/tests/fm-startup-network.test.sh +712 -0
  626. package/.agents/tests/fm-stow-cascade.test.sh +370 -0
  627. package/.agents/tests/fm-subagent-pretool-check.test.sh +291 -0
  628. package/.agents/tests/fm-supervision-events.test.sh +156 -0
  629. package/.agents/tests/fm-supervision-instructions.test.sh +189 -0
  630. package/.agents/tests/fm-tangle-guard.test.sh +277 -0
  631. package/.agents/tests/fm-task-delivery.test.sh +420 -0
  632. package/.agents/tests/fm-task-inbox.test.sh +513 -0
  633. package/.agents/tests/fm-teardown-endpoint-safety.test.sh +374 -0
  634. package/.agents/tests/fm-teardown.test.sh +2665 -0
  635. package/.agents/tests/fm-test-fixture-cleanup.test.sh +172 -0
  636. package/.agents/tests/fm-test-fixtures.test.sh +132 -0
  637. package/.agents/tests/fm-test-isolation-proof.test.sh +278 -0
  638. package/.agents/tests/fm-test-run.test.sh +1196 -0
  639. package/.agents/tests/fm-tmux-agent-liveness.test.sh +354 -0
  640. package/.agents/tests/fm-tmux-submit-busy.test.sh +340 -0
  641. package/.agents/tests/fm-tool-update-check.test.sh +1044 -0
  642. package/.agents/tests/fm-trace-context-lib.test.sh +253 -0
  643. package/.agents/tests/fm-trace-context-spawn.test.sh +581 -0
  644. package/.agents/tests/fm-transition-lib.test.sh +54 -0
  645. package/.agents/tests/fm-turnend-guard.test.sh +1822 -0
  646. package/.agents/tests/fm-update.test.sh +304 -0
  647. package/.agents/tests/fm-vendor-auth-probe.test.sh +395 -0
  648. package/.agents/tests/fm-voice-relay.test.sh +4741 -0
  649. package/.agents/tests/fm-wake-daemon-lifecycle-e2e.test.sh +171 -0
  650. package/.agents/tests/fm-wake-drain-open-decisions-cursor.test.sh +356 -0
  651. package/.agents/tests/fm-wake-drain-open-decisions.test.sh +226 -0
  652. package/.agents/tests/fm-wake-drain-unread-status.test.sh +379 -0
  653. package/.agents/tests/fm-wake-queue.test.sh +1224 -0
  654. package/.agents/tests/fm-watch-arm.test.sh +821 -0
  655. package/.agents/tests/fm-watch-checkpoint.test.sh +87 -0
  656. package/.agents/tests/fm-watch-recovery-loop.test.sh +223 -0
  657. package/.agents/tests/fm-watch-triage.test.sh +3889 -0
  658. package/.agents/tests/fm-watcher-lock.test.sh +1133 -0
  659. package/.agents/tests/fm-x-mode.test.sh +3042 -0
  660. package/.agents/tests/gleipnir-guard-pretool-check.test.sh +51 -0
  661. package/.agents/tests/gleipnir-machine-lock.test.sh +130 -0
  662. package/.agents/tests/herdr-test-safety.sh +42 -0
  663. package/.agents/tests/lib.sh +315 -0
  664. package/.agents/tests/remote-herdr-fixture.sh +125 -0
  665. package/.agents/tests/secondmate-helpers.sh +193 -0
  666. package/.agents/tests/smoke.test.sh +93 -0
  667. package/.agents/tests/wake-helpers.sh +338 -0
  668. package/.agents/tests/zellij-test-safety.sh +60 -0
  669. package/.agents/tools/README.md +10 -0
  670. package/.agents/tools/bin/tasks-cli +267 -0
  671. package/.agents/tools/tasks-cli.ts +216 -0
  672. package/AGENTS.md +498 -0
  673. package/CHANGELOG.md +1913 -0
  674. package/LICENSE +1 -1
  675. package/NOTICE +63 -0
  676. package/README.md +114 -60
  677. package/RULES/01-domains.md +51 -0
  678. package/RULES/02-agents.md +78 -0
  679. package/RULES/03-houses.md +61 -0
  680. package/RULES/04-hoard.md +97 -0
  681. package/RULES/05-platforms.md +67 -0
  682. package/RULES/06-append-only.md +108 -0
  683. package/RULES/07-config.md +101 -0
  684. package/RULES/08-delivery-gate.md +75 -0
  685. package/RULES/09-electron.md +58 -0
  686. package/RULES/README.md +22 -0
  687. package/bin/README.md +107 -0
  688. package/bin/a2a-mcp.sh +133 -0
  689. package/bin/a2a-serve.py +103 -0
  690. package/bin/a2a-serve.sh +8 -0
  691. package/bin/a2a-talk.sh +50 -0
  692. package/bin/a2abridge-ensure.sh +108 -0
  693. package/bin/agent-run.sh +43 -0
  694. package/bin/agents-config.sh +256 -0
  695. package/bin/apodex-smoke-test.sh +105 -0
  696. package/bin/bifrost-bridge.sh +131 -0
  697. package/bin/bifrost-ingress.sh +77 -0
  698. package/bin/bootstrap-macos.sh +112 -0
  699. package/bin/bootstrap-windows.ps1 +112 -0
  700. package/bin/branch-guard.sh +64 -0
  701. package/bin/brokk +73 -0
  702. package/bin/brokk-classify-lib.sh +1770 -0
  703. package/bin/brokk-lease-lib.sh +222 -0
  704. package/bin/brokk-lease.sh +193 -0
  705. package/bin/brokk-lint.sh +65 -0
  706. package/bin/brokk-send.sh +51 -0
  707. package/bin/brokk-update.sh +9 -0
  708. package/bin/brokk-wake-grant.sh +127 -0
  709. package/bin/brokk-wake-lib.sh +1849 -0
  710. package/bin/changelog-assemble.sh +154 -0
  711. package/bin/changelog-guard.sh +197 -0
  712. package/bin/crash-sense.sh +173 -0
  713. package/bin/design-check.sh +80 -0
  714. package/bin/design-icon.sh +153 -0
  715. package/bin/desktop-place.sh +224 -0
  716. package/bin/docs-guard.sh +39 -0
  717. package/bin/editor-place.sh +225 -0
  718. package/bin/eindri-acclaim.sh +47 -0
  719. package/bin/eindri-control.sh +28 -0
  720. package/bin/eindri-role.sh +83 -0
  721. package/bin/eindri-seat.sh +83 -0
  722. package/bin/eindri-seen.sh +54 -0
  723. package/bin/eindri-send.sh +15 -0
  724. package/bin/eindri-start.sh +98 -0
  725. package/bin/eindri-watch.sh +57 -0
  726. package/bin/einherjar-spawn.sh +576 -0
  727. package/bin/eir-doctor.sh +158 -0
  728. package/bin/erindi-brief.sh +271 -0
  729. package/bin/feature-inventory.sh +73 -0
  730. package/bin/fleet-apply.sh +81 -0
  731. package/bin/github-deploy.sh +94 -0
  732. package/bin/gjallarhorn-expose.sh +136 -0
  733. package/bin/gjallarhorn-notify.sh +71 -0
  734. package/bin/gjallarhorn-purge.sh +67 -0
  735. package/bin/gjallarhorn-tunnel.sh +85 -0
  736. package/bin/gleipnir-lock-lib.sh +284 -0
  737. package/bin/groa-update.sh +130 -0
  738. package/bin/hall-snapshot.sh +111 -0
  739. package/bin/hamr-harness.sh +246 -0
  740. package/bin/heimdall-ssh-keys.sh +374 -0
  741. package/bin/herdr-agents.py +44 -0
  742. package/bin/herdr-ensure.sh +104 -0
  743. package/bin/herdr-run.sh +452 -0
  744. package/bin/hermes-ensure.sh +88 -0
  745. package/bin/hlidskjalf-agents.sh +172 -0
  746. package/bin/hlidskjalf-usage.sh +196 -0
  747. package/bin/hoard-guard.sh +135 -0
  748. package/bin/hoard-lib.sh +105 -0
  749. package/bin/hodd.sh +102 -0
  750. package/bin/host-sense.sh +199 -0
  751. package/bin/huginn-research-worker.sh +121 -0
  752. package/bin/local-model-lock.sh +70 -0
  753. package/bin/mimir-bridge.py +259 -0
  754. package/bin/mimir-bridge.sh +100 -0
  755. package/bin/mimir-ingest.sh +131 -0
  756. package/bin/mimir-reflect.sh +27 -0
  757. package/bin/mimir.sh +113 -0
  758. package/bin/mjollnir-webhook.sh +72 -0
  759. package/bin/mjollnir.sh +104 -0
  760. package/bin/model-hardware.sh +96 -0
  761. package/bin/model-resolve.sh +160 -0
  762. package/bin/models-detect.sh +178 -0
  763. package/bin/nornir-cron-start.sh +162 -0
  764. package/bin/nornir-job-daily-briefing.sh +191 -0
  765. package/bin/nornir-job-git-sync.sh +152 -0
  766. package/bin/nornir-job-hall-snapshot.sh +28 -0
  767. package/bin/nornir-job-memory-housekeeping.sh +114 -0
  768. package/bin/nornir-job-nsr-compliance.sh +54 -0
  769. package/bin/nornir-job-observer.sh +166 -0
  770. package/bin/nornir-job-skillopt-sleep.sh +76 -0
  771. package/bin/npm-publish.sh +136 -0
  772. package/bin/omarchy-hook-install.sh +60 -0
  773. package/bin/omarchy-install.sh +161 -0
  774. package/bin/omarchy-plugins.sh +187 -0
  775. package/bin/omarchy-sense.sh +162 -0
  776. package/bin/perm-guard.sh +30 -0
  777. package/bin/pi-agent.sh +68 -0
  778. package/bin/pi-ensure.sh +77 -0
  779. package/bin/pi-local.sh +37 -0
  780. package/bin/pi-model-agnostic.sh +71 -0
  781. package/bin/pi-seat.sh +63 -0
  782. package/bin/prereq-ensure.sh +166 -0
  783. package/bin/private-guard.sh +58 -0
  784. package/bin/project-git.sh +69 -0
  785. package/bin/public-guard.sh +71 -0
  786. package/bin/ratatoskr.sh +49 -0
  787. package/bin/realm-lib.sh +32 -0
  788. package/bin/repo-scrub.sh +62 -0
  789. package/bin/rodd-operational-input.sh +250 -0
  790. package/bin/runes-append.sh +198 -0
  791. package/bin/saga-session-start.sh +172 -0
  792. package/bin/saga-sessionstart-run.sh +79 -0
  793. package/bin/saga-wake-drain.sh +41 -0
  794. package/bin/secret-guard.sh +63 -0
  795. package/bin/sessrumnir-ensure.sh +100 -0
  796. package/bin/sessrumnir-sync.sh +237 -0
  797. package/bin/sessrumnir.sh +104 -0
  798. package/bin/skillopt-setup.sh +76 -0
  799. package/bin/skuld-branch-outcome.sh +203 -0
  800. package/bin/skuld-branch-prompt.sh +101 -0
  801. package/bin/smidja-bootstrap.sh +94 -0
  802. package/bin/smidja-observe.sh +86 -0
  803. package/bin/syn-arm-pretool-check.sh +57 -0
  804. package/bin/syn-asset-pretool-check.sh +89 -0
  805. package/bin/syn-cd-pretool-check.sh +28 -0
  806. package/bin/syn-guard-pretool-check.sh +83 -0
  807. package/bin/syn-spawn-pretool-check.sh +58 -0
  808. package/bin/syn-turnend-guard.sh +36 -0
  809. package/bin/syn-watch-arm.sh +99 -0
  810. package/bin/tailscale-sync.sh +203 -0
  811. package/bin/telegram-bot.sh +82 -0
  812. package/bin/toolchain.sh +74 -0
  813. package/bin/ui-truth-check.sh +75 -0
  814. package/bin/utgard.sh +111 -0
  815. package/bin/valhalla.sh +115 -0
  816. package/bin/valknut-load.sh +298 -0
  817. package/bin/vor-crew-state.sh +124 -0
  818. package/bin/wedge-notify.sh +60 -0
  819. package/bin/workspace-provision.sh +80 -0
  820. package/bin/workspace-rag.sh +163 -0
  821. package/bin/wyrd-db.sh +47 -0
  822. package/bin/yggdrasil.sh +152 -0
  823. package/bin/ymir-edit.sh +145 -0
  824. package/bin/ymir-install.sh +806 -0
  825. package/bin/ymir-invite.sh +93 -0
  826. package/bin/ymir-isolation.sh +88 -0
  827. package/bin/ymir-migrate.sh +61 -0
  828. package/bin/ymir-plan.sh +356 -0
  829. package/bin/ymir-platform.sh +348 -0
  830. package/bin/ymir-say.sh +110 -0
  831. package/bin/ymir-setup-auth.sh +119 -0
  832. package/bin/ymir-validate.sh +193 -0
  833. package/bin/ymir.js +74 -16
  834. package/docs/Architecture.md +339 -0
  835. package/docs/design.md +351 -0
  836. package/docs/installations/README.md +63 -0
  837. package/docs/installations/ymir-home.md +93 -0
  838. package/docs/integration.md +105 -0
  839. package/docs/lore.md +1060 -0
  840. package/docs/research/agent-harnesses.md +290 -0
  841. package/docs/runbooks/README.md +19 -0
  842. package/docs/runbooks/a2a.md +91 -0
  843. package/docs/runbooks/agent-permissions.md +99 -0
  844. package/docs/runbooks/agents.md +57 -0
  845. package/docs/runbooks/models.md +69 -0
  846. package/docs/runbooks/realm-onboarding.md +60 -0
  847. package/docs/runbooks/secrets-and-hoard.md +60 -0
  848. package/docs/runbooks/updates-and-migrations.md +110 -0
  849. package/docs/runbooks/worktrees-isolation.md +72 -0
  850. package/docs/session-start.md +105 -0
  851. package/docs/skillopt-integration.md +321 -0
  852. package/docs/sync-system.md +66 -0
  853. package/docs/workspaces.md +104 -0
  854. package/docs/ymir-rut.md +260 -0
  855. package/package.json +54 -14
  856. package/packaging/build.sh +74 -0
  857. package/packaging/macos/Ymir Installer.command +43 -0
  858. package/packaging/windows/ymir-setup.nsi +74 -0
  859. package/scripts/README.md +22 -0
  860. package/scripts/electron.sh +269 -0
  861. package/scripts/lower.sh +34 -0
  862. package/scripts/raise.sh +42 -0
  863. package/scripts/start.sh +217 -0
  864. package/scripts/stop.sh +113 -0
  865. package/install.sh +0 -35
@@ -0,0 +1,806 @@
1
+ #!/usr/bin/env bash
2
+ # ymir-install.sh — THE FIRST SETUP. Stand the full Ymir up for the operator:
3
+ # prerequisites, the single-tenant workspace tree, the OSS engines (treehouse /
4
+ # sandcastle / no-mistakes), the sandbox image, the well (engram) + harness MCP,
5
+ # the loaders, the registries, and the runtime services. Idempotent. Galdr TOON.
6
+ #
7
+ # Usage:
8
+ # bin/ymir-install.sh [--check] [--skip-engines] [--skip-services] [--no-desktop] [--yes]
9
+ # bin/ymir-install.sh --plan [--json] # the plan, computed — changes nothing
10
+ # bin/ymir-install.sh --status
11
+ # bin/ymir-install.sh --version
12
+ #
13
+ # The consent a real install asks for is not a recited paragraph: it is the PLAN
14
+ # printed by bin/ymir-plan.sh — probed on THIS host, one row per step, each with
15
+ # its state and the reason for it. A paragraph drifts behind the code; a plan is
16
+ # computed from it every run.
17
+ #
18
+ # Exit: 0 all good (or --check/--plan), 1 a step failed, 2 usage, 3 declined.
19
+ set -u
20
+
21
+ # --- portability shim: bin/ymir-platform.sh --------------------------------
22
+ if [ -z "${YMIR_PLATFORM_LOADED:-}" ]; then
23
+ _ymir_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
24
+ for _ymir_c in "$_ymir_dir/ymir-platform.sh" "$(dirname "$_ymir_dir")/bin/ymir-platform.sh"; do
25
+ [ -r "$_ymir_c" ] && { . "$_ymir_c"; YMIR_PLATFORM_LOADED=1; break; }
26
+ done
27
+ unset _ymir_dir _ymir_c
28
+ fi
29
+
30
+ VERSION="1.0.0"
31
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
32
+ ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
33
+
34
+ # The operator's settings and secrets live in the home they chose, never in the
35
+ # code tree — a packaged install replaces its tree on upgrade, and a credential
36
+ # must never sit in a tree that ships (Rule 04).
37
+ if [ -z "${YMIR_HOARD_LIB_LOADED:-}" ]; then
38
+ _yr="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
39
+ for _yc in "$_yr/hoard-lib.sh" "$(dirname "$_yr")/bin/hoard-lib.sh"; do
40
+ [ -r "$_yc" ] && { . "$_yc"; YMIR_HOARD_LIB_LOADED=1; break; }
41
+ done
42
+ unset _yr _yc
43
+ fi
44
+ hoard_settings_dir YMIR_SETTINGS_DIR
45
+ hoard_local_env YMIR_ENV_FILE
46
+ # The home is the OPERATOR's to choose, never ours to assume. Resolution:
47
+ # $YMIR_HOME (explicit) → the choice recorded at a previous installation →
48
+ # the one documented default. An interactive run ASKS and RECORDS the answer
49
+ # (step_home); --check never writes, --yes takes what is recorded.
50
+ # The hoard resolves through the shared lib, so the installer can never disagree
51
+ # with bin/hodd.sh about where private data lives — and never points inside the
52
+ # repo (Rule 04).
53
+ # shellcheck source=bin/hoard-lib.sh
54
+ . "$SCRIPT_DIR/hoard-lib.sh"
55
+ ymir_home_root YMIR_HOME
56
+ WORKSPACE="${YMIR_WORKSPACE:-$YMIR_HOME/workspaces}"
57
+ hoard_root HOARD
58
+ DOMAINS="company marketing development life me"
59
+
60
+ CHECK=0; SKIP_ENGINES=0; SKIP_SERVICES=0; ASSUME_YES=0; NO_DESKTOP=0; PLAN_ONLY=0; PLAN_ARGS=()
61
+ case "${1-}" in -v|-V|--version) printf '%s\n' "$VERSION"; exit 0 ;; -h|--help) sed -n '2,20p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;; esac
62
+ while [ $# -gt 0 ]; do
63
+ case "$1" in
64
+ --check) CHECK=1; shift ;;
65
+ --plan|--dry-run) PLAN_ONLY=1; shift ;;
66
+ --json) PLAN_ARGS+=(--json); shift ;;
67
+ --skip-engines) SKIP_ENGINES=1; shift ;;
68
+ --skip-services) SKIP_SERVICES=1; shift ;;
69
+ --no-desktop) NO_DESKTOP=1; shift ;;
70
+ --yes|-y) ASSUME_YES=1; shift ;;
71
+ --status) exec "$SCRIPT_DIR/ymir-install.sh" --check ;;
72
+ *) printf 'error: unknown flag %s\nhelp: bin/ymir-install.sh [--check|--plan|--skip-engines|--skip-services|--no-desktop|--yes]\n' "$1" >&2; exit 2 ;;
73
+ esac
74
+ done
75
+
76
+ # The plan is a question, not a change: it prints and exits without writing.
77
+ if [ "$PLAN_ONLY" = 1 ]; then
78
+ exec "$SCRIPT_DIR/ymir-plan.sh" ${PLAN_ARGS[@]+"${PLAN_ARGS[@]}"}
79
+ fi
80
+
81
+ declare -a IDS STATUS DETAIL
82
+ # The code minted for this install, reported at the end so it is not lost in the
83
+ # step table. Empty on --check, and when no code could be minted.
84
+ INVITE_CODE=""
85
+ add() { IDS+=("$1"); STATUS+=("$2"); DETAIL+=("$3"); }
86
+ have() { command -v "$1" >/dev/null 2>&1; }
87
+ TOON="install[0]{step,status,detail}:"
88
+
89
+ # ── consent ──────────────────────────────────────────────────────────────
90
+ # Show exactly what will change and require explicit acceptance. A real
91
+ # install touches the machine (packages, a docker image, raised services),
92
+ # so it never proceeds on silence. The plan is COMPUTED here (bin/ymir-plan.sh
93
+ # probes this host) — never a paragraph that can drift behind the code.
94
+ confirm_install() {
95
+ [ "$ASSUME_YES" = 1 ] && return 0
96
+ if [ ! -t 0 ]; then
97
+ printf 'error: refusing a non-interactive install without --yes\nhelp: re-run with --yes to accept non-interactively, or --plan / --check to preview\n' >&2
98
+ exit 3
99
+ fi
100
+ cat <<'PLAN'
101
+ Ymir first setup — the plan below is probed on THIS machine, not recited.
102
+ Each row is a phase, a step, its state, and why.
103
+
104
+ DO a change will be made
105
+ SKIP already satisfied — nothing to do
106
+ INFO a fact about this host; no change implied
107
+ BLOCKED cannot run — the reason names what is missing
108
+ CONSENT needs your word (a credential, an invite, the desktop shells)
109
+
110
+ Nothing is deleted. Every step is idempotent.
111
+ PLAN
112
+ printf '\n'
113
+ bash "$SCRIPT_DIR/ymir-plan.sh" 2>&1 || true
114
+ printf '\nProceed with the install? [y/N] '
115
+ read -r reply || reply=""
116
+ case "$reply" in
117
+ y|Y|yes|YES) ;;
118
+ *) printf 'install declined — nothing was changed.\n'; exit 3 ;;
119
+ esac
120
+ }
121
+
122
+ # ── 1. prereqs ───────────────────────────────────────────────────────────────
123
+ #
124
+ # Self-healing: `bin/prereq-ensure.sh` provisions what it can in user space
125
+ # (bun, uv, mcp<2) with no sudo. Anything it cannot do is reported with an
126
+ # exact command. engram is OPTIONAL and reported honestly, never as a failure.
127
+ ENGRAM_PY=""
128
+ step_prereqs() {
129
+ if [ "$CHECK" = 0 ] && [ -x "$SCRIPT_DIR/prereq-ensure.sh" ]; then
130
+ "$SCRIPT_DIR/prereq-ensure.sh" bun >/dev/null 2>&1 || true
131
+ "$SCRIPT_DIR/prereq-ensure.sh" uv >/dev/null 2>&1 || true
132
+ "$SCRIPT_DIR/prereq-ensure.sh" mcp >/dev/null 2>&1 || true
133
+ # bun installs to ~/.bun/bin; adopt it for the rest of this run.
134
+ [ -x "$HOME/.bun/bin/bun" ] && export PATH="$HOME/.bun/bin:$PATH"
135
+ [ -x "$HOME/.local/bin/uv" ] && export PATH="$HOME/.local/bin:$PATH"
136
+ fi
137
+ local miss="" engine
138
+ for c in git python3 bun; do have "$c" || miss="$miss $c"; done
139
+ python3 -c "from mcp.server.fastmcp import FastMCP" >/dev/null 2>&1 || miss="$miss mcp<2"
140
+ # Docker or Podman — whichever this host has; never assume the binary name.
141
+ engine="$(ymir_container_engine_name 2>/dev/null || true)"
142
+ [ -n "$engine" ] || miss="$miss docker/podman"
143
+ have gh || miss="$miss gh"
144
+ if [ -n "$miss" ]; then add prereqs WARN "missing:$miss"; else add prereqs OK "git python3 bun $engine gh mcp<2"; fi
145
+ # The well engine: attempt to provision it rather than leaving a hint. engram
146
+ # needs Python 3.12/3.13, so prereq-ensure installs it into a compatible
147
+ # interpreter and records which one — the bridge then reuses it.
148
+ if [ -x "$SCRIPT_DIR/prereq-ensure.sh" ]; then
149
+ if "$SCRIPT_DIR/prereq-ensure.sh" engram >/dev/null 2>&1; then
150
+ add memory-well OK "engram installed for the engine's Python"
151
+ else
152
+ add memory-well WARN "engram could not be installed — bin/prereq-ensure.sh engram (needs Python 3.12/3.13)"
153
+ fi
154
+ else
155
+ add memory-well SKIP "no prereq-ensure.sh"
156
+ fi
157
+ }
158
+
159
+ # ── 2. workspace tree ────────────────────────────────────────────────────────
160
+ step_tree() {
161
+ if [ "$CHECK" = 1 ]; then
162
+ local ok=1
163
+ [ -d "$WORKSPACE/work" ] && [ -d "$WORKSPACE/personal" ] && [ -f "$HOARD/identity/workspaces.yaml" ] && [ -f "$HOARD/identity/projects.yaml" ] || ok=0
164
+ if [ "$ok" = 1 ]; then add tree OK "workspace tree present"; else add tree WARN "workspace tree incomplete"; fi
165
+ return
166
+ fi
167
+ local created=0
168
+ for ws in work:company,marketing,development,life personal:me,life,development; do
169
+ local name="${ws%%:*}" domains="${ws#*:}"
170
+ for d in ${domains//,/ }; do
171
+ [ -d "$WORKSPACE/$name/$d" ] || { mkdir -p "$WORKSPACE/$name/$d"; created=$((created+1)); }
172
+ done
173
+ done
174
+ mkdir -p "$WORKSPACE/companies" "$WORKSPACE/memory/daily" "$HOARD/identity"
175
+ # The hoard is OUTSIDE the repo (Rule 04): this creates its layout at the
176
+ # resolved root, never in the checkout. Idempotent.
177
+ "$SCRIPT_DIR/hodd.sh" init >/dev/null 2>&1 || true
178
+ # A missing platform env makes `bin/hodd.sh emit secrets/platform.env` fail on a
179
+ # fresh machine; seed an empty one (0600) so the reference always resolves.
180
+ if [ ! -f "$HOARD/secrets/platform.env" ]; then
181
+ mkdir -p "$HOARD/secrets"
182
+ ( umask 077; : >"$HOARD/secrets/platform.env" )
183
+ created=$((created+1))
184
+ fi
185
+ if [ ! -f "$HOARD/identity/workspaces.yaml" ]; then
186
+ cat >"$HOARD/identity/workspaces.yaml" <<'YAML'
187
+ # Workspace registry — single tenant. One operator, many workspaces.
188
+ # kind: work | personal. company: only for work. domains: knowledge areas.
189
+ # Add a work workspace of your own, e.g.:
190
+ # - id: work
191
+ # name: Work
192
+ # kind: work
193
+ # company: your-company
194
+ # domains: [company, development]
195
+ workspaces:
196
+ - id: personal
197
+ name: Personal
198
+ kind: personal
199
+ domains: [me, life, development]
200
+ YAML
201
+ created=$((created+1))
202
+ fi
203
+ if [ ! -f "$HOARD/identity/projects.yaml" ]; then
204
+ cat >"$HOARD/identity/projects.yaml" <<'YAML'
205
+ # Master project registry. Every project carries its GitHub block here; the
206
+ # runtime reads it — never guesses a remote. auth is a REFERENCE, never a value.
207
+ # Register your own projects, e.g.:
208
+ # - id: my-project
209
+ # name: My Project
210
+ # workspace: personal
211
+ # domains: [development]
212
+ # repo: projects/my-project
213
+ # posture: local-only
214
+ # git: { host: github.com, owner: <you>, repo: my-project, remote: origin, default_branch: main, auth: gh }
215
+ projects: []
216
+ YAML
217
+ created=$((created+1))
218
+ fi
219
+ add tree OK "workspace/{personal} · companies · registries · hoard (outside the repo) (created $created)"
220
+ }
221
+
222
+ # ── 2a. the home the operator chooses ────────────────────────────────────────
223
+ # Everything private — docs, secrets, identity, projects, workspaces, memory —
224
+ # lives in ONE place the operator owns, and it is the operator's to name. A real
225
+ # interactive run asks once and records the answer under ~/.config/ymir/home, so
226
+ # every later script resolves the same home without being told again. --check
227
+ # never writes; --yes takes what is already recorded (or the documented default).
228
+ step_home() {
229
+ local rec="" chosen=""
230
+ ymir_home_record rec
231
+ if [ -n "${YMIR_HOME:-}" ] && [ "$CHECK" = 1 ]; then add home OK "home: $YMIR_HOME"; return; fi
232
+ if [ -n "$rec" ]; then
233
+ add home OK "home: $YMIR_HOME (the choice recorded at installation)"
234
+ return
235
+ fi
236
+ if [ "$ASSUME_YES" = 1 ] || [ ! -t 0 ]; then
237
+ if ymir_home_record_set "$YMIR_HOME" 2>/dev/null; then
238
+ add home OK "home: $YMIR_HOME (default recorded — change it any time with YMIR_HOME=<path> bin/ymir-install.sh)"
239
+ else
240
+ add home WARN "home: $YMIR_HOME (could not record the choice under $YMIR_CONFIG_DIR — pass YMIR_HOME=<path> to every run)"
241
+ fi
242
+ return
243
+ fi
244
+ printf '\nWhere shall your home live?\n'
245
+ printf 'Everything private is kept there — docs, secrets, identity, projects,\n'
246
+ printf 'workspaces, memory — never in the code tree, never in this package.\n'
247
+ printf 'Home [%s]: ' "$YMIR_HOME"
248
+ IFS= read -r chosen || true
249
+ [ -n "$chosen" ] && YMIR_HOME="${chosen/#\~/$HOME}"
250
+ if [ -e "$YMIR_HOME" ]; then
251
+ printf 'using %s — what is already there is kept; nothing is deleted.\n' "$YMIR_HOME"
252
+ fi
253
+ # Re-resolve the roots the choice moved: the hoard within the home, and the
254
+ # workspace tree beneath it. A second run finds the record and never asks again.
255
+ hoard_root HOARD
256
+ WORKSPACE="${YMIR_WORKSPACE:-$YMIR_HOME/workspaces}"
257
+ if ymir_home_record_set "$YMIR_HOME"; then
258
+ add home OK "home: $YMIR_HOME (recorded — later runs need not ask)"
259
+ else
260
+ add home WARN "home: $YMIR_HOME (could not record the choice; pass YMIR_HOME=<path> to every run)"
261
+ fi
262
+ }
263
+
264
+ # ── 2b. app repos (the app split) ────────────────────────────────────────────
265
+ # The apps live in their OWN repos (zerwiz/hlidskjalf · hlidskjalf-mobile ·
266
+ # odrerir · sessrumnir · smidja), registered in the home registry with a
267
+ # `repo: apps/<path>` block. The monorepo never tracks them; installation
268
+ # clones each into the tree — never guessing a remote, always reading the
269
+ # registry. A present repo is fast-forwarded; a missing one cloned. The smithy
270
+ # engine (apps/smidja) is stamped from the cloned factory's templates, exactly
271
+ # as install.py does for a target repo.
272
+ step_apps() {
273
+ local reg="$HOARD/identity/projects.yaml"
274
+ if [ ! -r "$reg" ]; then
275
+ add apps SKIP "no registry — no app repos to pull ($reg)"
276
+ return 0
277
+ fi
278
+ # Parse blocks that carry `repo: apps/<path>` and a `git:` inline dict.
279
+ local entries
280
+ entries=$(awk '
281
+ /^ - id:/ { repo="" }
282
+ /^ repo: apps\// { repo=substr($2, 6) }
283
+ /^ git: / {
284
+ line=$0; host=""; owner=""; grepo=""
285
+ if (match(line, /host: [A-Za-z0-9._-]+/)) host=substr(line, RSTART+6, RLENGTH-6)
286
+ if (match(line, /owner: [A-Za-z0-9_-]+/)) owner=substr(line, RSTART+7, RLENGTH-7)
287
+ if (match(line, /repo: [A-Za-z0-9._-]+/)) grepo=substr(line, RSTART+6, RLENGTH-6)
288
+ if (repo != "" && owner != "" && grepo != "") print repo "|" host "|" owner "|" grepo
289
+ repo=""
290
+ }' "$reg")
291
+ if [ -z "$entries" ]; then
292
+ add apps OK "no apps/ projects registered — nothing to pull"
293
+ return 0
294
+ fi
295
+ local ok=0 skip=0 fail=0 missing=0
296
+ while IFS='|' read -r rel host owner grepo; do
297
+ [ -n "$rel" ] || continue
298
+ local path="$ROOT/apps/$rel"
299
+ if [ "$CHECK" = 1 ]; then
300
+ if [ -d "$path/.git" ]; then add apps OK "$rel present ($owner/$grepo)"; ok=$((ok+1));
301
+ elif [ -d "$path" ]; then add apps WARN "$rel present but not a git clone — re-install to replace"; skip=$((skip+1));
302
+ else add apps WARN "$rel absent — a full run clones $owner/$grepo"; missing=$((missing+1)); fi
303
+ continue
304
+ fi
305
+ if [ -d "$path/.git" ]; then
306
+ if (cd "$path" && git fetch origin 2>/dev/null && git merge --ff-only origin/main >/dev/null 2>&1); then add apps OK "$rel up to date ($owner/$grepo)"; ok=$((ok+1));
307
+ else add apps OK "$rel present ($owner/$grepo; pull refused — local changes?)"; skip=$((skip+1)); fi
308
+ elif [ -d "$path" ]; then
309
+ add apps WARN "$rel present but not a git clone — move $path aside and re-run"; skip=$((skip+1))
310
+ else
311
+ local url="https://github.com/$owner/$grepo.git"
312
+ if git clone -q "$url" "$path" 2>/dev/null; then add apps OK "$rel cloned ($owner/$grepo)"; ok=$((ok+1));
313
+ else add apps WARN "$rel clone failed — run: git clone $url $path"; fail=$((fail+1)); fi
314
+ fi
315
+ done <<< "$entries"
316
+ # The smithy engine: apps/smidja is stamped from the cloned factory's
317
+ # templates (the monorepo tracks neither). The config template follows.
318
+ local factory="$ROOT/apps/smidja-factory" eng="$ROOT/apps/smidja"
319
+ if [ "$CHECK" = 0 ] && [ -d "$factory/templates/smidja" ] && [ ! -e "$eng/smidja_modules" ]; then
320
+ mkdir -p "$eng"
321
+ cp -rn "$factory/templates/smidja/." "$eng/" 2>/dev/null
322
+ [ -f "$factory/templates/smidja.config.yaml" ] && { mkdir -p "$eng/smidja_smidja_config"; cp -n "$factory/templates/smidja.config.yaml" "$eng/smidja_smidja_config/smidja.config.yaml" 2>/dev/null; }
323
+ add apps OK "smidja engine stamped into apps/smidja"
324
+ fi
325
+ if [ "$fail" -gt 0 ]; then add apps WARN "$fail app clone(s) failed (offline?)"; fi
326
+ }
327
+
328
+ # ── 3. engines ───────────────────────────────────────────────────────────────
329
+ step_engines() {
330
+ [ "$SKIP_ENGINES" = 1 ] && { add engines SKIP "--skip-engines"; return; }
331
+ if [ "$CHECK" = 1 ]; then
332
+ local has=""
333
+ have treehouse && has="$has treehouse"
334
+ have no-mistakes && has="$has no-mistakes"
335
+ { [ -d "$ROOT/node_modules/@ai-hero/sandcastle" ] || have sandcastle; } && has="$has sandcastle"
336
+ if [ -n "$has" ]; then add engines OK "present:$has"; else add engines WARN "none present"; fi
337
+ return
338
+ fi
339
+ local got=""
340
+ if have treehouse; then got="$got treehouse"; else
341
+ if curl -fsSL https://kunchenguid.github.io/treehouse/install.sh 2>/dev/null | sh >/dev/null 2>&1 && have treehouse; then got="$got treehouse"; fi
342
+ fi
343
+ if have no-mistakes; then got="$got no-mistakes"; else
344
+ if curl -fsSL https://raw.githubusercontent.com/kunchenguid/no-mistakes/main/docs/install.sh 2>/dev/null | sh >/dev/null 2>&1 && have no-mistakes; then got="$got no-mistakes"; fi
345
+ fi
346
+ if [ -d "$ROOT/node_modules/@ai-hero/sandcastle" ] || have sandcastle; then got="$got sandcastle"; fi
347
+ if [ -z "$got" ]; then add engines WARN "none installed (offline?) — install manually"; else add engines OK "installed:$got"; fi
348
+ }
349
+
350
+ # ── 3a2. the Pi agent + local models ────────────────────────────────────────
351
+ # Ensure pi and the Pi packages Ymir needs (pi-mcp-adapter, pi-web-access,
352
+ # pi-lmstudio — Pi has no native MCP/web/local-model support), detect the LOCAL
353
+ # model runtimes actually here (never assume llama.cpp), and seed
354
+ # ~/.pi/agent/models.json only when the operator has none.
355
+ step_models() {
356
+ [ "$SKIP_ENGINES" = 1 ] && { add models SKIP "--skip-engines"; return; }
357
+ if [ "$CHECK" = 1 ]; then add models OK "would ensure pi + packages and detect local models"; return; fi
358
+ if [ -x "$SCRIPT_DIR/pi-ensure.sh" ]; then
359
+ if "$SCRIPT_DIR/pi-ensure.sh" ensure --install >/dev/null 2>&1; then add models OK "pi + packages present";
360
+ else add models WARN "pi or a Pi package missing — run bin/pi-ensure.sh install"; fi
361
+ else
362
+ add models SKIP "no pi-ensure.sh"
363
+ fi
364
+ if [ -x "$SCRIPT_DIR/models-detect.sh" ]; then
365
+ local detected
366
+ detected="$("$SCRIPT_DIR/models-detect.sh" --json 2>/dev/null | python3 -c 'import json,sys;print(",".join(json.load(sys.stdin).get("providers",{}).keys()))' 2>/dev/null)"
367
+ add models OK "local runtimes: ${detected:-none}"
368
+ if [ ! -f "$HOME/.pi/agent/models.json" ]; then
369
+ "$SCRIPT_DIR/models-detect.sh" --write >/dev/null 2>&1 && add models OK "seeded ~/.pi/agent/models.json (was absent)"
370
+ fi
371
+ fi
372
+ if [ -x "$SCRIPT_DIR/model-hardware.sh" ]; then
373
+ "$SCRIPT_DIR/model-hardware.sh" >/dev/null 2>&1 && add models OK "profiled this machine (data/local-models.md; online research left for Brokk)"
374
+ fi
375
+ }
376
+
377
+ # ── 3b. hermes runtime ───────────────────────────────────────────────────────
378
+ step_hermes() {
379
+ [ "$SKIP_ENGINES" = 1 ] && { add hermes SKIP "--skip-engines"; return; }
380
+ if [ -x "$SCRIPT_DIR/hermes-ensure.sh" ]; then
381
+ if [ "$CHECK" = 1 ]; then
382
+ if "$SCRIPT_DIR/hermes-ensure.sh" status >/dev/null 2>&1; then add hermes OK "present"; else add hermes WARN "absent"; fi
383
+ else
384
+ if "$SCRIPT_DIR/hermes-ensure.sh" ensure --install >/dev/null 2>&1; then add hermes OK "present"; else add hermes WARN "not installed (run bin/hermes-ensure.sh install)"; fi
385
+ fi
386
+ else add hermes SKIP "no hermes-ensure.sh"; fi
387
+ }
388
+
389
+ # ── 3b2. Sessrúmnir desktop GUI ──────────────────────────────────────────────
390
+ # The seat-hall: a vendored, re-themed fork of pi-desktop (Apache-2.0) at
391
+ # apps/sessrumnir. Deps are never committed; the ensure step installs them on
392
+ # first run, exactly as scripts/electron.sh does for the other desktop apps.
393
+ step_sessrumnir() {
394
+ [ "$SKIP_ENGINES" = 1 ] && { add sessrumnir SKIP "--skip-engines"; return; }
395
+ if [ -x "$SCRIPT_DIR/sessrumnir-ensure.sh" ]; then
396
+ if [ "$CHECK" = 1 ]; then
397
+ if "$SCRIPT_DIR/sessrumnir-ensure.sh" status >/dev/null 2>&1; then add sessrumnir OK "ready"; else add sessrumnir WARN "not ready (run bin/sessrumnir-ensure.sh install)"; fi
398
+ else
399
+ if "$SCRIPT_DIR/sessrumnir-ensure.sh" ensure --install >/dev/null 2>&1; then add sessrumnir OK "ready"; else add sessrumnir WARN "not ready — run bin/sessrumnir-ensure.sh install"; fi
400
+ fi
401
+ else add sessrumnir SKIP "no sessrumnir-ensure.sh"; fi
402
+ }
403
+
404
+ # ── 3c. Þjazi backend (herdr-first) ──────────────────────────────────────────
405
+ # Ymir spawns agents into terminal panes, so a backend must exist. herdr is
406
+ # preferred (protocol 14+, presentation spaces at 0.8.0+); tmux is an accepted
407
+ # reference backend. Never a silent fallback — a missing backend is reported.
408
+ step_backend() {
409
+ if [ ! -x "$SCRIPT_DIR/herdr-ensure.sh" ]; then add backend SKIP "no herdr-ensure.sh"; return; fi
410
+ if [ "$CHECK" = 1 ]; then
411
+ if out="$("$SCRIPT_DIR/herdr-ensure.sh" status 2>&1)"; then
412
+ local b; b="$(printf '%s' "$out" | grep -oE '"(herdr|tmux|none)"' | head -1 | tr -d '"')"
413
+ add backend OK "$b"
414
+ else
415
+ add backend WARN "no terminal backend (install herdr or tmux)"
416
+ fi
417
+ else
418
+ if "$SCRIPT_DIR/herdr-ensure.sh" ensure --install >/dev/null 2>&1; then
419
+ local b; b="$( "$SCRIPT_DIR/herdr-ensure.sh" status 2>&1 | grep -oE '"(herdr|tmux|none)"' | head -1 | tr -d '"' )"
420
+ add backend OK "$b"
421
+ else
422
+ add backend WARN "no terminal backend — install herdr or tmux"
423
+ fi
424
+ fi
425
+ }
426
+
427
+ # ── 3d. host integration ─────────────────────────────────────────────────
428
+ # Learn the machine and place the desktop apps on EVERY host; the Omarchy-specific
429
+ # extras (the post-update hook) apply only when Omarchy is present. A non-Omarchy
430
+ # host still gets host learning and desktop placement — this is not a bonus for
431
+ # Omarchy, it is part of a normal install.
432
+ # ── 3b. the Omarchy installation layer (Rule 05) ─────────────────────────────
433
+ # Ymir is Omarchy-first: the desktop integration is a LAYER beside the portable
434
+ # core, and it owns its own installer. The core calls it here and reports one
435
+ # line; everything inside is the layer's business.
436
+ step_omarchy() {
437
+ if [ ! -x "$SCRIPT_DIR/omarchy-install.sh" ]; then add omarchy SKIP "no omarchy-install.sh"; return 0; fi
438
+ if [ "$CHECK" = 1 ]; then
439
+ "$SCRIPT_DIR/omarchy-install.sh" --check >/dev/null 2>&1
440
+ else
441
+ "$SCRIPT_DIR/omarchy-install.sh" >/dev/null 2>&1
442
+ fi
443
+ rc=$?
444
+ if [ "$rc" = 0 ]; then
445
+ if [ -d /usr/share/omarchy ]; then add omarchy OK "layer applied (sense · hook · plugins · desktops · editor · alarm · backend)"
446
+ else add omarchy SKIP "not an Omarchy host — the core runs without this layer"; fi
447
+ else
448
+ add omarchy WARN "layer reported a failing step — run bin/omarchy-install.sh to see which"
449
+ fi
450
+ }
451
+
452
+ step_host() {
453
+ # Core host learning: sense THIS machine on EVERY host with the portable
454
+ # sensor (Rule 05). The Omarchy-specific RECORDING (omarchy-sense observe), the
455
+ # post-update hook, desktop placement, the plugin offer, and the desktop alarm
456
+ # channel belong to the Omarchy layer and are applied by step_omarchy; nothing
457
+ # here assumes Omarchy.
458
+ local seen="unknown"
459
+ if [ -x "$SCRIPT_DIR/host-sense.sh" ]; then
460
+ # host-sense TOON row 2 is: os, id, family, session, desktop
461
+ local row; row="$("$SCRIPT_DIR/host-sense.sh" 2>/dev/null | sed -n '2p')"
462
+ [ -n "$row" ] && seen="$(printf '%s' "$row" | sed -E 's/^[[:space:]]*"//; s/"[[:space:]]*$//; s/","/ \/ /g')"
463
+ fi
464
+ add host OK "host sensed: ${seen}"
465
+
466
+ # The operator's own agent setup, seeded from the tracked template into the
467
+ # home's settings dir — settings are the operator's, never the package's.
468
+ # Idempotent: the seeded file is private and is never overwritten once set.
469
+ # --check writes nothing, so it only reports. The template is code, so it is
470
+ # read from wherever the tree keeps it: `config/` in a clone (a symlink the
471
+ # npm tarball cannot carry), else `.agents/config/`.
472
+ if [ -e "$YMIR_SETTINGS_DIR/agents.yaml" ]; then
473
+ add agents-config OK "kept (private, never overwritten)"
474
+ return 0
475
+ fi
476
+ local tpl="$ROOT/config/agents.yaml.example"
477
+ [ -r "$tpl" ] || tpl="$ROOT/.agents/config/agents.yaml.example"
478
+ if [ "$CHECK" = 1 ]; then
479
+ add agents-config WARN "not seeded yet — a real run writes $YMIR_SETTINGS_DIR/agents.yaml"
480
+ elif [ -r "$tpl" ] && mkdir -p "$YMIR_SETTINGS_DIR" && cp "$tpl" "$YMIR_SETTINGS_DIR/agents.yaml" 2>/dev/null; then
481
+ add agents-config OK "seeded $YMIR_SETTINGS_DIR/agents.yaml from the template"
482
+ else
483
+ add agents-config WARN "could not seed $YMIR_SETTINGS_DIR/agents.yaml"
484
+ fi
485
+ }
486
+
487
+ # ── 4. sandbox image ─────────────────────────────────────────────────────────
488
+ step_sandbox() {
489
+ local engine; engine="$(ymir_container_engine_name 2>/dev/null || true)"
490
+ if [ -z "$engine" ]; then add sandbox SKIP "no container engine (docker/podman)"; return; fi
491
+ if "$engine" image inspect utgard-runner:latest >/dev/null 2>&1; then
492
+ add sandbox OK "utgard-runner:latest present ($engine)"
493
+ elif [ "$CHECK" = 1 ]; then
494
+ add sandbox WARN "utgard-runner:latest missing (run without --check)"
495
+ else
496
+ # Distinguish "engine not reachable" from "build failed" so the operator gets
497
+ # an actionable message instead of a blanket failure.
498
+ if ! "$engine" info >/dev/null 2>&1; then
499
+ local who; who="$(id -un)"
500
+ if ymir_engine_is_podman 2>/dev/null; then
501
+ add sandbox WARN "rootless podman unreachable — ensure a login session (loginctl enable-linger) and XDG_RUNTIME_DIR are set"
502
+ elif id -nG "$who" 2>/dev/null | grep -qw docker; then
503
+ add sandbox WARN "docker daemon unreachable — log out and back in so the docker group applies"
504
+ else
505
+ add sandbox WARN "docker permission denied — add $who to the docker group, then re-login"
506
+ fi
507
+ return
508
+ fi
509
+ if "$SCRIPT_DIR/utgard.sh" build >/dev/null 2>&1; then add sandbox OK "utgard-runner:latest built ($engine)"; else add sandbox WARN "image build failed (see $engine)"; fi
510
+ fi
511
+ }
512
+
513
+ # ── 5. memory (well + harness MCP) ───────────────────────────────────────────
514
+ step_memory() {
515
+ local db="$YMIR_HOME/memory/kaia.engram" mcp=0
516
+ [ "$CHECK" = 0 ] && "$SCRIPT_DIR/mimir-bridge.sh" --start >/dev/null 2>&1 || true
517
+ for f in "$ROOT/opencode.json" "$HOME/.config/opencode/opencode.json" "$HOME/.pi/agent/settings.json" "$HOME/.claude.json" "$HOME/.cursor/mcp.json"; do
518
+ [ -f "$f" ] && grep -q '"engram"' "$f" 2>/dev/null && mcp=$((mcp+1))
519
+ done
520
+ local store="absent"; [ -f "$db" ] && store="present"
521
+ add memory OK "engram store $store · MCP in $mcp harness configs"
522
+ }
523
+
524
+ # ── 5b. smidja db (visualizer readiness) ─────────────────────────────
525
+ step_smidja() {
526
+ if [ -x "$SCRIPT_DIR/smidja-bootstrap.sh" ]; then
527
+ if [ "$CHECK" = 1 ]; then
528
+ local dbok vizok
529
+ [ -f "$YMIR_HOME/smidja/smidja.db" ] && dbok=present || dbok=missing
530
+ [ -d "$ROOT/.agents/skills/smidja-factory/apps/visualizer/dist" ] && vizok=built || vizok=unbuilt
531
+ if [ "$dbok" = missing ]; then
532
+ add smidja WARN "smidja.db missing — a full run (without --check) creates it and seeds one bootstrap session"
533
+ else
534
+ add smidja OK "smidja.db $dbok · visualizer UI $vizok"
535
+ fi
536
+ elif ! have uv; then
537
+ # The bootstrap creates the schema through the tracer, run under uv so the
538
+ # smidja deps resolve without a system install.
539
+ add smidja WARN "needs uv — bin/prereq-ensure.sh uv (the visualizer stays empty without it)"
540
+ else
541
+ if "$SCRIPT_DIR/smidja-bootstrap.sh" >/dev/null 2>&1; then add smidja OK "smidja.db ready (visualizer has data)"; else add smidja WARN "could not bootstrap smidja.db — run bin/smidja-bootstrap.sh to see why"; fi
542
+ fi
543
+ else add smidja SKIP "no smidja-bootstrap.sh"; fi
544
+ # The visualizer API serves its UI from ./dist — without a build it answers
545
+ # the API but shows "No ./dist build found". Build it once when absent.
546
+ local viz="$ROOT/.agents/skills/smidja-factory/apps/visualizer"
547
+ [ -d "$viz" ] || return 0
548
+ if [ -d "$viz/dist" ]; then
549
+ add visualizer OK "UI built (served on :8437)"
550
+ elif [ "$CHECK" = 1 ]; then
551
+ add visualizer WARN "UI not built (run without --check)"
552
+ elif command -v bun >/dev/null 2>&1; then
553
+ if [ ! -d "$viz/node_modules" ] && ! (cd "$viz" && bun install >/dev/null 2>&1); then
554
+ add visualizer WARN "bun install failed — (cd $viz && bun install)"
555
+ elif (cd "$viz" && bun run build >/dev/null 2>&1); then
556
+ add visualizer OK "UI built (served on :8437)"
557
+ else
558
+ add visualizer WARN "UI build failed — (cd $viz && bun run build)"
559
+ fi
560
+ else
561
+ add visualizer WARN "no bun — cannot build the visualizer UI"
562
+ fi
563
+ }
564
+
565
+ # ── 5c. the SPA ──────────────────────────────────────────────────────────────
566
+ # Hlidskjalf installs with npm (its own lockfile), not bun, and its API serves the
567
+ # UI from ./dist. Without this step a fresh clone has no SPA and no build.
568
+ step_spa() {
569
+ local app="$ROOT/apps/hlidskjalf"
570
+ [ -d "$app" ] || { add hlidskjalf SKIP "no apps/hlidskjalf"; return 0; }
571
+ if [ "$CHECK" = 0 ]; then
572
+ if ! have npm; then
573
+ add hlidskjalf WARN "no npm — cannot install the SPA"; return 0
574
+ fi
575
+ if [ ! -d "$app/node_modules" ] && ! (cd "$app" && npm install --no-audit --no-fund >/dev/null 2>&1); then
576
+ add hlidskjalf WARN "npm install failed — (cd $app && npm install --no-audit --no-fund)"; return 0
577
+ fi
578
+ if [ ! -d "$app/dist" ] && ! (cd "$app" && npm run build >/dev/null 2>&1); then
579
+ add hlidskjalf WARN "installed, build failed — (cd $app && npm run build)"; return 0
580
+ fi
581
+ fi
582
+ if [ ! -d "$app/node_modules" ] || [ ! -d "$app/dist" ]; then
583
+ add hlidskjalf WARN "not installed (run without --check)"; return 0
584
+ fi
585
+ # Electron's runtime comes from a gated postinstall. package.json pins the
586
+ # approval, but verify the binary so the desktop shell never fails silently.
587
+ if [ -x "$app/node_modules/electron/dist/electron" ] || [ ! -d "$app/electron" ]; then
588
+ add hlidskjalf OK "installed + built + electron (served on :3888)"
589
+ else
590
+ add hlidskjalf WARN "installed + built, but electron has no binary — npm rebuild electron"
591
+ fi
592
+ }
593
+
594
+ # ── 6. loaders ───────────────────────────────────────────────────────────────
595
+ step_loaders() {
596
+ if [ -x "$SCRIPT_DIR/valknut-load.sh" ]; then
597
+ if [ "$CHECK" = 1 ]; then add loaders OK "valknut-load.sh present"; else
598
+ "$SCRIPT_DIR/valknut-load.sh" >/dev/null 2>&1 && add loaders OK "agents/skills loaded" || add loaders WARN "loader reported errors"
599
+ fi
600
+ else add loaders SKIP "no valknut-load.sh"; fi
601
+ }
602
+
603
+ # ── 6b. delivery gates (git hooks) ───────────────────────────────────────────
604
+ #
605
+ # Rule 08: work leaves by PR, and every push carries a CHANGELOG entry. The
606
+ # guards live in bin/ (branch-guard, changelog-guard, secret-guard) but git
607
+ # only reads .git/hooks, so the install seats them there — the gate is live
608
+ # from the first commit of a fresh clone. Idempotent: each --install rewrites
609
+ # its own hook.
610
+ step_gates() {
611
+ local hooks="$ROOT/.git/hooks" pre_commit="$ROOT/.git/hooks/pre-commit" pre_push="$ROOT/.git/hooks/pre-push"
612
+ if [ ! -d "$hooks" ]; then add gates SKIP "not a git checkout"; return; fi
613
+ if [ "$CHECK" = 1 ]; then
614
+ if [ -x "$pre_commit" ] && [ -x "$pre_push" ]; then
615
+ add gates OK "pre-commit + pre-push installed"
616
+ else
617
+ add gates WARN "hooks not installed — bin/secret-guard.sh --install && bin/changelog-guard.sh --install"
618
+ fi
619
+ # The home repo is where the private data lives, so its ward matters more
620
+ # than this repo's four. Report it separately so a dormant vault is visible.
621
+ local hh; hh="${YMIR_HOME:-$HOME/Documents/Ymir}/.git/hooks/pre-commit"
622
+ if [ -x "$hh" ]; then add hoard-gate OK "home pre-commit seated";
623
+ else add hoard-gate WARN "home hooks not installed — bin/hoard-guard.sh --install"; fi
624
+ return
625
+ fi
626
+ [ -x "$SCRIPT_DIR/secret-guard.sh" ] && "$SCRIPT_DIR/secret-guard.sh" --install >/dev/null 2>&1 || true
627
+ [ -x "$SCRIPT_DIR/changelog-guard.sh" ] && "$SCRIPT_DIR/changelog-guard.sh" --install >/dev/null 2>&1 || true
628
+ # Seat the ward on the PRIVATE home too — every install layer, every machine.
629
+ [ -x "$SCRIPT_DIR/hoard-guard.sh" ] && "$SCRIPT_DIR/hoard-guard.sh" --install >/dev/null 2>&1 || true
630
+ if [ -x "$pre_commit" ] && [ -x "$pre_push" ]; then add gates OK "pre-commit + pre-push installed"
631
+ else add gates WARN "could not write .git/hooks — gates are dormant"; fi
632
+ local hh; hh="${YMIR_HOME:-$HOME/Documents/Ymir}/.git/hooks/pre-commit"
633
+ if [ -x "$hh" ]; then add hoard-gate OK "home pre-commit seated";
634
+ else add hoard-gate WARN "home hooks not seated — bin/hoard-guard.sh --install"; fi
635
+ }
636
+
637
+ # ── 6c. desktop marks (the rune, the entry, the contract) ────────────────────
638
+ #
639
+ # Every app wears its OWN rune in the operator's desktop: the icon into the icon
640
+ # theme, the .desktop entry into their applications dir (so every app is
641
+ # dockable and pinnable), and the Ymir contract deployed into pi's agent home so
642
+ # every session - in ANY folder - loads Brokk. Idempotent, and it writes to the
643
+ # operator's real data dir, never a sandbox one.
644
+ step_marks() {
645
+ if [ ! -x "$SCRIPT_DIR/design-icon.sh" ]; then add marks SKIP "no design-icon.sh"; return; fi
646
+ if [ "$CHECK" = 1 ]; then
647
+ n=$(ls "$HOME/.local/share"/applications/ymir-*.desktop 2>/dev/null | wc -l | tr -d ' ')
648
+ add marks OK "$n desktop app marks installed"
649
+ return
650
+ fi
651
+ "$SCRIPT_DIR/design-icon.sh" mint --all >/dev/null 2>&1 || true
652
+ n=$("$SCRIPT_DIR/design-icon.sh" install 2>/dev/null | grep -c '"ymir-') || n=0
653
+ [ -r "$HOME/.pi/agent/AGENTS.md" ] || [ -d "$HOME/.pi/agent" ] && {
654
+ ln -sfn "$ROOT/AGENTS.md" "$HOME/.pi/agent/AGENTS.md" 2>/dev/null || true
655
+ }
656
+ add marks OK "$n app marks (rune icon + entry) · Ymir contract in the pi agent home"
657
+ }
658
+
659
+ # ── 7. services ──────────────────────────────────────────────────────────────
660
+ step_services() {
661
+ [ "$SKIP_SERVICES" = 1 ] && { add services SKIP "--skip-services"; return; }
662
+ if [ "$CHECK" = 1 ]; then
663
+ local up=0
664
+ for p in 3888 3889 4602 4603; do (exec 3<>"/dev/tcp/127.0.0.1/$p") 2>/dev/null && up=$((up+1)); done
665
+ add services OK "$up/4 ports up (3888/3889/4602/4603)"; return
666
+ fi
667
+ if "$ROOT/scripts/start.sh" >/dev/null 2>&1; then add services OK "runtime raised"; else add services WARN "start.sh reported errors"; fi
668
+ }
669
+
670
+ # ── 7b. desktop (both Electron apps) ──────────────────────────
671
+ # The operator should SEE the applications when the install finishes, so we
672
+ # raise both desktop shells (Hlidskjalf + Smíðja) as separate processes.
673
+ step_desktop() {
674
+ if [ "$NO_DESKTOP" = 1 ]; then add desktop SKIP "--no-desktop"; return; fi
675
+ if [ ! -x "$ROOT/scripts/electron.sh" ]; then add desktop SKIP "no scripts/electron.sh"; return; fi
676
+ if [ "$CHECK" = 1 ]; then add desktop OK "would launch Hlidskjalf + Smíðja"; return; fi
677
+ # A headless host has no display; launching a window would only fail.
678
+ # DISPLAY/WAYLAND_DISPLAY are X11/Wayland variables — macOS has a display and
679
+ # neither of them, so testing only those would wrongly skip every Mac.
680
+ if [ -z "${DISPLAY:-}${WAYLAND_DISPLAY:-}" ] && [ "$(ymir_os)" != macos ]; then
681
+ add desktop SKIP "no display (headless) — run scripts/electron.sh start --both"; return
682
+ fi
683
+ # Placement is the Omarchy layer's job and has already run (step_omarchy runs
684
+ # before this step), so here we only launch.
685
+ if "$ROOT/scripts/electron.sh" start --both >/dev/null 2>&1; then
686
+ add desktop OK "raised Hlidskjalf + Smíðja"
687
+ else
688
+ add desktop WARN "could not raise the desktop apps — run scripts/electron.sh start --both"
689
+ fi
690
+ }
691
+
692
+ # ── 8. register ──────────────────────────────────────────────────────────────
693
+ # ── 8b. the way in ────────────────────────────────
694
+ # One operator owns the instance; an invite code is how someone *else* is let in
695
+ # to try it. Registration stays closed until a live code exists, so the gate is
696
+ # never open by accident.
697
+ step_invite() {
698
+ if [ "$CHECK" = 1 ]; then add invite OK "would mint an invite code"; return; fi
699
+ if [ ! -x "$ROOT/bin/ymir-invite.sh" ]; then add invite SKIP "bin/ymir-invite.sh not executable"; return; fi
700
+ if ! command -v bun >/dev/null 2>&1; then add invite SKIP "bun missing — no account store"; return; fi
701
+ local out
702
+ if ! out=$(bash "$ROOT/bin/ymir-invite.sh" ensure 2>&1); then add invite WARN "could not mint a code"; return; fi
703
+ INVITE_CODE=$(printf '%s\n' "$out" | sed -n '2p' | tr -d ' "' | cut -d, -f1)
704
+ if [ -n "$INVITE_CODE" ]; then add invite OK "invite ${INVITE_CODE} — share it to let someone register"; else add invite WARN "no code found"; fi
705
+ }
706
+
707
+ # ── 8a. the operator's way in ────────────────────────────────────────────────
708
+ # The gate has two doors — a local password (HLIDSKJALF_AUTH) or GitHub sign-in
709
+ # (a GitHub OAuth app). Neither is seeded by a checkout, so a fresh instance has
710
+ # no way in until the operator sets one. Interactive installs prompt; --yes and
711
+ # non-tty leave it to bin/ymir-setup-auth.sh.
712
+ step_auth() {
713
+ if [ ! -x "$ROOT/bin/ymir-setup-auth.sh" ]; then add auth SKIP "bin/ymir-setup-auth.sh not executable"; return; fi
714
+ local door
715
+ door=$(bash "$ROOT/bin/ymir-setup-auth.sh" status 2>/dev/null | sed -n '2p' | cut -d, -f1 | tr -d ' "')
716
+ if [ -n "$door" ] && [ "$door" != none ]; then add auth OK "operator credential present ($door)"; return; fi
717
+ if [ "$CHECK" = 1 ]; then add auth WARN "no operator credential — run bin/ymir-setup-auth.sh set|github"; return; fi
718
+ if [ "$ASSUME_YES" = 1 ] || [ ! -t 0 ]; then
719
+ add auth WARN "no operator credential — set one: bin/ymir-setup-auth.sh set (or github)"
720
+ return
721
+ fi
722
+ printf '\nSet the operator credential now? [p]assword / [g]ithub / [s]kip: '
723
+ local choice; IFS= read -r choice || true
724
+ case "${choice:-s}" in
725
+ p|P) bash "$ROOT/bin/ymir-setup-auth.sh" set && add auth OK "operator password set" || add auth WARN "password setup failed" ;;
726
+ g|G) bash "$ROOT/bin/ymir-setup-auth.sh" github && add auth OK "GitHub sign-in configured" || add auth WARN "GitHub setup failed" ;;
727
+ *) add auth SKIP "left unset — run bin/ymir-setup-auth.sh set|github later" ;;
728
+ esac
729
+ }
730
+
731
+ step_register() {
732
+ if [ "$CHECK" = 1 ]; then add register OK "would write workspace/INSTALL.md"; return; fi
733
+ local out="$WORKSPACE/INSTALL.md"
734
+ {
735
+ printf '# Ymir — first setup\n\n'
736
+ printf 'Provisioned by `bin/ymir-install.sh` at %s.\n\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
737
+ printf '## Workspaces\n\n'; printf -- '- personal\n\n'
738
+ printf '## Engines\n\n- Yggdrasil → treehouse\n- Utgard → sandcastle\n- Mjollnir/Glitnir → no-mistakes\n- Hermes → hermes-agent (worker runtime)\n- Sessrúmnir → pi-desktop (desktop GUI, vendored at apps/sessrumnir)\n\n'
739
+ printf '## Next\n\n1. `gh auth login` (your own GitHub login).\n'
740
+ printf '2. Register your projects and their `git{}` blocks in `hoard/identity/projects.yaml`.\n'
741
+ printf '3. `scripts/start.sh` then open http://127.0.0.1:3888/.\n'
742
+ printf '4. To let someone else try it, share the invite code printed above\n'
743
+ printf ' (or mint another: `bin/ymir-invite.sh mint <n>`). They register at the\n'
744
+ printf ' login screen; `bin/ymir-invite.sh list` shows what is spent.\n'
745
+ } >"$out"
746
+ add register OK "wrote workspace/INSTALL.md"
747
+ }
748
+
749
+ # ── 9. validate ───────────────────────────────────
750
+ # Prove the installation actually works: live ports, readable stores, running
751
+ # processes. The installer says what it did; this observes the result.
752
+ step_validate() {
753
+ if [ ! -x "$SCRIPT_DIR/ymir-validate.sh" ]; then add validate SKIP "no ymir-validate.sh"; return; fi
754
+ if [ "$CHECK" = 1 ]; then add validate OK "would verify the running system"; return; fi
755
+ if out="$("$SCRIPT_DIR/ymir-validate.sh" --quiet 2>&1)"; then
756
+ add validate OK "all required checks pass"
757
+ else
758
+ local nf; nf="$(printf '%s' "$out" | grep -oE '[0-9]+ required check\(s\) failed' | head -1)"
759
+ add validate WARN "${nf:-some checks} failed — run bin/ymir-validate.sh for detail"
760
+ fi
761
+ }
762
+
763
+ # ── 0. herdr panes (visible when inside herdr) ──────────────
764
+ # When the Allfather sits within herdr, the install should be SEEN: a pane is
765
+ # raised for the run and the steps are executed within it. Outside herdr this is
766
+ # a clean fall-through — the same steps, no panes. Nothing here can lose work:
767
+ # if a pane cannot be made, the caller runs its command inline.
768
+ step_panes() {
769
+ local runner="$SCRIPT_DIR/herdr-run.sh"
770
+ if [ ! -x "$runner" ]; then add panes SKIP "no herdr-run.sh"; return; fi
771
+ if ! "$runner" available >/dev/null 2>&1; then
772
+ add panes SKIP "no herdr session — steps run inline"
773
+ return
774
+ fi
775
+ if [ "$CHECK" = 1 ]; then
776
+ add panes OK "herdr present — steps would run in visible panes"
777
+ return
778
+ fi
779
+ # Keep the panes the run makes, so the Allfather can read them afterwards.
780
+ YMIR_HERDR_KEEP=1 "$runner" run "install" -- bash -c \
781
+ 'echo "Ymir first setup begins $(date -u +%H:%M:%SZ)"; echo "the steps follow in this pane"; echo "repo: $PWD"' \
782
+ >/dev/null 2>&1 && add panes OK "run shown in a herdr pane" || add panes WARN "could not raise a herdr pane"
783
+ }
784
+
785
+ # Ask before touching the machine; --check only previews and never asks.
786
+ [ "$CHECK" = 0 ] && confirm_install
787
+
788
+ step_panes; step_prereqs; step_home; step_tree; step_apps; step_engines; step_models; step_hermes; step_sessrumnir; step_backend; step_host; step_sandbox; step_memory; step_smidja; step_spa; step_omarchy; step_loaders; step_gates; step_marks
789
+ # Migrations MOVE private data — that is a write, and `--check` promises none.
790
+ # Only a real run heals the home forward; the preview leaves it untouched.
791
+ if [ "$CHECK" = 0 ]; then bin/ymir-migrate.sh apply >/dev/null 2>&1 || true; fi
792
+ step_auth; step_invite; step_register
793
+ [ "$CHECK" = 0 ] && step_services
794
+ [ "$CHECK" = 0 ] && step_desktop
795
+ [ "$CHECK" = 0 ] && step_validate
796
+
797
+ # The panes were raised for the Allfather to read; leave them standing when we
798
+ # made them, and close them only when the operator asks (herdr-run close-all).
799
+
800
+ printf 'install[%d]{step,status,detail}:\n' "${#IDS[@]}"
801
+ for i in "${!IDS[@]}"; do printf ' "%s","%s","%s"\n' "${IDS[$i]}" "${STATUS[$i]}" "${DETAIL[$i]}"; done
802
+ printf '\nnext: gh auth login · register your projects in hoard/identity/projects.yaml · open http://127.0.0.1:3888/\n'
803
+ [ -n "$INVITE_CODE" ] && printf 'invite: %s — share it to let someone register (bin/ymir-invite.sh list shows what is spent)\n' "$INVITE_CODE"
804
+
805
+ for s in "${STATUS[@]}"; do [ "$s" = FAIL ] && exit 1; done
806
+ exit 0