@zerwiz/ymir 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (850) hide show
  1. package/.agents/README.md +291 -0
  2. package/.agents/agents/bragi-marketer.md +111 -0
  3. package/.agents/agents/brokk.md +352 -0
  4. package/.agents/agents/forseti-reviewer.md +93 -0
  5. package/.agents/agents/frigg-consent.md +77 -0
  6. package/.agents/agents/groa-update.md +77 -0
  7. package/.agents/agents/hnoss-designer.md +69 -0
  8. package/.agents/agents/huginn-researcher.md +99 -0
  9. package/.agents/agents/jord-projects.md +78 -0
  10. package/.agents/agents/kvasir-scout.md +91 -0
  11. package/.agents/agents/mimir-planner.md +92 -0
  12. package/.agents/agents/muninn-stow.md +77 -0
  13. package/.agents/agents/saga-bearings.md +78 -0
  14. package/.agents/agents/sindri-developer.md +114 -0
  15. package/.agents/agents/snotra-documenter.md +105 -0
  16. package/.agents/agents/syn-recovery.md +78 -0
  17. package/.agents/agents/tyr-check.md +78 -0
  18. package/.agents/agents/urdh-hold.md +77 -0
  19. package/.agents/agents/volundr-smith.md +80 -0
  20. package/.agents/agents/vor-diagnostics.md +77 -0
  21. package/.agents/assets/agents/naming.md +50 -0
  22. package/.agents/assets/agents/registry.md +93 -0
  23. package/.agents/assets/agents/runtime.md +36 -0
  24. package/.agents/assets/agents/toon-tasks-cli.md +42 -0
  25. package/.agents/assets/templates/company_entity.template.md +37 -0
  26. package/.agents/backend/backends/cmux.sh +649 -0
  27. package/.agents/backend/backends/herdr-eventwait.py +157 -0
  28. package/.agents/backend/backends/herdr-workspace-move.py +114 -0
  29. package/.agents/backend/backends/herdr.sh +3386 -0
  30. package/.agents/backend/backends/orca.sh +290 -0
  31. package/.agents/backend/backends/tmux.sh +357 -0
  32. package/.agents/backend/backends/zellij.sh +700 -0
  33. package/.agents/backend/fm-afk-launch.sh +654 -0
  34. package/.agents/backend/fm-afk-return.sh +241 -0
  35. package/.agents/backend/fm-afk-start.sh +172 -0
  36. package/.agents/backend/fm-arm-command-policy.mjs +960 -0
  37. package/.agents/backend/fm-arm-pretool-check.sh +200 -0
  38. package/.agents/backend/fm-backend-hometag-lib.sh +52 -0
  39. package/.agents/backend/fm-backend.sh +981 -0
  40. package/.agents/backend/fm-backlog-handoff.sh +909 -0
  41. package/.agents/backend/fm-backlog-receive.sh +187 -0
  42. package/.agents/backend/fm-backlog-transition-lib.sh +779 -0
  43. package/.agents/backend/fm-bearings-board.sh +204 -0
  44. package/.agents/backend/fm-bearings-snapshot.sh +546 -0
  45. package/.agents/backend/fm-bootstrap.sh +1568 -0
  46. package/.agents/backend/fm-branch-outcome.sh +203 -0
  47. package/.agents/backend/fm-branch-prompt.sh +101 -0
  48. package/.agents/backend/fm-brief.sh +452 -0
  49. package/.agents/backend/fm-busy-event.sh +234 -0
  50. package/.agents/backend/fm-busy-lib.sh +986 -0
  51. package/.agents/backend/fm-captain-hold.sh +1001 -0
  52. package/.agents/backend/fm-cd-command-policy.mjs +153 -0
  53. package/.agents/backend/fm-cd-pretool-check.sh +190 -0
  54. package/.agents/backend/fm-check-lib.sh +74 -0
  55. package/.agents/backend/fm-check-register.sh +42 -0
  56. package/.agents/backend/fm-check-unregister.sh +52 -0
  57. package/.agents/backend/fm-classify-lib.sh +1770 -0
  58. package/.agents/backend/fm-claude-stop-autoarm.sh +334 -0
  59. package/.agents/backend/fm-composer-lib.sh +1416 -0
  60. package/.agents/backend/fm-config-inherit-lib.sh +1202 -0
  61. package/.agents/backend/fm-config-push.sh +254 -0
  62. package/.agents/backend/fm-control-lib.sh +251 -0
  63. package/.agents/backend/fm-control.sh +878 -0
  64. package/.agents/backend/fm-crew-state.sh +625 -0
  65. package/.agents/backend/fm-cursor-lib.sh +243 -0
  66. package/.agents/backend/fm-decision-hold.sh +232 -0
  67. package/.agents/backend/fm-doc-audience-check.sh +269 -0
  68. package/.agents/backend/fm-dod-lib.sh +67 -0
  69. package/.agents/backend/fm-ensure-agents-md.sh +253 -0
  70. package/.agents/backend/fm-extension-launch-barrier.mjs +129 -0
  71. package/.agents/backend/fm-extension.mjs +2577 -0
  72. package/.agents/backend/fm-extension.sh +16 -0
  73. package/.agents/backend/fm-ff-lib.sh +420 -0
  74. package/.agents/backend/fm-fleet-snapshot.sh +1463 -0
  75. package/.agents/backend/fm-fleet-sync.sh +458 -0
  76. package/.agents/backend/fm-fleet-view.sh +96 -0
  77. package/.agents/backend/fm-gate-refuse-lib.sh +102 -0
  78. package/.agents/backend/fm-guard.sh +242 -0
  79. package/.agents/backend/fm-harness.sh +195 -0
  80. package/.agents/backend/fm-herdr-ci-cleanup.sh +115 -0
  81. package/.agents/backend/fm-herdr-lab.sh +346 -0
  82. package/.agents/backend/fm-herdr-session-cleanup.sh +337 -0
  83. package/.agents/backend/fm-home-seed.sh +984 -0
  84. package/.agents/backend/fm-home-summary-refresh.sh +255 -0
  85. package/.agents/backend/fm-hook-host-lib.sh +36 -0
  86. package/.agents/backend/fm-inactive-reconcile.sh +531 -0
  87. package/.agents/backend/fm-inbox.sh +399 -0
  88. package/.agents/backend/fm-install-actionlint.sh +84 -0
  89. package/.agents/backend/fm-install-herdr.sh +96 -0
  90. package/.agents/backend/fm-install-shellcheck.sh +84 -0
  91. package/.agents/backend/fm-install-treehouse.sh +95 -0
  92. package/.agents/backend/fm-kimi-turnend-hook.sh +276 -0
  93. package/.agents/backend/fm-lease-lib.sh +218 -0
  94. package/.agents/backend/fm-lease.sh +189 -0
  95. package/.agents/backend/fm-line-cap-lib.sh +51 -0
  96. package/.agents/backend/fm-lint-workflows.sh +137 -0
  97. package/.agents/backend/fm-lint.sh +591 -0
  98. package/.agents/backend/fm-lock-lib.sh +104 -0
  99. package/.agents/backend/fm-lock.sh +107 -0
  100. package/.agents/backend/fm-marker-lib.sh +12 -0
  101. package/.agents/backend/fm-merge-local.sh +74 -0
  102. package/.agents/backend/fm-merge-outcome-lib.sh +138 -0
  103. package/.agents/backend/fm-nm-run-lib.sh +124 -0
  104. package/.agents/backend/fm-on.sh +125 -0
  105. package/.agents/backend/fm-operational-input.sh +253 -0
  106. package/.agents/backend/fm-peek.sh +46 -0
  107. package/.agents/backend/fm-pending-reply-lib.sh +1409 -0
  108. package/.agents/backend/fm-pr-check.sh +135 -0
  109. package/.agents/backend/fm-pr-lib.sh +1016 -0
  110. package/.agents/backend/fm-pr-merge.sh +707 -0
  111. package/.agents/backend/fm-pr-poll.sh +110 -0
  112. package/.agents/backend/fm-primary-scope-lib.sh +33 -0
  113. package/.agents/backend/fm-procevent-extension-capture.pl +259 -0
  114. package/.agents/backend/fm-procevent-lavish.sh +628 -0
  115. package/.agents/backend/fm-procevent-lib.sh +892 -0
  116. package/.agents/backend/fm-procevent-quota.sh +290 -0
  117. package/.agents/backend/fm-procevent-remote-reply.sh +577 -0
  118. package/.agents/backend/fm-procevent-when.sh +504 -0
  119. package/.agents/backend/fm-procevent.sh +1466 -0
  120. package/.agents/backend/fm-project-mode.sh +92 -0
  121. package/.agents/backend/fm-project-origin-lib.sh +180 -0
  122. package/.agents/backend/fm-promote.sh +282 -0
  123. package/.agents/backend/fm-public-followup-emit.sh +260 -0
  124. package/.agents/backend/fm-public-followup-lib.sh +398 -0
  125. package/.agents/backend/fm-public-followup.sh +1330 -0
  126. package/.agents/backend/fm-push-transition-lib.sh +168 -0
  127. package/.agents/backend/fm-quota-axi-lib.sh +93 -0
  128. package/.agents/backend/fm-quota-choose.sh +384 -0
  129. package/.agents/backend/fm-remote-delta-read.sh +189 -0
  130. package/.agents/backend/fm-remote-doctor.sh +800 -0
  131. package/.agents/backend/fm-remote-entrypoint.sh +193 -0
  132. package/.agents/backend/fm-remote-file.sh +234 -0
  133. package/.agents/backend/fm-remote-home-provision.sh +259 -0
  134. package/.agents/backend/fm-remote-home-seed.sh +259 -0
  135. package/.agents/backend/fm-remote-inherit-push.sh +90 -0
  136. package/.agents/backend/fm-remote-inherit.sh +179 -0
  137. package/.agents/backend/fm-remote-job-lib.sh +1241 -0
  138. package/.agents/backend/fm-remote-job-reap-orphans.sh +137 -0
  139. package/.agents/backend/fm-remote-job-worker.sh +1124 -0
  140. package/.agents/backend/fm-remote-readiness-lib.sh +44 -0
  141. package/.agents/backend/fm-remote-secondmate-control.sh +340 -0
  142. package/.agents/backend/fm-review-diff.sh +158 -0
  143. package/.agents/backend/fm-secondmate-charter-lib.sh +44 -0
  144. package/.agents/backend/fm-secondmate-nudge-lib.sh +68 -0
  145. package/.agents/backend/fm-secondmate-parent-lib.sh +70 -0
  146. package/.agents/backend/fm-secondmate-reconcile.sh +371 -0
  147. package/.agents/backend/fm-secondmate-registry-lib.sh +311 -0
  148. package/.agents/backend/fm-secondmate-report.sh +88 -0
  149. package/.agents/backend/fm-send.sh +1059 -0
  150. package/.agents/backend/fm-session-lock-lib.sh +176 -0
  151. package/.agents/backend/fm-session-start.sh +970 -0
  152. package/.agents/backend/fm-sessionstart-cursor.sh +40 -0
  153. package/.agents/backend/fm-sessionstart-nudge.sh +45 -0
  154. package/.agents/backend/fm-sessionstart-run.sh +145 -0
  155. package/.agents/backend/fm-spawn.sh +3153 -0
  156. package/.agents/backend/fm-startup-memory-budget-lib.sh +224 -0
  157. package/.agents/backend/fm-startup-memory-budget.sh +94 -0
  158. package/.agents/backend/fm-startup-network.sh +642 -0
  159. package/.agents/backend/fm-stow-cascade.sh +251 -0
  160. package/.agents/backend/fm-subagent-pretool-check.sh +207 -0
  161. package/.agents/backend/fm-supervise-daemon.sh +1732 -0
  162. package/.agents/backend/fm-supervision-instructions.sh +215 -0
  163. package/.agents/backend/fm-supervision-lib.sh +90 -0
  164. package/.agents/backend/fm-supervisor-target-lib.sh +78 -0
  165. package/.agents/backend/fm-tangle-lib.sh +53 -0
  166. package/.agents/backend/fm-task-inbox-lib.sh +402 -0
  167. package/.agents/backend/fm-tasks-axi-lib.sh +123 -0
  168. package/.agents/backend/fm-teardown.sh +2922 -0
  169. package/.agents/backend/fm-test-isolation-proof.sh +588 -0
  170. package/.agents/backend/fm-test-run.sh +2191 -0
  171. package/.agents/backend/fm-timeout-lib.sh +141 -0
  172. package/.agents/backend/fm-timing-lib.sh +179 -0
  173. package/.agents/backend/fm-tmux-lib.sh +291 -0
  174. package/.agents/backend/fm-tool-update-check.sh +898 -0
  175. package/.agents/backend/fm-trace-context-lib.sh +227 -0
  176. package/.agents/backend/fm-transition-lib.sh +103 -0
  177. package/.agents/backend/fm-turnend-guard-cursor.sh +391 -0
  178. package/.agents/backend/fm-turnend-guard-grok.sh +90 -0
  179. package/.agents/backend/fm-turnend-guard.sh +432 -0
  180. package/.agents/backend/fm-update.sh +110 -0
  181. package/.agents/backend/fm-vendor-auth-probe.sh +190 -0
  182. package/.agents/backend/fm-voice-client.py +1373 -0
  183. package/.agents/backend/fm-voice-relay.py +1256 -0
  184. package/.agents/backend/fm-wake-drain.sh +592 -0
  185. package/.agents/backend/fm-wake-grant.sh +127 -0
  186. package/.agents/backend/fm-wake-lib.sh +1849 -0
  187. package/.agents/backend/fm-watch-arm.sh +602 -0
  188. package/.agents/backend/fm-watch-checkpoint.sh +109 -0
  189. package/.agents/backend/fm-watch.sh +1962 -0
  190. package/.agents/backend/fm-x-dismiss.sh +116 -0
  191. package/.agents/backend/fm-x-followup.sh +286 -0
  192. package/.agents/backend/fm-x-lib.sh +1000 -0
  193. package/.agents/backend/fm-x-link.sh +234 -0
  194. package/.agents/backend/fm-x-poll.sh +185 -0
  195. package/.agents/backend/fm-x-reply.sh +385 -0
  196. package/.agents/backend/fm_voice_frame.py +166 -0
  197. package/.agents/backend/fm_voice_records.py +574 -0
  198. package/.agents/backend/model-bridge.py +290 -0
  199. package/.agents/backend/opencode-go-bridge.py +30 -0
  200. package/.agents/bus/README.md +12 -0
  201. package/.agents/bus/messages.json +1 -0
  202. package/.agents/config/agents.machine.example.yaml +16 -0
  203. package/.agents/config/agents.yaml +50 -0
  204. package/.agents/config/agents.yaml.example +72 -0
  205. package/.agents/config/crew-dispatch.json +22 -0
  206. package/.agents/config/cron.yaml +9 -0
  207. package/.agents/config/eindri-dispatch.json +67 -0
  208. package/.agents/config/eindri-harness +1 -0
  209. package/.agents/config/startup-memory-budget +1 -0
  210. package/.agents/config/tailscale-sync.yaml +27 -0
  211. package/.agents/filebrowser/.filebrowser.json +6 -0
  212. package/.agents/filebrowser/README.md +11 -0
  213. package/.agents/gateway/README.md +12 -0
  214. package/.agents/github/README.md +15 -0
  215. package/.agents/github/webhooks/.gitkeep +0 -0
  216. package/.agents/github/workflows/.gitkeep +0 -0
  217. package/.agents/harness/opencode/plugins/lib/rodd-operational-input.js +37 -0
  218. package/.agents/harness/opencode/plugins/package.json +4 -0
  219. package/.agents/harness/opencode/plugins/saga-sessionstart.js +77 -0
  220. package/.agents/harness/opencode/plugins/syn-cd-check.js +61 -0
  221. package/.agents/harness/opencode/plugins/syn-pretool-check.js +68 -0
  222. package/.agents/harness/opencode/plugins/syn-turnend-guard.js +105 -0
  223. package/.agents/harness/opencode/plugins/syn-watch-arm.js +521 -0
  224. package/.agents/memory/README.md +46 -0
  225. package/.agents/memory/kaia.engram +0 -0
  226. package/.agents/memory/kaia.engram-shm +0 -0
  227. package/.agents/memory/kaia.engram-wal +0 -0
  228. package/.agents/memory/runes_audit.md +5 -0
  229. package/.agents/memory/well/episodes.jsonl +367 -0
  230. package/.agents/memory/well/workspace.jsonl +27 -0
  231. package/.agents/migrations/0001-hodd-layout.sh +38 -0
  232. package/.agents/migrations/0002-a2a-mcp.sh +27 -0
  233. package/.agents/migrations/0003-private-data-separation.sh +111 -0
  234. package/.agents/migrations/0004-hoard-and-realms.sh +104 -0
  235. package/.agents/sandbox/Dockerfile.utgard +19 -0
  236. package/.agents/sandbox/README.md +14 -0
  237. package/.agents/sandbox/utgard.config.json +14 -0
  238. package/.agents/skills/README.md +59 -0
  239. package/.agents/skills/bragi-marketing/README.md +3 -0
  240. package/.agents/skills/bragi-marketing/SKILL.md +82 -0
  241. package/.agents/skills/eindri-homes/README.md +3 -0
  242. package/.agents/skills/eindri-homes/SKILL.md +291 -0
  243. package/.agents/skills/eindri-homes/assets/control-plane.md +122 -0
  244. package/.agents/skills/eindri-homes/assets/dispatch.md +80 -0
  245. package/.agents/skills/frigg-consent/README.md +3 -0
  246. package/.agents/skills/frigg-consent/SKILL.md +56 -0
  247. package/.agents/skills/galdr-ymirsystem/README.md +3 -0
  248. package/.agents/skills/galdr-ymirsystem/SKILL.md +158 -0
  249. package/.agents/skills/galdr-ymirsystem/assets/README.md +74 -0
  250. package/.agents/skills/galdr-ymirsystem/assets/brokk-distro-runtime.md +390 -0
  251. package/.agents/skills/galdr-ymirsystem/assets/build-method.md +113 -0
  252. package/.agents/skills/galdr-ymirsystem/assets/build-tool-categories.md +178 -0
  253. package/.agents/skills/galdr-ymirsystem/assets/eindri-orchestration.md +518 -0
  254. package/.agents/skills/galdr-ymirsystem/assets/eindri-profiles.md +136 -0
  255. package/.agents/skills/galdr-ymirsystem/assets/harness-integration/README.md +673 -0
  256. package/.agents/skills/galdr-ymirsystem/assets/harness-integration/claude-code.md +197 -0
  257. package/.agents/skills/galdr-ymirsystem/assets/harness-integration/codex.md +191 -0
  258. package/.agents/skills/galdr-ymirsystem/assets/harness-integration/cursor.md +193 -0
  259. package/.agents/skills/galdr-ymirsystem/assets/harness-integration/opencode.md +262 -0
  260. package/.agents/skills/galdr-ymirsystem/assets/harness-integration/pi.md +295 -0
  261. package/.agents/skills/galdr-ymirsystem/assets/hlidskjalf-ui.md +496 -0
  262. package/.agents/skills/galdr-ymirsystem/assets/installation.md +571 -0
  263. package/.agents/skills/galdr-ymirsystem/assets/local-models/HOST-DATA.example.md +72 -0
  264. package/.agents/skills/galdr-ymirsystem/assets/local-models.md +274 -0
  265. package/.agents/skills/galdr-ymirsystem/assets/memory-well.md +161 -0
  266. package/.agents/skills/galdr-ymirsystem/assets/nornir-jobs.md +377 -0
  267. package/.agents/skills/galdr-ymirsystem/assets/norse-naming.md +325 -0
  268. package/.agents/skills/galdr-ymirsystem/assets/odrerir-hall.md +129 -0
  269. package/.agents/skills/galdr-ymirsystem/assets/pi-boot/einherjar-spawn.schema.json +81 -0
  270. package/.agents/skills/galdr-ymirsystem/assets/pi-boot/herdr-profile.toml +75 -0
  271. package/.agents/skills/galdr-ymirsystem/assets/pi-boot/pi-profile.yml +96 -0
  272. package/.agents/skills/galdr-ymirsystem/assets/pi-boot/supervision-tree.yml +163 -0
  273. package/.agents/skills/galdr-ymirsystem/assets/pi-boot-guide.md +58 -0
  274. package/.agents/skills/galdr-ymirsystem/assets/porting-upstream-to-norse.md +301 -0
  275. package/.agents/skills/galdr-ymirsystem/assets/principles.md +385 -0
  276. package/.agents/skills/galdr-ymirsystem/assets/reference-adoption.md +99 -0
  277. package/.agents/skills/galdr-ymirsystem/assets/registry.md +379 -0
  278. package/.agents/skills/galdr-ymirsystem/assets/runtime-compliance.md +463 -0
  279. package/.agents/skills/galdr-ymirsystem/assets/runtime-components.md +553 -0
  280. package/.agents/skills/galdr-ymirsystem/assets/smidja.md +175 -0
  281. package/.agents/skills/galdr-ymirsystem/schemas/toon-schemas.md +190 -0
  282. package/.agents/skills/galdr-ymirsystem/scripts/README.md +45 -0
  283. package/.agents/skills/galdr-ymirsystem/scripts/bench-one.sh +248 -0
  284. package/.agents/skills/galdr-ymirsystem/scripts/compliance-check.sh +360 -0
  285. package/.agents/skills/galdr-ymirsystem/scripts/gpu-sample.sh +43 -0
  286. package/.agents/skills/galdr-ymirsystem/scripts/stop-all.sh +34 -0
  287. package/.agents/skills/galdr-ymirsystem/scripts/toon-check.py +188 -0
  288. package/.agents/skills/gjallarhorn-relay/README.md +3 -0
  289. package/.agents/skills/gjallarhorn-relay/SKILL.md +283 -0
  290. package/.agents/skills/groa-update/SKILL.md +70 -0
  291. package/.agents/skills/hamr-adapters/README.md +3 -0
  292. package/.agents/skills/hamr-adapters/SKILL.md +123 -0
  293. package/.agents/skills/hamr-adapters/references/common/control-and-recovery.md +37 -0
  294. package/.agents/skills/hamr-adapters/references/common/dispatch.md +32 -0
  295. package/.agents/skills/hamr-adapters/references/common/model-and-effort.md +42 -0
  296. package/.agents/skills/hamr-adapters/references/common/primary-hooks.md +40 -0
  297. package/.agents/skills/hamr-adapters/references/harness/claude.md +55 -0
  298. package/.agents/skills/hamr-adapters/references/harness/codex.md +43 -0
  299. package/.agents/skills/hamr-adapters/references/harness/cursor.md +75 -0
  300. package/.agents/skills/hamr-adapters/references/harness/grok.md +69 -0
  301. package/.agents/skills/hamr-adapters/references/harness/kimi.md +51 -0
  302. package/.agents/skills/hamr-adapters/references/harness/muse.md +70 -0
  303. package/.agents/skills/hamr-adapters/references/harness/opencode.md +42 -0
  304. package/.agents/skills/hamr-adapters/references/harness/pi.md +56 -0
  305. package/.agents/skills/herdr-panes/README.md +3 -0
  306. package/.agents/skills/herdr-panes/SKILL.md +92 -0
  307. package/.agents/skills/herdr-panes/assets/herdr-backend.md +346 -0
  308. package/.agents/skills/herdr-panes/assets/tmux-backend.md +115 -0
  309. package/.agents/skills/hnoss-design/DESIGN.md +19 -0
  310. package/.agents/skills/hnoss-design/README.md +3 -0
  311. package/.agents/skills/hnoss-design/SKILL.md +83 -0
  312. package/.agents/skills/hvild-afk/README.md +3 -0
  313. package/.agents/skills/hvild-afk/SKILL.md +241 -0
  314. package/.agents/skills/jord-projects/README.md +3 -0
  315. package/.agents/skills/jord-projects/SKILL.md +92 -0
  316. package/.agents/skills/lifecycle/SKILL.md +56 -0
  317. package/.agents/skills/lifecycle/smoke_test.sh +52 -0
  318. package/.agents/skills/lifecycle/start.sh +21 -0
  319. package/.agents/skills/lifecycle/status.sh +35 -0
  320. package/.agents/skills/lifecycle/stop.sh +16 -0
  321. package/.agents/skills/muninn-stow/README.md +3 -0
  322. package/.agents/skills/muninn-stow/SKILL.md +309 -0
  323. package/.agents/skills/no-mistakes/SKILL.md +379 -0
  324. package/.agents/skills/nornir-schedule/README.md +3 -0
  325. package/.agents/skills/nornir-schedule/SKILL.md +25 -0
  326. package/.agents/skills/nornir-schedule/assets/events.md +137 -0
  327. package/.agents/skills/nornir-schedule/assets/quota.md +131 -0
  328. package/.agents/skills/nsr-compliance/README.md +3 -0
  329. package/.agents/skills/nsr-compliance/SKILL.md +29 -0
  330. package/.agents/skills/nsr-compliance/assets/nsr/README.md +40 -0
  331. package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/README.md +15 -0
  332. package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/git-workflow.md +18 -0
  333. package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/security.md +22 -0
  334. package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/tech-stack.md +8 -0
  335. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/SKILL.md +71 -0
  336. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/config/core_four.yaml +16 -0
  337. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/check_danger.sh +102 -0
  338. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/check_wiring.sh +69 -0
  339. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/validate_code.sh +29 -0
  340. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/verify_docs.py +66 -0
  341. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/generate.sh +109 -0
  342. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/harness/envelopes/result_envelope.json +14 -0
  343. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/harness/envelopes/task_envelope.json +20 -0
  344. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/harness/runner.py +303 -0
  345. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/telemetry/logger.py +112 -0
  346. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/README.md +18 -0
  347. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/config/README.md +10 -0
  348. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/README.md +12 -0
  349. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/check_env.sh +23 -0
  350. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/check_paths.sh +20 -0
  351. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/check_platform.sh +23 -0
  352. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/harness/README.md +11 -0
  353. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/harness/envelopes/README.md +10 -0
  354. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/installer/README.md +10 -0
  355. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/installer/install.sh +125 -0
  356. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/telemetry/README.md +11 -0
  357. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/README.md +20 -0
  358. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/features/README.md +36 -0
  359. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/features/SKILL-template.md +14 -0
  360. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/README.md +25 -0
  361. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/SKILL.md +13 -0
  362. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/create_branch.sh +6 -0
  363. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/safe_commit.sh +9 -0
  364. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/sync_upstream.sh +6 -0
  365. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/README.md +27 -0
  366. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/SKILL.md +15 -0
  367. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/smoke_test.sh +12 -0
  368. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/start.sh +19 -0
  369. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/status.sh +12 -0
  370. package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/stop.sh +15 -0
  371. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/README.md +18 -0
  372. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/config/README.md +10 -0
  373. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/config/core_four.yaml +13 -0
  374. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/README.md +12 -0
  375. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_danger.sh +102 -0
  376. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_env.sh +23 -0
  377. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_paths.sh +20 -0
  378. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_platform.sh +23 -0
  379. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_wiring.sh +69 -0
  380. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/README.md +11 -0
  381. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/envelopes/README.md +10 -0
  382. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/envelopes/result_envelope.json +14 -0
  383. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/envelopes/task_envelope.json +20 -0
  384. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/runner.py +303 -0
  385. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/installer/README.md +10 -0
  386. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/installer/install.sh +125 -0
  387. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/telemetry/README.md +11 -0
  388. package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/telemetry/logger.py +112 -0
  389. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/README.md +14 -0
  390. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/api.md +17 -0
  391. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/compliance-wiring.md +155 -0
  392. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/frontend.md +15 -0
  393. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/README.md +11 -0
  394. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/README.md +23 -0
  395. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/clients/README.md +16 -0
  396. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/clients/template-README.md +11 -0
  397. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/deploy.sh +49 -0
  398. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/README.md +12 -0
  399. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/development.env.example +17 -0
  400. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/production.env.example +17 -0
  401. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/staging.env.example +17 -0
  402. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/tenants/README.md +11 -0
  403. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/tenants/template.env.example +8 -0
  404. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/README.md +26 -0
  405. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/agent.md +7 -0
  406. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/developers/dev-1.md +20 -0
  407. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/linux.md +9 -0
  408. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/macos.md +10 -0
  409. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/shared.md +19 -0
  410. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/windows.md +14 -0
  411. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/HOSTING/README.md +25 -0
  412. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/HOSTING/_template.md +41 -0
  413. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/HOSTING/hosting-1.md +41 -0
  414. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/README.md +21 -0
  415. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/README.md +15 -0
  416. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/deployment.md +19 -0
  417. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/disaster-recovery.md +15 -0
  418. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/ops-tasks.md +14 -0
  419. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/features/README.md +16 -0
  420. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/project-skills.md +146 -0
  421. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/research/README.md +11 -0
  422. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/research/software-compliance-research.md +269 -0
  423. package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/working-with-agents.md +260 -0
  424. package/.agents/skills/nsr-compliance/assets/nsr/assets/root/AGENTS.md +38 -0
  425. package/.agents/skills/nsr-compliance/assets/nsr/assets/root/ARCHITECTURE.md +36 -0
  426. package/.agents/skills/nsr-compliance/assets/nsr/assets/root/BEST_PRACTICES.md +27 -0
  427. package/.agents/skills/nsr-compliance/assets/nsr/assets/root/CI_CD.md +23 -0
  428. package/.agents/skills/nsr-compliance/assets/nsr/assets/root/FEATURES.md +15 -0
  429. package/.agents/skills/nsr-compliance/assets/nsr/assets/root/README.md +22 -0
  430. package/.agents/skills/nsr-compliance/assets/nsr/assets/root/RULES.md +37 -0
  431. package/.agents/skills/nsr-compliance/assets/nsr/assets/root/STRUCTURE.md +45 -0
  432. package/.agents/skills/nsr-compliance/assets/nsr/assets/root/TECH_STACK.md +28 -0
  433. package/.agents/skills/nsr-compliance/assets/nsr/scaffold-spec.md +63 -0
  434. package/.agents/skills/nsr-compliance/assets/nsr/scripts/scaffold.sh +103 -0
  435. package/.agents/skills/nsr-compliance/assets/nsr/scripts/validate.sh +52 -0
  436. package/.agents/skills/nsr-compliance/assets/nsrcompliance/SKILL.md +71 -0
  437. package/.agents/skills/nsr-compliance/assets/nsrcompliance/config/core_four.yaml +16 -0
  438. package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/check_danger.sh +102 -0
  439. package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/check_wiring.sh +69 -0
  440. package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/validate_code.sh +29 -0
  441. package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/verify_docs.py +66 -0
  442. package/.agents/skills/nsr-compliance/assets/nsrcompliance/generate.sh +109 -0
  443. package/.agents/skills/nsr-compliance/assets/nsrcompliance/harness/envelopes/result_envelope.json +14 -0
  444. package/.agents/skills/nsr-compliance/assets/nsrcompliance/harness/envelopes/task_envelope.json +20 -0
  445. package/.agents/skills/nsr-compliance/assets/nsrcompliance/harness/runner.py +303 -0
  446. package/.agents/skills/nsr-compliance/assets/nsrcompliance/telemetry/logger.py +112 -0
  447. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/README.md +18 -0
  448. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/config/README.md +10 -0
  449. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/README.md +12 -0
  450. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/check_env.sh +23 -0
  451. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/check_paths.sh +20 -0
  452. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/check_platform.sh +23 -0
  453. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/harness/README.md +11 -0
  454. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/harness/envelopes/README.md +10 -0
  455. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/installer/README.md +10 -0
  456. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/installer/install.sh +125 -0
  457. package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/telemetry/README.md +11 -0
  458. package/.agents/skills/pr-ops/README.md +3 -0
  459. package/.agents/skills/pr-ops/SKILL.md +109 -0
  460. package/.agents/skills/ratatoskr-a2a/README.md +3 -0
  461. package/.agents/skills/ratatoskr-a2a/SKILL.md +148 -0
  462. package/.agents/skills/rules-check-drift/SKILL.md +81 -0
  463. package/.agents/skills/saga-bearings/README.md +3 -0
  464. package/.agents/skills/saga-bearings/SKILL.md +26 -0
  465. package/.agents/skills/saga-bearings/assets/bearings.md +161 -0
  466. package/.agents/skills/saga-bearings/assets/board-template.html +731 -0
  467. package/.agents/skills/saga-bearings/assets/recap.md +56 -0
  468. package/.agents/skills/syn-recovery/README.md +3 -0
  469. package/.agents/skills/syn-recovery/SKILL.md +54 -0
  470. package/.agents/skills/tyr-check/README.md +3 -0
  471. package/.agents/skills/tyr-check/SKILL.md +218 -0
  472. package/.agents/skills/urdh-hold/README.md +3 -0
  473. package/.agents/skills/urdh-hold/SKILL.md +25 -0
  474. package/.agents/skills/urdh-hold/assets/decisions.md +15 -0
  475. package/.agents/skills/urdh-hold/assets/hold.md +54 -0
  476. package/.agents/skills/vor-diagnostics/README.md +3 -0
  477. package/.agents/skills/vor-diagnostics/SKILL.md +68 -0
  478. package/.agents/skills/ymir-host/README.md +3 -0
  479. package/.agents/skills/ymir-host/SKILL.md +34 -0
  480. package/.agents/skills/ymir-host/assets/desktop.md +36 -0
  481. package/.agents/skills/ymir-host/assets/omarchy.md +297 -0
  482. package/.agents/skills/ymir-host/assets/runbooks.md +15 -0
  483. package/.agents/skills/ymir-host/assets/thjazi.md +220 -0
  484. package/.agents/skills/ymir-host/assets/update.md +64 -0
  485. package/.agents/tests/assets/board-render-harness.mjs +117 -0
  486. package/.agents/tests/cmux-test-safety.sh +51 -0
  487. package/.agents/tests/fixtures.sh +291 -0
  488. package/.agents/tests/fm-afk-inject-e2e.test.sh +428 -0
  489. package/.agents/tests/fm-afk-inject-herdr-e2e.test.sh +536 -0
  490. package/.agents/tests/fm-afk-launch.test.sh +961 -0
  491. package/.agents/tests/fm-afk-pi-herdr-return-e2e.test.sh +297 -0
  492. package/.agents/tests/fm-afk-return.test.sh +283 -0
  493. package/.agents/tests/fm-arm-pretool-check.test.sh +482 -0
  494. package/.agents/tests/fm-ask-user-authority.test.sh +42 -0
  495. package/.agents/tests/fm-backend-autodetect-smoke.test.sh +176 -0
  496. package/.agents/tests/fm-backend-cmux-smoke.test.sh +188 -0
  497. package/.agents/tests/fm-backend-cmux.test.sh +1166 -0
  498. package/.agents/tests/fm-backend-herdr-eventwait-smoke.test.sh +136 -0
  499. package/.agents/tests/fm-backend-herdr-eventwait.test.py +106 -0
  500. package/.agents/tests/fm-backend-herdr-focus-flash-e2e.test.sh +409 -0
  501. package/.agents/tests/fm-backend-herdr-launcher-workspace-e2e.test.sh +437 -0
  502. package/.agents/tests/fm-backend-herdr-presentation-e2e.test.sh +1424 -0
  503. package/.agents/tests/fm-backend-herdr-prune-safety-e2e.test.sh +180 -0
  504. package/.agents/tests/fm-backend-herdr-respawn-idem-e2e.test.sh +182 -0
  505. package/.agents/tests/fm-backend-herdr-smoke.test.sh +355 -0
  506. package/.agents/tests/fm-backend-herdr-workspace-per-home-e2e.test.sh +251 -0
  507. package/.agents/tests/fm-backend-herdr.test.sh +4606 -0
  508. package/.agents/tests/fm-backend-orca.test.sh +1357 -0
  509. package/.agents/tests/fm-backend-tmux-smoke.test.sh +173 -0
  510. package/.agents/tests/fm-backend-zellij-smoke.test.sh +205 -0
  511. package/.agents/tests/fm-backend-zellij.test.sh +1360 -0
  512. package/.agents/tests/fm-backend.test.sh +1142 -0
  513. package/.agents/tests/fm-backlog-atomicity.test.sh +2302 -0
  514. package/.agents/tests/fm-backlog-handoff.test.sh +1360 -0
  515. package/.agents/tests/fm-bearings-board-render.test.sh +135 -0
  516. package/.agents/tests/fm-bearings-board.test.sh +414 -0
  517. package/.agents/tests/fm-bearings-snapshot.test.sh +1990 -0
  518. package/.agents/tests/fm-bootstrap-network-parallel.test.sh +316 -0
  519. package/.agents/tests/fm-bootstrap.test.sh +1178 -0
  520. package/.agents/tests/fm-branch-supervision.test.sh +552 -0
  521. package/.agents/tests/fm-brief.test.sh +785 -0
  522. package/.agents/tests/fm-busy-adapter-wiring.test.sh +324 -0
  523. package/.agents/tests/fm-busy-state.test.sh +465 -0
  524. package/.agents/tests/fm-calm-pi-extension.test.sh +3979 -0
  525. package/.agents/tests/fm-captain-hold-lifecycle.test.sh +1187 -0
  526. package/.agents/tests/fm-cd-pretool-check.test.sh +400 -0
  527. package/.agents/tests/fm-check-unregister.test.sh +198 -0
  528. package/.agents/tests/fm-classify-corr-token.test.sh +543 -0
  529. package/.agents/tests/fm-classify-decision-key.test.sh +340 -0
  530. package/.agents/tests/fm-claude-stop-autoarm-live-e2e.test.sh +164 -0
  531. package/.agents/tests/fm-claude-stop-autoarm.test.sh +1190 -0
  532. package/.agents/tests/fm-cmux-claude-composer-live-e2e.test.sh +110 -0
  533. package/.agents/tests/fm-codex-continuity-live-e2e.test.sh +55 -0
  534. package/.agents/tests/fm-composer-ghost.test.sh +716 -0
  535. package/.agents/tests/fm-composer-lib.test.sh +666 -0
  536. package/.agents/tests/fm-composer-matrix-live-e2e.test.sh +220 -0
  537. package/.agents/tests/fm-control-herdr-smoke.test.sh +149 -0
  538. package/.agents/tests/fm-control-relaunch.test.sh +1530 -0
  539. package/.agents/tests/fm-control.test.sh +910 -0
  540. package/.agents/tests/fm-crew-state.test.sh +1610 -0
  541. package/.agents/tests/fm-cursor-harness.test.sh +404 -0
  542. package/.agents/tests/fm-cursor-primary-live-e2e.test.sh +217 -0
  543. package/.agents/tests/fm-cursor-primary.test.sh +708 -0
  544. package/.agents/tests/fm-daemon.test.sh +2740 -0
  545. package/.agents/tests/fm-documentation-audiences.test.sh +141 -0
  546. package/.agents/tests/fm-ensure-agents-md.test.sh +371 -0
  547. package/.agents/tests/fm-extension-binding.test.sh +2187 -0
  548. package/.agents/tests/fm-fleet-snapshot-view.test.sh +816 -0
  549. package/.agents/tests/fm-fleet-sync.test.sh +721 -0
  550. package/.agents/tests/fm-gate-refuse.test.sh +356 -0
  551. package/.agents/tests/fm-gitignore-config.test.sh +89 -0
  552. package/.agents/tests/fm-gotmp.test.sh +230 -0
  553. package/.agents/tests/fm-grok-continuity-live-e2e.test.sh +112 -0
  554. package/.agents/tests/fm-grok-harness.test.sh +117 -0
  555. package/.agents/tests/fm-grok-stop-live-e2e.test.sh +219 -0
  556. package/.agents/tests/fm-guard-stale-banner.test.sh +709 -0
  557. package/.agents/tests/fm-harness-adapter-instructions-live-e2e.test.sh +134 -0
  558. package/.agents/tests/fm-harness-adapter-references.test.sh +30 -0
  559. package/.agents/tests/fm-harness-liveness-drift-live-e2e.test.sh +151 -0
  560. package/.agents/tests/fm-herdr-lab.test.sh +243 -0
  561. package/.agents/tests/fm-herdr-session-cleanup-e2e.test.sh +146 -0
  562. package/.agents/tests/fm-herdr-session-cleanup.test.sh +329 -0
  563. package/.agents/tests/fm-herdr-submit-confirm-live-e2e.test.sh +125 -0
  564. package/.agents/tests/fm-herdr-version-floor-live-e2e.test.sh +144 -0
  565. package/.agents/tests/fm-home-summary-refresh.test.sh +971 -0
  566. package/.agents/tests/fm-inactive-reconcile.test.sh +485 -0
  567. package/.agents/tests/fm-kimi-harness.test.sh +687 -0
  568. package/.agents/tests/fm-lint-workflows.test.sh +532 -0
  569. package/.agents/tests/fm-lint.test.sh +1023 -0
  570. package/.agents/tests/fm-muse-harness.test.sh +932 -0
  571. package/.agents/tests/fm-muse-signals-live-e2e.test.sh +205 -0
  572. package/.agents/tests/fm-no-mistakes-required.test.sh +72 -0
  573. package/.agents/tests/fm-on.test.sh +507 -0
  574. package/.agents/tests/fm-opencode-primary-live-e2e.test.sh +357 -0
  575. package/.agents/tests/fm-operational-input.test.sh +160 -0
  576. package/.agents/tests/fm-peek-remote.test.sh +110 -0
  577. package/.agents/tests/fm-pending-reply.test.sh +1288 -0
  578. package/.agents/tests/fm-pi-branch-extension.test.sh +3182 -0
  579. package/.agents/tests/fm-pi-branch-live-e2e.test.sh +527 -0
  580. package/.agents/tests/fm-pi-primary-live-e2e.test.sh +345 -0
  581. package/.agents/tests/fm-pi-primary-types.test.sh +68 -0
  582. package/.agents/tests/fm-pi-watch-extension.test.sh +2843 -0
  583. package/.agents/tests/fm-pr-check-security.test.sh +2140 -0
  584. package/.agents/tests/fm-pr-merge.test.sh +2135 -0
  585. package/.agents/tests/fm-procevent-quota.test.sh +225 -0
  586. package/.agents/tests/fm-procevent-when.test.sh +406 -0
  587. package/.agents/tests/fm-procevent.test.sh +1745 -0
  588. package/.agents/tests/fm-project-origin.test.sh +110 -0
  589. package/.agents/tests/fm-public-followup.test.sh +2272 -0
  590. package/.agents/tests/fm-quota-array-dispatch-live-e2e.test.sh +526 -0
  591. package/.agents/tests/fm-quota-choose.test.sh +626 -0
  592. package/.agents/tests/fm-remote-backlog-handoff.test.sh +453 -0
  593. package/.agents/tests/fm-remote-doctor.test.sh +625 -0
  594. package/.agents/tests/fm-remote-entrypoint.test.sh +59 -0
  595. package/.agents/tests/fm-remote-job-orphan-reap.test.sh +205 -0
  596. package/.agents/tests/fm-remote-job.test.sh +768 -0
  597. package/.agents/tests/fm-remote-reply.test.sh +520 -0
  598. package/.agents/tests/fm-remote-secondmate-lifecycle-e2e.test.sh +1256 -0
  599. package/.agents/tests/fm-remote-secondmate-parent-binding.test.sh +326 -0
  600. package/.agents/tests/fm-remote-secondmate-trace-context.test.sh +310 -0
  601. package/.agents/tests/fm-remote-transport-lanes.test.sh +431 -0
  602. package/.agents/tests/fm-review-diff.test.sh +176 -0
  603. package/.agents/tests/fm-secondmate-harness.test.sh +2600 -0
  604. package/.agents/tests/fm-secondmate-lifecycle-e2e.test.sh +259 -0
  605. package/.agents/tests/fm-secondmate-liveness.test.sh +559 -0
  606. package/.agents/tests/fm-secondmate-reconcile.test.sh +732 -0
  607. package/.agents/tests/fm-secondmate-safety.test.sh +2972 -0
  608. package/.agents/tests/fm-secondmate-sync.test.sh +913 -0
  609. package/.agents/tests/fm-send-inbox-doorbell-live-e2e.test.sh +206 -0
  610. package/.agents/tests/fm-send-inbox.test.sh +352 -0
  611. package/.agents/tests/fm-send-popup-settle.test.sh +167 -0
  612. package/.agents/tests/fm-send-remote-delivery.test.sh +796 -0
  613. package/.agents/tests/fm-send-resolve-key.test.sh +551 -0
  614. package/.agents/tests/fm-send-secondmate-marker-herdr-e2e.test.sh +187 -0
  615. package/.agents/tests/fm-send-secondmate-marker.test.sh +278 -0
  616. package/.agents/tests/fm-send-settle.test.sh +147 -0
  617. package/.agents/tests/fm-send-strict.test.sh +241 -0
  618. package/.agents/tests/fm-session-lock-ancestry.test.sh +365 -0
  619. package/.agents/tests/fm-session-start.test.sh +2515 -0
  620. package/.agents/tests/fm-sessionstart-hook-live-e2e.test.sh +631 -0
  621. package/.agents/tests/fm-sessionstart-instruction-refresh-live-e2e.test.sh +230 -0
  622. package/.agents/tests/fm-sessionstart-nudge.test.sh +1039 -0
  623. package/.agents/tests/fm-shared-captain-inheritance.test.sh +404 -0
  624. package/.agents/tests/fm-spawn-batch.test.sh +148 -0
  625. package/.agents/tests/fm-spawn-dispatch-profile.test.sh +827 -0
  626. package/.agents/tests/fm-spawn-pool-base-freshen.test.sh +440 -0
  627. package/.agents/tests/fm-spawn-worktree-settle.test.sh +147 -0
  628. package/.agents/tests/fm-startup-memory-budget.test.sh +333 -0
  629. package/.agents/tests/fm-startup-network.test.sh +712 -0
  630. package/.agents/tests/fm-stow-cascade.test.sh +370 -0
  631. package/.agents/tests/fm-subagent-pretool-check.test.sh +291 -0
  632. package/.agents/tests/fm-supervision-events.test.sh +156 -0
  633. package/.agents/tests/fm-supervision-instructions.test.sh +189 -0
  634. package/.agents/tests/fm-tangle-guard.test.sh +277 -0
  635. package/.agents/tests/fm-task-delivery.test.sh +420 -0
  636. package/.agents/tests/fm-task-inbox.test.sh +513 -0
  637. package/.agents/tests/fm-teardown-endpoint-safety.test.sh +374 -0
  638. package/.agents/tests/fm-teardown.test.sh +2665 -0
  639. package/.agents/tests/fm-test-fixture-cleanup.test.sh +172 -0
  640. package/.agents/tests/fm-test-fixtures.test.sh +132 -0
  641. package/.agents/tests/fm-test-isolation-proof.test.sh +278 -0
  642. package/.agents/tests/fm-test-run.test.sh +1196 -0
  643. package/.agents/tests/fm-tmux-agent-liveness.test.sh +354 -0
  644. package/.agents/tests/fm-tmux-submit-busy.test.sh +340 -0
  645. package/.agents/tests/fm-tool-update-check.test.sh +1044 -0
  646. package/.agents/tests/fm-trace-context-lib.test.sh +253 -0
  647. package/.agents/tests/fm-trace-context-spawn.test.sh +581 -0
  648. package/.agents/tests/fm-transition-lib.test.sh +54 -0
  649. package/.agents/tests/fm-turnend-guard.test.sh +1822 -0
  650. package/.agents/tests/fm-update.test.sh +304 -0
  651. package/.agents/tests/fm-vendor-auth-probe.test.sh +395 -0
  652. package/.agents/tests/fm-voice-relay.test.sh +4741 -0
  653. package/.agents/tests/fm-wake-daemon-lifecycle-e2e.test.sh +171 -0
  654. package/.agents/tests/fm-wake-drain-open-decisions-cursor.test.sh +356 -0
  655. package/.agents/tests/fm-wake-drain-open-decisions.test.sh +226 -0
  656. package/.agents/tests/fm-wake-drain-unread-status.test.sh +379 -0
  657. package/.agents/tests/fm-wake-queue.test.sh +1224 -0
  658. package/.agents/tests/fm-watch-arm.test.sh +821 -0
  659. package/.agents/tests/fm-watch-checkpoint.test.sh +87 -0
  660. package/.agents/tests/fm-watch-recovery-loop.test.sh +223 -0
  661. package/.agents/tests/fm-watch-triage.test.sh +3889 -0
  662. package/.agents/tests/fm-watcher-lock.test.sh +1133 -0
  663. package/.agents/tests/fm-x-mode.test.sh +3042 -0
  664. package/.agents/tests/gleipnir-guard-pretool-check.test.sh +51 -0
  665. package/.agents/tests/gleipnir-machine-lock.test.sh +130 -0
  666. package/.agents/tests/herdr-test-safety.sh +42 -0
  667. package/.agents/tests/lib.sh +315 -0
  668. package/.agents/tests/remote-herdr-fixture.sh +125 -0
  669. package/.agents/tests/secondmate-helpers.sh +193 -0
  670. package/.agents/tests/smoke.test.sh +93 -0
  671. package/.agents/tests/wake-helpers.sh +338 -0
  672. package/.agents/tests/zellij-test-safety.sh +60 -0
  673. package/.agents/tools/README.md +10 -0
  674. package/.agents/tools/bin/tasks-cli +267 -0
  675. package/.agents/tools/tasks-cli.ts +216 -0
  676. package/AGENTS.md +454 -0
  677. package/CHANGELOG.md +881 -0
  678. package/LICENSE +1 -1
  679. package/NOTICE +63 -0
  680. package/README.md +113 -59
  681. package/RULES/01-domains.md +51 -0
  682. package/RULES/02-agents.md +78 -0
  683. package/RULES/03-houses.md +61 -0
  684. package/RULES/04-hoard.md +65 -0
  685. package/RULES/05-platforms.md +67 -0
  686. package/RULES/06-append-only.md +58 -0
  687. package/RULES/07-config.md +45 -0
  688. package/RULES/08-delivery-gate.md +75 -0
  689. package/RULES/README.md +20 -0
  690. package/bin/README.md +107 -0
  691. package/bin/a2a-mcp.sh +98 -0
  692. package/bin/a2a-serve.py +103 -0
  693. package/bin/a2a-serve.sh +8 -0
  694. package/bin/a2a-talk.sh +50 -0
  695. package/bin/a2abridge-ensure.sh +108 -0
  696. package/bin/agent-run.sh +43 -0
  697. package/bin/agents-config.sh +233 -0
  698. package/bin/apodex-smoke-test.sh +92 -0
  699. package/bin/bifrost-bridge.sh +112 -0
  700. package/bin/bifrost-ingress.sh +77 -0
  701. package/bin/bootstrap-macos.sh +107 -0
  702. package/bin/bootstrap-windows.ps1 +112 -0
  703. package/bin/branch-guard.sh +64 -0
  704. package/bin/brokk +73 -0
  705. package/bin/brokk-classify-lib.sh +1770 -0
  706. package/bin/brokk-lease-lib.sh +222 -0
  707. package/bin/brokk-lease.sh +193 -0
  708. package/bin/brokk-lint.sh +65 -0
  709. package/bin/brokk-send.sh +38 -0
  710. package/bin/brokk-update.sh +9 -0
  711. package/bin/brokk-wake-grant.sh +127 -0
  712. package/bin/brokk-wake-lib.sh +1849 -0
  713. package/bin/changelog-guard.sh +165 -0
  714. package/bin/crash-sense.sh +160 -0
  715. package/bin/desktop-place.sh +224 -0
  716. package/bin/docs-guard.sh +39 -0
  717. package/bin/editor-place.sh +207 -0
  718. package/bin/eindri-acclaim.sh +34 -0
  719. package/bin/eindri-control.sh +28 -0
  720. package/bin/eindri-role.sh +83 -0
  721. package/bin/eindri-seen.sh +41 -0
  722. package/bin/eindri-send.sh +15 -0
  723. package/bin/eindri-start.sh +85 -0
  724. package/bin/eindri-watch.sh +57 -0
  725. package/bin/einherjar-spawn.sh +576 -0
  726. package/bin/eir-doctor.sh +112 -0
  727. package/bin/erindi-brief.sh +271 -0
  728. package/bin/fleet-apply.sh +68 -0
  729. package/bin/github-deploy.sh +81 -0
  730. package/bin/gjallarhorn-expose.sh +102 -0
  731. package/bin/gjallarhorn-notify.sh +58 -0
  732. package/bin/gjallarhorn-purge.sh +54 -0
  733. package/bin/gjallarhorn-tunnel.sh +72 -0
  734. package/bin/gleipnir-lock-lib.sh +284 -0
  735. package/bin/groa-update.sh +122 -0
  736. package/bin/hall-snapshot.sh +92 -0
  737. package/bin/hamr-harness.sh +246 -0
  738. package/bin/heimdall-ssh-keys.sh +374 -0
  739. package/bin/herdr-agents.py +44 -0
  740. package/bin/herdr-ensure.sh +104 -0
  741. package/bin/herdr-run.sh +431 -0
  742. package/bin/hermes-ensure.sh +88 -0
  743. package/bin/hoard-lib.sh +25 -0
  744. package/bin/hodd.sh +78 -0
  745. package/bin/host-sense.sh +199 -0
  746. package/bin/huginn-research-worker.sh +108 -0
  747. package/bin/local-model-lock.sh +51 -0
  748. package/bin/mimir-bridge.py +226 -0
  749. package/bin/mimir-bridge.sh +87 -0
  750. package/bin/mimir-ingest.sh +131 -0
  751. package/bin/mimir.sh +113 -0
  752. package/bin/mjollnir-webhook.sh +59 -0
  753. package/bin/mjollnir.sh +85 -0
  754. package/bin/model-hardware.sh +82 -0
  755. package/bin/model-resolve.sh +147 -0
  756. package/bin/models-detect.sh +178 -0
  757. package/bin/nornir-cron-start.sh +162 -0
  758. package/bin/nornir-job-daily-briefing.sh +191 -0
  759. package/bin/nornir-job-git-sync.sh +152 -0
  760. package/bin/nornir-job-memory-housekeeping.sh +114 -0
  761. package/bin/nornir-job-observer.sh +166 -0
  762. package/bin/nornir-job-skillopt-sleep.sh +76 -0
  763. package/bin/omarchy-hook-install.sh +60 -0
  764. package/bin/omarchy-install.sh +148 -0
  765. package/bin/omarchy-plugins.sh +174 -0
  766. package/bin/omarchy-sense.sh +149 -0
  767. package/bin/perm-guard.sh +30 -0
  768. package/bin/pi-agent.sh +68 -0
  769. package/bin/pi-ensure.sh +77 -0
  770. package/bin/pi-local.sh +37 -0
  771. package/bin/pi-seat.sh +63 -0
  772. package/bin/prereq-ensure.sh +166 -0
  773. package/bin/private-guard.sh +38 -0
  774. package/bin/project-git.sh +55 -0
  775. package/bin/public-guard.sh +70 -0
  776. package/bin/ratatoskr.sh +49 -0
  777. package/bin/realm-lib.sh +32 -0
  778. package/bin/repo-scrub.sh +62 -0
  779. package/bin/rodd-operational-input.sh +250 -0
  780. package/bin/runes-append.sh +198 -0
  781. package/bin/saga-session-start.sh +172 -0
  782. package/bin/saga-sessionstart-run.sh +79 -0
  783. package/bin/saga-wake-drain.sh +41 -0
  784. package/bin/secret-guard.sh +63 -0
  785. package/bin/sessrumnir-ensure.sh +100 -0
  786. package/bin/sessrumnir-sync.sh +237 -0
  787. package/bin/sessrumnir.sh +91 -0
  788. package/bin/skillopt-setup.sh +76 -0
  789. package/bin/skuld-branch-outcome.sh +203 -0
  790. package/bin/skuld-branch-prompt.sh +101 -0
  791. package/bin/smidja-bootstrap.sh +90 -0
  792. package/bin/smidja-observe.sh +86 -0
  793. package/bin/syn-arm-pretool-check.sh +57 -0
  794. package/bin/syn-asset-pretool-check.sh +76 -0
  795. package/bin/syn-cd-pretool-check.sh +28 -0
  796. package/bin/syn-guard-pretool-check.sh +83 -0
  797. package/bin/syn-turnend-guard.sh +36 -0
  798. package/bin/syn-watch-arm.sh +99 -0
  799. package/bin/tailscale-sync.sh +190 -0
  800. package/bin/telegram-bot.sh +69 -0
  801. package/bin/toolchain.sh +74 -0
  802. package/bin/utgard.sh +111 -0
  803. package/bin/valhalla.sh +115 -0
  804. package/bin/valknut-load.sh +260 -0
  805. package/bin/vor-crew-state.sh +124 -0
  806. package/bin/wedge-notify.sh +47 -0
  807. package/bin/workspace-provision.sh +80 -0
  808. package/bin/workspace-rag.sh +150 -0
  809. package/bin/wyrd-db.sh +47 -0
  810. package/bin/yggdrasil.sh +152 -0
  811. package/bin/ymir-edit.sh +145 -0
  812. package/bin/ymir-install.sh +641 -0
  813. package/bin/ymir-invite.sh +93 -0
  814. package/bin/ymir-isolation.sh +88 -0
  815. package/bin/ymir-migrate.sh +61 -0
  816. package/bin/ymir-platform.sh +348 -0
  817. package/bin/ymir-say.sh +97 -0
  818. package/bin/ymir-setup-auth.sh +108 -0
  819. package/bin/ymir-validate.sh +173 -0
  820. package/bin/ymir.js +74 -16
  821. package/docs/Architecture.md +339 -0
  822. package/docs/design.md +351 -0
  823. package/docs/installations/README.md +63 -0
  824. package/docs/installations/ymir-home.md +93 -0
  825. package/docs/integration.md +105 -0
  826. package/docs/lore.md +1056 -0
  827. package/docs/research/agent-harnesses.md +290 -0
  828. package/docs/runbooks/README.md +19 -0
  829. package/docs/runbooks/a2a.md +91 -0
  830. package/docs/runbooks/agent-permissions.md +99 -0
  831. package/docs/runbooks/agents.md +57 -0
  832. package/docs/runbooks/models.md +69 -0
  833. package/docs/runbooks/realm-onboarding.md +60 -0
  834. package/docs/runbooks/secrets-and-hoard.md +60 -0
  835. package/docs/runbooks/updates-and-migrations.md +110 -0
  836. package/docs/runbooks/worktrees-isolation.md +72 -0
  837. package/docs/session-start.md +105 -0
  838. package/docs/skillopt-integration.md +321 -0
  839. package/docs/sync-system.md +66 -0
  840. package/docs/workspaces.md +104 -0
  841. package/docs/ymir-rut.md +260 -0
  842. package/package.json +44 -14
  843. package/packaging/build.sh +74 -0
  844. package/packaging/macos/Ymir Installer.command +43 -0
  845. package/packaging/windows/ymir-setup.nsi +74 -0
  846. package/scripts/README.md +22 -0
  847. package/scripts/electron.sh +210 -0
  848. package/scripts/start.sh +167 -0
  849. package/scripts/stop.sh +113 -0
  850. package/install.sh +0 -35
@@ -0,0 +1,496 @@
1
+ # Hlidskjalf UI — working guide
2
+
3
+ Ymir's own surface (one of the three things Ymir owns: the UI, the runtime, A2A).
4
+ Load this when touching `apps/hlidskjalf`. The design contract is `docs/design.md`;
5
+ the tokens are the single source of truth.
6
+
7
+ ## Surfaces
8
+
9
+ ```
10
+ surfaces[6]{part,where,note}:
11
+ "SPA",":3888 (vite) / built dist served by the gate","React app; gates: Fleet, Chat, Runes, …"
12
+ "gate API",":3889 (bun apps/hlidskjalf/server/index.ts)","auth + /api/* + serves dist/; static types + caching"
13
+ "login","in-app modal → /api/login → session cookie","user/pass from .env.local HLIDSKJALF_AUTH; Heimdall (oauth2-proxy) is the target"
14
+ "register","in-app modal → /api/register → spends an invite code","bin/ymir-invite.sh mints a limited-use code when nothing is live; argon2id account in state/accounts.json (0600, gitignored)"
15
+ "desktop","apps/hlidskjalf/electron/main.cjs + scripts/electron.sh","single instance + one window (never stack); see the ymir skill assets/desktop.md"
16
+ "tunnel","gjallarhorn → your hostname → :3889","outbound only; `bin/gjallarhorn-tunnel.sh`"
17
+ ```
18
+
19
+ Quick rules:
20
+
21
+ - **One login, one window** — no GitHub hop before Heimdall; auth stays in-window.
22
+ - **Gate API protects `/api/*`** and serves the SPA; 401 → `ymir:unauthorized`.
23
+ - **No secrets inline** — `HLIDSKJALF_AUTH` from `.env.local`.
24
+ - **Electron:** single-instance lock; `openWindow` reuses the live window.
25
+ - Raise/repair: `scripts/start.sh`; if the window is gone but ports answer, the
26
+ shell must be restarted (backend ≠ window).
27
+
28
+ ## Location & stack
29
+
30
+ - App: `apps/hlidskjalf` — **React 19 + Vite + TypeScript**, state via **Zustand**.
31
+ - Gate API: `apps/hlidskjalf/server/index.ts` — **Bun + `bun:sqlite`**, read-only,
32
+ bound to the runtime and the smithy trace; Vite proxies `/api` → `:3889`.
33
+ - Raise everything with the scripts (do not hand-start each process):
34
+
35
+ ```bash
36
+ scripts/start.sh # SPA :3888 · gate API :3889 · Smíðja visualizer :8437 · Nornir cron · Bifrost bridge
37
+ scripts/stop.sh # lower them all
38
+ ```
39
+
40
+ - Verify: `npm run typecheck` (`tsc --noEmit`) and `npm run build` must both be green.
41
+ - Headless check: render with Playwright/Chrome and assert **0 console errors**.
42
+
43
+ ## Tokens — never hardcode colour
44
+
45
+ - Canonical tokens: `midgard/design-system/tokens.css`, imported once in
46
+ `src/main.tsx` (Vite `server.fs.allow` grants access outside the app root).
47
+ - Style with CSS variables only (`var(--ymir-cyan-1)`, `var(--ymir-bg-2)`, …).
48
+ **Never** write a raw hex in a component or a stylesheet — add a token instead.
49
+ - The active **accent** is driven by `--realm-tint` / `--realm-tint-2` /
50
+ `--realm-tint-dim` on `:root`, set per realm via `data-realm` and overridable by
51
+ the user (`state/store.ts` → `applyAccent`). Tenant overrides live in
52
+ `tenantColors`.
53
+ - **Fonts** are the cloth's three faces, loaded from Google Fonts in `index.html`:
54
+ Cormorant (display/runes), Newsreader (body), IBM Plex Mono (data), with Noto
55
+ Sans Runic appended to every stack so a rune glyph falls through to the rune
56
+ family.
57
+
58
+ ### The cloth (2026-09-13)
59
+
60
+ The token *values* are the **carved cloth of the halls** — the landing page's own
61
+ palette (`CodeP/ymir-homepage/src/lore.html` `:root`; the hall carries its own
62
+ locked copy at `apps/odrerir/src/styles/cloth.css`), so Hlidskjalf, Smíðja and
63
+ Sessrúmnir are one look (`docs/design.md` §0/§4.2 is the contract):
64
+
65
+ ```
66
+ canvas bg-0 #0e0c09 · bg-1 #151209 · bg-2 #1a1610 · bg-3 #221d14 (stone)
67
+ accent cyan-1 #c9973f bronze · cyan-2 #7d5f2a bronze-deep
68
+ violet-1 #96a0a8 steel · violet-2 #5f686e steel-dim
69
+ lines steel-1 #2b241a (line) · steel-2 #7d5f2a (brass rule) · chisel #c9973f
70
+ text text-0 #cfc3a9 bone · text-1 rgba(207,195,169,.82) · text-2 #9a8f75 · text-3 #6b6250
71
+ state ok #96a0a8 steel · warn #c9973f · danger #c2584a blood-lit · info #9a8f75
72
+ bevel inset 0 0 0 1px rgba(201,151,79,.12)
73
+ ```
74
+
75
+ Rules that hold it honest:
76
+
77
+ - **The cloth is the default, not a cage** — a user accent/background choice wins
78
+ (`AccentPicker`), and the eight **house/domain seals keep their heraldry**
79
+ (`DOMAINS`), exactly as the landing page keeps its house seals. Chrome is the
80
+ cloth; heraldry is not chrome.
81
+ - The **workspace tints** are cloth too: `work` = bronze `#c9973f`, `personal` =
82
+ steel `#96a0a8` (`src/data/realms.ts` → `WORKSPACES`, mirrored by the
83
+ `data-realm` fallbacks in `styles/global.css`).
84
+ - The **Emblem** (`components/Emblem.tsx`, `midgard/design-system/ymir-mark.svg`)
85
+ is brand, not cloth — it keeps its own colours on the stone.
86
+ - The login's GitHub button is a bone plate with a dark rune (the old white/navy
87
+ literal is gone), and the `HallsChooser` cards read real tokens (they used to
88
+ name two tokens that never existed, `--ymir-line`/`--ymir-panel`).
89
+ - Role-coloured literals in the stylesheets are now `color-mix(… var(--token) …)`,
90
+ so a token change re-themes them.
91
+ - Geometry did not move: radius, spacing and the shell are unchanged by the cloth
92
+ (the carved-slate squaring is still an open question).
93
+
94
+ ## The shell (structural, do not redesign)
95
+
96
+ - `.shell` grid: `236px rail | 1fr`; rows `56px topbar · stage · stream`
97
+ (the stream height is draggable, persisted in `streamHeight`).
98
+ - `.rail` (brand · gates · tenants · status), `.topbar` (realm chip · search ·
99
+ accent · density · trace index · account), `main.stage` (the gate), `.stream`
100
+ (Ratatoskr + Runes, pausable).
101
+ - Gates are **deep-linkable** and registered in `src/data/realms.ts` (`GATES`) and
102
+ routed in `src/app/Shell.tsx`:
103
+ `#/fleet` · `#/tasks` · `#/well` · `#/runes` · `#/reviews` · `#/processes` ·
104
+ `#/files` · `#/chat` · `#/forge` · `#/profile` · `#/sessions` · `#/trace` ·
105
+ `#/decisions` · `#/stats` · `#/cron` · `#/runtime`.
106
+
107
+ ## Rules of the surface
108
+
109
+ 1. **Color-only states are forbidden** — every status carries glyph + colour + text
110
+ (`StatusChip`, `TaskChip`).
111
+ 2. **Runecoded, not emoji** — use the rune family (runic glyphs fall through to
112
+ Noto Sans Runic inside the Cormorant/mono stacks); never an emoji as an icon.
113
+ 3. **Every button must act** — no dead controls. Wire to a state change, a modal, or
114
+ a toast.
115
+ 4. **Motion explains** — 120–240ms, no bounce; honour `prefers-reduced-motion`.
116
+ 5. **Metrics are IBM Plex Mono, tabular** (`.mono`, `.tabular`).
117
+ 6. **Metadata per page** — a gate declares its title/description/OG tags in
118
+ `src/data/metadata.ts`; `Shell` applies them on gate/realm change.
119
+
120
+ ## Interaction patterns (modal + toast)
121
+
122
+ - `src/state/ui.ts` exposes `useUI()` → `toast({kind,title,body})` and
123
+ `openModal({variant,title,body,fields,content,onSubmit})`.
124
+ - `<Overlay/>` (mounted in `App`) renders the modal + toast host. Variants:
125
+ `confirm`, `form` (fields), `info` (content block, e.g. a diff).
126
+ - Any consequential action **must** open a confirm/form modal, mutate the store,
127
+ emit a rune (`pushStream`), and toast the outcome. Reference: `components/PRCard.tsx`
128
+ (Seal / Request changes / View diff).
129
+ - Buttons get press feedback from `styles/overlays.css` (`translateY(1px) scale(.97)`).
130
+
131
+ ## State & live data
132
+
133
+ - `src/state/store.ts` — session, realm, gate, accent, tenant colours, company,
134
+ and data: agents, tasks, runes, stream, recall, processes, reviews, files, chat,
135
+ skills, **smidja** (sessions/stats/decisions/db), **mimir**.
136
+ - **Live mode** loads the gate API (`loadLive`); every call degrades on its own and
137
+ has a 10s timeout (`services/api.ts`). Smíðja loads on a **separate track**
138
+ (`refreshSmidja`) so a slow endpoint (e.g. `/api/reviews`) cannot hold its gates
139
+ hostage. `App` polls `refreshSmidja` every 5s.
140
+ - Realm switching is **granted**: `setRealm` refuses a realm the session has no
141
+ grant. Tenant boundaries are sacred — never render another tenant's data.
142
+ - Persist user prefs to `localStorage` (`ymir.accent`, `ymir.tenant-colors`,
143
+ `ymir.company.*`, `ymir.stream-height`).
144
+
145
+ ## The gate API surface (`/api`, read-only)
146
+
147
+ `/api/health · /api/me · /api/workspace · /api/agents · /api/tasks · /api/runes ·
148
+ /api/well · /api/processes · /api/reviews · /api/files · /api/runtime · /api/cron ·
149
+ /api/loaders · /api/checks · /api/settings · /api/stream · /api/mimir …` plus the
150
+ smithy trace: `/api/smidja/{health,sessions,sessions/:id,decisions,stats}` and
151
+ chat: `/api/chat/history`, `POST /api/chat`.
152
+
153
+ `POST /api/chat` resolves the chosen model against the operator's Pi catalog and
154
+ tries **every** engine that advertises it (LM Studio `:1234`, the llama.cpp
155
+ router `:8080`, Bifrost `:4603`), never only the first — a dead engine falls
156
+ through to a live one. Recall reads `.agents/memory/well/episodes.jsonl`
157
+ directly, so restoring that file revives the chat's memory without a restart.
158
+
159
+ ### The gate API reads cheaply (added 2026-09-16)
160
+
161
+ The gate reads append-only ledgers (Runes, the well's `episodes.jsonl`, masterplan
162
+ orders) and probes live runtime scripts on every request. Both grow without bound,
163
+ so the hot readers are memoised and the probes now run off the event loop:
164
+
165
+ - `runAsync()` — read-only subprocess probes via `Bun.spawn` (was `spawnSync`,
166
+ which could block the single Bun event loop for up to 12s); results cached ~3s
167
+ and concurrent callers share one in-flight spawn. Sync `run()` stays for
168
+ **mutating** actions only (`setupRun`, `workspaceProvision`).
169
+ - `memo()` — `orders`, `runes`, `smidjaStats`, `chatRecall` are cached (2–3s), so a
170
+ request never re-parses the whole ledger or well.
171
+
172
+ Measured: `/api/checks` 442ms → 4ms warm; `/api/runtime` 312ms → 5ms warm;
173
+ 20 parallel `/api/runes` in 8ms.
174
+
175
+ **Ports are environment-driven.** The SPA (Vite) and the gate API read
176
+ `HLIDSKJALF_PORT` (default `3888`) and `HLIDSKJALF_API_PORT` (default `3889`);
177
+ `scripts/start.sh` passes the API port to the server as `PORT`, and the visualizer
178
+ uses `SMIDJA_VIZ_API_PORT`. A deployment should use 5-digit ports (the Quadlet/
179
+ Compose examples publish `38888`/`38889`/`54370`) to avoid colliding with other
180
+ services on a shared host; the defaults are unchanged for bare local dev. The SPA
181
+ bind host is `HLIDSKJALF_HOST` (default `127.0.0.1`); inside a container set it to
182
+ `0.0.0.0` so the published port reaches it, and pin the host-side publish to
183
+ `127.0.0.1` so the surface stays private.
184
+
185
+ ## Smíðja in the UI
186
+
187
+ The smithy's trace (its own `smidja/smidja_data/smidja.db`) is rendered by four gates:
188
+
189
+ | Gate | Route | Reads |
190
+ |---|---|---|
191
+ | Sessions | `#/sessions` | every run, status, tokens/cost — **Open visualizer** + **Refresh** |
192
+ | Trace | `#/trace` | the selected run: phase lanes, events, agent sessions |
193
+ | Decisions | `#/decisions` | failures clustered by diagnosis/model |
194
+ | Stats | `#/stats` | token/cost breakdown, cache, providers |
195
+
196
+ **Open visualizer** opens `VISUALIZER_URL` (`src/data/metadata.ts`, default
197
+ `http://127.0.0.1:8437`) — Smíðja's own Vue trace UI, served by the smithy's Bun
198
+ API on the same port (`scripts/start.sh` raises it). Details: `assets/smidja.md`,
199
+ `docs/lore.md` §XIII.
200
+
201
+ ## Agents, skills & mythological naming
202
+
203
+ - The Forge gate (`src/gates/Forge.tsx`) creates/edits **Eindri** and **skills**,
204
+ and reads/edits the smithy's prompts.
205
+ - Naming law: `src/data/mythology.ts` maps a craft/capability → the Norse figure
206
+ whose myth matches it (smith→Sindri, skald→Bragi, sage→Huginn, judge→Tyr,
207
+ forger→Brokk …). Skills take an **aett** prefix.
208
+ - New skills are validated in Utgard before production (Gungnir, W0007).
209
+
210
+ ## Identity
211
+
212
+ - Mark: `midgard/design-system/ymir-mark.svg` (served `public/ymir-mark.svg`), used
213
+ for login/rail logo and favicon. OG image: `public/og.png` (1200×630), source
214
+ `public/og.svg`. Rebuild the PNG with headless Chrome if the SVG changes.
215
+
216
+ ## The desktop apps (Electron)
217
+
218
+ `Hlidskjalf` and `Smíðja` each run as their own Electron app (`electron/main.cjs`,
219
+ launched by `scripts/electron.sh start --both`).
220
+
221
+ **Window placement.** The apps open on a **non-primary** display when one is
222
+ attached (the Allfather keeps the dashboards beside his work) and on the primary
223
+ otherwise. All geometry is in **logical** units — Electron's `screen` API returns
224
+ physical ÷ scale, and Omarchy commonly runs a fractional scale (e.g. a 1920×1200
225
+ panel at 1.5 is a 1280×800 logical desktop), so a 1440-wide default is clamped to
226
+ the work area rather than overflowing it. `YMIR_DESKTOP_DISPLAY` overrides the
227
+ choice: `other` (default) · `primary` · an index.
228
+
229
+ **Identity.** Never track an Electron app by the pid returned from
230
+ `.bin/electron` — that is a node shim which *spawns* the real binary, so the pid
231
+ is wrong and a second launch stacks on the first. Identify it by its own command
232
+ line (the per-view `--user-data-dir` is stable), which is what `electron.sh` does.
233
+
234
+ **GPU.** On a small-VRAM iGPU the Wayland `--type=gpu-process` can die with
235
+ `amdgpu: Not enough memory for command submission` (SIGSEGV, not an OOM).
236
+ `YMIR_DESKTOP_DISABLE_GPU=1` adds `--disable-gpu --disable-gpu-compositing` —
237
+ these are dashboards, not 3D apps. See the `ymir` skill (its omarchy asset)
238
+ skill for the full native story.
239
+
240
+ ## Verification
241
+
242
+ ```bash
243
+ cd apps/hlidskjalf
244
+ npm run typecheck # tsc --noEmit
245
+ npm run build # must be green
246
+ # headless: render the gate and assert 0 console errors (Playwright/Chrome)
247
+ ```
248
+
249
+ ## Maintaining this
250
+
251
+ - **Owner:** Brokk. **Router:** `.agents/skills/galdr-ymirsystem/SKILL.md`.
252
+ - **Mirror:** `.agents/skills/tyr-check/assets/hlidskjalf-ui.md`.
253
+ - When the shell, tokens, gates, or the gate API change, update this asset and
254
+ `docs/design.md` together.
255
+
256
+ ## Domains, not houses (Rule 01/03)
257
+
258
+ The eight Labs are **domains (Greinar)** — the knowledge axes — not houses. A
259
+ **house is a company** (WayOf). In the UI the eight render as an agent's
260
+ **domain** (`agent.domain` via the `DOMAINS` map in `src/data/realms.ts`); the
261
+ Forge picker is labelled **Domain**. `svartalfaheim/<company>/companies/` holds
262
+ the house card(s); the eight domain cards live under `.../domains/`.
263
+
264
+ ### The GPU-process crash on a shared-memory iGPU (fixed 2026-09-12)
265
+
266
+ Symptom: both dashboards appear and work, while `coredumpctl` fills with SIGSEGV
267
+ cores from `electron --type=gpu-process`, and the kernel logs `amdgpu … Not enough
268
+ memory for command submission` immediately before each one. The window survives
269
+ because only the **GPU process** dies; Electron retries it, then falls back.
270
+
271
+ Cause: an iGPU has a small VRAM carve-out and backs the rest with system RAM
272
+ (GTT). A local model served on that same iGPU can hold several GiB of GTT, after
273
+ which the driver fails the desktop's command submissions. Electron's error path
274
+ dereferences NULL — a segfault at a constant offset, not memory corruption.
275
+
276
+ `scripts/electron.sh` now decides for itself: `igpu_vram_small()` reads
277
+ `/sys/class/drm/card*/device/mem_info_vram_total` and switches the dashboards to
278
+ software rendering when the carve-out is under `YMIR_IGPU_VRAM_SMALL_MIB`
279
+ (default 2048). `YMIR_DESKTOP_DISABLE_GPU=1` forces software, `=0` forces the GPU
280
+ path. Verified: with the fix the amdgpu submission errors stop and the
281
+ gpu-process runs SwiftShader instead of the hardware path.
282
+
283
+ If the crash returns, check GTT before anything else — `mem_info_gtt_used` on the
284
+ render device, next to whatever is serving a model on that GPU.
285
+
286
+ ### The login surface carries no operator name
287
+
288
+ The in-app login (the gate shows it; there is no browser prompt) renders its
289
+ fields from the server template in `apps/hlidskjalf/server/index.ts`. Neither the
290
+ placeholder nor any default may name the operator: the field says `username`, and
291
+ the password comes from `HLIDSKJALF_AUTH` in `.env.local`, never inline. A
292
+ hardcoded name here is both a leak into the public tree and wrong for any other
293
+ operator — `bin/public-guard.sh` exists to catch exactly that class of mistake.
294
+
295
+ ### One login, and it is the one with the lore (2026-09-12)
296
+
297
+ There used to be **two** ways in, and the second was a mistake:
298
+
299
+ | | what it was | fate |
300
+ |---|---|---|
301
+ | `components/LoginModal.tsx` | the gate's login, beside the saga panel | **kept** — the only login |
302
+ | `app/Login.tsx` | a mock identity picker (`MOCK_IDENTITIES`), "Mock · Heimdall W0028 pending", demo mode | **deleted** |
303
+
304
+ The mock was wrong in a way that mattered: `App` rendered it as the fallback
305
+ whenever the store had no session, so a *correct* sign-in could land on a screen
306
+ offering a hardcoded identity — the operator's own name and email among them. The
307
+ demo scaffolding went with it (`demo` flag, `setApiDemo`, `data/mock.ts`,
308
+ `enterDemo`/`signIn`, the fake chat reply that claimed the well was seeded), and
309
+ with it every branch that could invent data in a live session.
310
+
311
+ What replaced it:
312
+
313
+ - **One session shaper.** `services/auth.ts` exports `sessionFor(login)` — the
314
+ gate decides *who*, the UI only shapes what it renders. `App` calls
315
+ `gateApi.session()` at boot and establishes the session from the login the gate
316
+ reports; `establishSession(login)` replaced `signIn`/`enterDemo` in the store.
317
+ - **A GitHub door on the same gate.** `LoginModal` carries *Continue with GitHub*
318
+ → `GET /api/auth/github`, which returns the authorize URL when
319
+ `GITHUB_CLIENT_ID`/`GITHUB_CLIENT_SECRET` are set, and the exact reason when
320
+ they are not. The callback (`/api/auth/github/callback`) exchanges the code,
321
+ reads `/user`, and then **requires an account for that login** — accounts come
322
+ from an invite, so GitHub never becomes an open door.
323
+ - **A 401 still re-locks.** `noteUnauthorized` is the only thing the demo switch
324
+ was suppressing, and it survives without it.
325
+
326
+ Verified: `tsc --noEmit` and `npm run build` green, and the served SPA renders the
327
+ lore login with the invite affordance and no baked-in identity.
328
+
329
+ ### Accounts and invites — how someone else gets in (added 2026-09-12)
330
+
331
+ One operator owns an instance. `HLIDSKJALF_AUTH` is that operator. Everyone else
332
+ enters through an **invite code**: registration is closed unless a live code is
333
+ presented, and a code carries its own ceiling, so a shared link cannot quietly
334
+ become an open door.
335
+
336
+ ```
337
+ POST /api/register {username,password,invite} → 201 + session (403 when refused)
338
+ POST /api/login {username,password} → 200 + session (operator OR account)
339
+ GET /api/session → {authed,login,registration}
340
+ GET /api/invites → {invites,accounts} (authed)
341
+ ```
342
+
343
+ - **Store:** `apps/hlidskjalf/server/accounts.ts` owns accounts and invites.
344
+ `SESSIONS` is a `Map<token,login>` — a session knows *who* it is, and
345
+ `/api/me` reports that login, never a hardcoded one.
346
+ - **Where it lives:** `~/.config/ymir/accounts.json`, mode `0600`
347
+ (`YMIR_CONFIG_DIR` overrides, for tests). Machine state, never in the repo.
348
+ - **Passwords:** `Bun.password` argon2id via `Bun.password.hash/verify`. The
349
+ plaintext is never written; only the hash lands.
350
+ - **The operator's own tool:** `bin/ymir-invite.sh {mint,list,revoke,where,ensure}`.
351
+ `ensure` mints only when nothing is live, so the installer stays idempotent.
352
+ - **The UI:** `LoginModal` offers "I have an invite code" **only while
353
+ `/api/session.registration` is true**. A spent or revoked code removes the
354
+ offer, because the gate is what decides — the surface merely reports it.
355
+ - **Refusals are spoken:** the gate's own sentence ("that invite code has been
356
+ used up") is carried to the caller by `services/api.ts` (`errorText`), so the
357
+ login surface says what is actually wrong instead of a bare status.
358
+
359
+ ### Speed-starts inside the apps (added 2026-09-12)
360
+
361
+ Each app's own UI can raise the other one — `POST /api/desktop {view}`, valid for
362
+ `hlidskjalf` and `smidja`. Both servers implement it by calling
363
+ `scripts/electron.sh start --view <view>`, the same launcher the Omarchy key
364
+ bindings use, so there is **one** way to raise a Ymir window: it raises the app
365
+ when it is already up, and starts it when it is not. The visualizer finds the
366
+ checkout by walking up to the directory holding `scripts/electron.sh`, so it
367
+ works wherever the app is served from.
368
+
369
+ **rename sweep (2026-09-12).** The `galdr` -> `galdr-ymirsystem` rename corrected a stale path reference inside `apps/hlidskjalf/server/index.ts` as well; behaviour unchanged.
370
+
371
+ ### The gate's default realm is `wayof` (2026-09-12)
372
+
373
+ Three places in `apps/hlidskjalf/server/index.ts` defaulted to the retired name
374
+ `way-of` (the fleet event realm, the reviews realm, and a seeded lint review).
375
+ They now default to `wayof`, matching `svartalfaheim/README.md`: one company
376
+ container, no person realms. A retired realm name in a default is not cosmetic —
377
+ it sends an event to a directory the platform does not have.
378
+
379
+ ### Reviews now reads real pull requests (added 2026-09-13)
380
+
381
+ `/api/reviews` built exactly one synthetic card (`id: 'lint'`, `number: 1`,
382
+ "Brokk lint gate") from the lint + compliance checks — it **never read a pull
383
+ request**, so a delivered change had no Glitnir card and Mjollnir's PR leg had
384
+ nowhere to land. `reviews()` now first lists the repo's **open PRs** via
385
+ `gh pr list --json …` (mapping `statusCheckRollup` to the card's checks; a
386
+ failing check sets `state: 'changes'`), then appends the lint + compliance card
387
+ (now `number: 0`). Real PRs lead the list; the compile-and-lint card stays.
388
+ The review surface's operator copy now names the **Allfather** throughout — the
389
+ seal prompt, the rune emit string, the "awaiting the Allfather" tile, and the
390
+ gate comment — retiring the imported `captain` term.
391
+
392
+ ### One seat, three halls (added 2026-09-13)
393
+
394
+ - **Post-login chooser** (`src/components/Halls.tsx`): `App.tsx` shows it once
395
+ after the gate admits the session — three cards explaining Hlidskjalf, Smíðja,
396
+ and Sessrúmnir, each raising its hall.
397
+ - **Switcher**: `Halls.tsx` also exports `HallsSwitcher` (three rune buttons),
398
+ which replaces the lone Smíðja speed-start button in the Topbar. Smíðja's own
399
+ topbar and Sessrúmnir's menu carry matching switchers; all route through the
400
+ gate's `/api/desktop`, which now raises Sessrúmnir too (`bin/sessrumnir.sh`).
401
+ - **Search box**: `.topbar .search` `min-width` was 120px — narrower than the
402
+ text "Search work workspace…", so the placeholder clipped. Raised to 280px;
403
+ the input may shrink (`min-width: 0`).
404
+ - **One login, Sign out everywhere — verified live, never a file.** The gate is
405
+ the one authority: a session is an in-memory `token → login` map, handed out as
406
+ the httpOnly `ymir_session` cookie. There is **no bearer on disk** and **no
407
+ header credential** (`X-Ymir-Session`/`Bearer` are rejected): a persisted token
408
+ is a credential at rest any local process could replay, and a session read from
409
+ a file is "logged in when you are not". A gate restart ends sessions (nothing
410
+ revives one). Other surfaces verify live: the Smíðja visualizer server forwards
411
+ the browser's cookie to the gate's `/api/session`; Sessrúmnir, having no gate
412
+ cookie, shows a Sign-in link rather than claiming a session. Sign out clears the
413
+ cookie and the in-memory token (shell menu; AccountMenu).
414
+ - **The GitHub door is offered only when it can open**: `/api/auth/github`
415
+ returns 503 when no OAuth app is configured, so `/api/session` now carries
416
+ `github: !!(GITHUB_CLIENT_ID && GITHUB_CLIENT_SECRET)` and `LoginModal` renders
417
+ the "Continue with GitHub" button (and its `or` divider) only when true. The
418
+ password door (`HLIDSKJALF_AUTH`) is always present. Configure GitHub with
419
+ `bin/ymir-setup-auth.sh github`.
420
+
421
+ Rule: a Hlidskjalf code change updates this asset in the same pass — the
422
+ compliance gate (`assets/governed assets current`) fails otherwise.
423
+
424
+ ### The Hall door — one button out of the three halls (added 2026-09-13)
425
+
426
+ The **Óðrerir Live Hall** (the fleet's carved stone/bronze board; now its own
427
+ app at `apps/odrerir`, migrated from `~/CodeP/ymir-homepage` on 2026-09-15) is
428
+ **not** one of the gate's three apps but it IS its own desktop app since the
429
+ migration. The gate raises Hlidskjalf/Smíðja/Sessrúmnir (`/api/desktop` →
430
+ `scripts/electron.sh`); Óðrerir is raised with them by `scripts/start.sh` on
431
+ `:4322`, opens in its own window via `scripts/electron.sh start --view odrerir`
432
+ (native app identity `ymir-odrerir`), and its in-app door is a plain anchor in a
433
+ new tab — **never** a launcher call.
434
+
435
+ - **Where:** `app/Topbar.tsx` carries it beside `HallsSwitcher` — `.hall-btn`, the
436
+ rune **Othala (ᛟ)** plus "To the Hall", tinted with the active realm accent so
437
+ it reads as the same chrome as the chips around it. Styled in `styles/shell.css`
438
+ (tokens only, no raw hex), press feedback in `styles/overlays.css`.
439
+ - **The hall app:** `apps/odrerir` — an Astro board (the Óðrerir Live Hall) that
440
+ serves `:4322` and reads `public/livehall.json`, written by
441
+ `bin/hall-snapshot.sh` (planning glass; public-safe). Its own Electron shell:
442
+ `apps/odrerir/electron/main.cjs`, raised by `scripts/electron.sh --view odrerir`.
443
+ - **Target rule — one rule for all of Ymir's apps:** `HALL_URL` in
444
+ `src/data/metadata.ts`. `window.location.host` starting with `localhost` or
445
+ `127.0.0.1` → `http://localhost:4322`; any other host → the public
446
+ `https://hall.ymir.zerw.org`. `VITE_HALL_URL` overrides it, exactly as
447
+ `VISUALIZER_URL` does. Each app computes this inline — the Vite builds are
448
+ separate, so there is no shared module to hang it on.
449
+ - **Same door** in the Smíðja visualizer's topbar and in Sessrúmnir, so every
450
+ app's chrome has one way to the Hall.
451
+ - Verified: both branches of the rule in both apps (headless Chromium DOM probe),
452
+ `tsc --noEmit && vite build` green, 0 console errors; `apps/odrerir` builds
453
+ standalone and the hall answers `:4322` from `scripts/start.sh`.
454
+
455
+ ## Packaging (Amendment C)
456
+
457
+ Each app ships as its own published package under the `@zerwiz` scope (the scope
458
+ that already carries `@zerwiz/ymir`) — `@zerwiz/hlidskjalf`, `@zerwiz/odrerir`,
459
+ and `apps/hlidskjalf/package.json` carries the metadata that makes that legal:
460
+ `license`, `repository`, `publishConfig.access: public`, a `files` surface, and
461
+ `prepack` where a build exists (never `prepublishOnly`: a build must not be able
462
+ to veto a publish, and neither must a documentation gate).
463
+
464
+ Two facts worth keeping:
465
+
466
+ - **The APK is not in the tarball.** `apps/hlidskjalf/dist/ymir.apk` (~13.6 MB)
467
+ is built for Android, not for npm; `files` excludes it with `!dist/*.apk`.
468
+ Including it took the package from 1.3 MB to 14.5 MB — npm is not an APK
469
+ distribution channel.
470
+ - **`private: true` is the safety catch.** It stays set until the Allfather
471
+ publishes deliberately, so no accidental `npm publish` can push a half-built
472
+ artefact to a public registry.
473
+
474
+ Measured with `npm pack --dry-run --ignore-scripts` (see the app's `files` for
475
+ the exact surface).
476
+
477
+ ## The two doors — web logs in, the desktop seat does not
478
+
479
+ There is **one** login surface (`LoginModal` → `POST /api/login`), and it belongs
480
+ to the **web** door. The desktop shell (Electron) is a local, trusted seat and is
481
+ never asked to log in.
482
+
483
+ The mechanism is deliberately narrow, because a marker a client can send is not
484
+ proof of anything:
485
+
486
+ - the Electron preload exposes `window.ymirDesktop = { desktop: true }`;
487
+ - the SPA sends `x-ymir-surface: desktop` on every request, and
488
+ `?surface=desktop` on the SSE stream (EventSource cannot set headers);
489
+ - the gate (`server/index.ts`) honours that marker **only when the request
490
+ arrives over loopback** — `REQUEST_IP`, recorded per request from Bun's
491
+ `server.requestIP(req)`, because Bun's `Request` carries no socket. A remote
492
+ web caller can send the header and still be refused.
493
+
494
+ Verified both ways: `GET /api/session` without a cookie is `authed:false` and
495
+ `/api/orders` is 401; the same calls with the marker from 127.0.0.1 are
496
+ `authed:true` (login = the operator) and 200.