@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,154 @@
1
+ #!/usr/bin/env bash
2
+ # changelog-assemble.sh — fold CHANGELOG.d/ fragments into CHANGELOG.md.
3
+ #
4
+ # WHY THIS EXISTS
5
+ # CHANGELOG.md is one file, and every branch appends at the same position — the
6
+ # top. Git sees two branches inserting different lines at the same spot and
7
+ # calls it a conflict, so every merge re-conflicts every open branch. With N
8
+ # branches that is O(N^2) conflicts, all of them meaningless.
9
+ #
10
+ # A fragment directory removes the collision at the root: each change adds ONE
11
+ # file with a UNIQUE name, so two branches never touch the same file and can
12
+ # never conflict. This script folds the fragments into the ledger.
13
+ #
14
+ # THE LAW (RULES/06-append-only.md)
15
+ # Append, never rewrite. Never truncate. Never lose one in a move.
16
+ # A fragment is a new file; the ledger only ever grows. Folding is an append.
17
+ # CHANGELOG.d/ joins the append-only set, so a move must carry it.
18
+ #
19
+ # FRAGMENT FORMAT
20
+ # CHANGELOG.d/<YYYY-MM-DD>-<slug>.md — the entry exactly as it should appear in
21
+ # CHANGELOG.md, starting with its `## YYYY-MM-DD — title` heading.
22
+ #
23
+ # USAGE
24
+ # bin/changelog-assemble.sh # fold every fragment, newest first
25
+ # bin/changelog-assemble.sh --dry-run # report what would fold
26
+ # bin/changelog-assemble.sh --check # exit 1 if fragments are unfolded
27
+ #
28
+ # Exit: 0 ok, 1 error (or --check with fragments present), 2 usage.
29
+ set -euo pipefail
30
+
31
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
32
+ ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
33
+ FRAG_DIR="$ROOT/CHANGELOG.d"
34
+ LEDGER="$ROOT/CHANGELOG.md"
35
+
36
+ DRY=0; CHECK=0
37
+ for a in "$@"; do
38
+ case "$a" in
39
+ --dry-run) DRY=1 ;;
40
+ --check) CHECK=1 ;;
41
+ -h|--help) sed -n '2,26p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
42
+ *) printf 'error: unknown flag %s\nhelp: bin/changelog-assemble.sh [--dry-run|--check]\n' "$a" >&2; exit 2 ;;
43
+ esac
44
+ done
45
+
46
+ [ -f "$LEDGER" ] || { printf 'error: no ledger at %s\n' "$LEDGER" >&2; exit 1; }
47
+
48
+ # One python block owns the whole fold: regex, ordering, and the ledger's
49
+ # structure are all easier to get right in one language than split across awk,
50
+ # sed and shell — and an awk interval regex silently matched nothing, which
51
+ # duplicated the entire ledger.
52
+ ROOT="$ROOT" FRAG_DIR="$FRAG_DIR" LEDGER="$LEDGER" DRY="$DRY" CHECK="$CHECK" python3 - <<'PY'
53
+ import os, re, sys, glob
54
+
55
+ root = os.environ["ROOT"]
56
+ frag_dir = os.environ["FRAG_DIR"]
57
+ ledger = os.environ["LEDGER"]
58
+ dry = os.environ["DRY"] == "1"
59
+ check = os.environ["CHECK"] == "1"
60
+
61
+ HEADING = re.compile(r"^## (\d{4}-\d{2}-\d{2}) ")
62
+
63
+ # --- fragments -------------------------------------------------------------
64
+ frags = []
65
+ if os.path.isdir(frag_dir):
66
+ for p in sorted(glob.glob(os.path.join(frag_dir, "*.md"))):
67
+ if os.path.basename(p) == "README.md":
68
+ continue
69
+ frags.append(p)
70
+
71
+ if not frags:
72
+ if check:
73
+ sys.exit(0)
74
+ print('changelog-assemble[1]{fragments,folded,state}:')
75
+ print(' "0","0","none pending"')
76
+ sys.exit(0)
77
+
78
+ # A fragment must begin with its dated heading, or folding it would corrupt the
79
+ # ledger's structure.
80
+ bad = []
81
+ for p in frags:
82
+ first = open(p, encoding="utf-8").readline()
83
+ if not HEADING.match(first):
84
+ bad.append(os.path.relpath(p, root))
85
+ if bad:
86
+ for b in bad:
87
+ print(f'error: fragment has no dated heading: {b}', file=sys.stderr)
88
+ print('help: first line must be "## YYYY-MM-DD — title"', file=sys.stderr)
89
+ sys.exit(1)
90
+
91
+ def frag_date(p):
92
+ m = re.match(r"^(\d{4}-\d{2}-\d{2})", os.path.basename(p))
93
+ return m.group(1) if m else "0000-00-00"
94
+
95
+ # newest first; ties broken by name for determinism
96
+ frags.sort(key=lambda p: (frag_date(p), os.path.basename(p)), reverse=True)
97
+
98
+ if check:
99
+ print(f'changelog-assemble[{len(frags)}]{{fragment,state}}:')
100
+ for p in frags:
101
+ print(f' "{os.path.relpath(p, root)}","unfolded"')
102
+ print(f'error: {len(frags)} changelog fragment(s) not folded into CHANGELOG.md', file=sys.stderr)
103
+ print('help: run bin/changelog-assemble.sh', file=sys.stderr)
104
+ sys.exit(1)
105
+
106
+ if dry:
107
+ print(f'changelog-assemble[{len(frags)}]{{fragment,date}}:')
108
+ for p in frags:
109
+ print(f' "{os.path.relpath(p, root)}","{frag_date(p)}"')
110
+ print('changelog-assemble: dry run — nothing written')
111
+ sys.exit(0)
112
+
113
+ # --- the ledger ------------------------------------------------------------
114
+ text = open(ledger, encoding="utf-8").read()
115
+ lines = text.split("\n")
116
+
117
+ # preamble = everything before the first dated entry (the `# CHANGELOG` head)
118
+ split = None
119
+ for i, ln in enumerate(lines):
120
+ if HEADING.match(ln):
121
+ split = i
122
+ break
123
+ if split is None:
124
+ preamble = lines[:] # no dated entry yet: the whole file is preamble
125
+ existing = []
126
+ else:
127
+ preamble = lines[:split]
128
+ existing = lines[split:]
129
+
130
+ # trim trailing blanks from the preamble, then one blank separator
131
+ while preamble and preamble[-1].strip() == "":
132
+ preamble.pop()
133
+
134
+ # --- assemble: fragments first (newest at top), then the existing ledger ----
135
+ out = list(preamble)
136
+ out.append("")
137
+ for p in frags:
138
+ body = open(p, encoding="utf-8").read().rstrip("\n").split("\n")
139
+ out.extend(body)
140
+ out.append("")
141
+ out.append("")
142
+ out.extend(existing)
143
+
144
+ # collapse runs of 3+ blank lines to two (entry separation only — never content)
145
+ t = "\n".join(out)
146
+ t = re.sub(r"\n{3,}", "\n\n", t).rstrip("\n") + "\n"
147
+
148
+ open(ledger, "w", encoding="utf-8").write(t)
149
+ for p in frags:
150
+ os.remove(p)
151
+
152
+ print('changelog-assemble[1]{fragments,folded,ledger}:')
153
+ print(f' "{len(frags)}","{len(frags)}","CHANGELOG.md"')
154
+ PY
@@ -0,0 +1,197 @@
1
+ #!/usr/bin/env bash
2
+ # changelog-guard.sh — every push must carry a CHANGELOG entry.
3
+ #
4
+ # The house law: a change that ships is a change that was told. CHANGELOG.md is
5
+ # append-only (RULES/06-append-only.md) and is the record the operator reads
6
+ # after the fact. This guard refuses a push whose range never touches it, so the
7
+ # record can never lag silently behind the code.
8
+ #
9
+ # Two tiers, so a follow-up commit needs no micro-entry:
10
+ # 1. the pushed range (remote..local) touches CHANGELOG.md, or
11
+ # 2. the branch's whole range since it left the trunk does — the record is
12
+ # already told, and this push merely lands a file it describes.
13
+ # What can never pass is a branch whose entire range leaves with no entry.
14
+ #
15
+ # bin/changelog-guard.sh # pre-push: refs on stdin (hook mode)
16
+ # bin/changelog-guard.sh --range A..B # check one explicit range
17
+ # bin/changelog-guard.sh --install # wire pre-push (branch + changelog)
18
+ #
19
+ # Exit codes: 0 = a changelog entry is present (or nothing is being pushed),
20
+ # 1 = blocked, 2 = usage.
21
+ #
22
+ # Override (deliberate, loud): YMIR_SKIP_CHANGELOG_GUARD=1 git push …
23
+ set -u
24
+
25
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
26
+ ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
27
+ CHANGELOG="CHANGELOG.md"
28
+ # A change may tell its story either way: an entry appended to the ledger, or a
29
+ # fragment in CHANGELOG.d/ that the assembler will fold in. The fragment is the
30
+ # preferred form — two branches never touch the same fragment file, so the duty
31
+ # is met without the O(N^2) conflict every branch appending to one file causes.
32
+ FRAGMENT_DIR="CHANGELOG.d"
33
+ ZERO="0000000000000000000000000000000000000000"
34
+
35
+ usage() {
36
+ sed -n '2,16p' "$0" | sed 's/^# \{0,1\}//'
37
+ exit 2
38
+ }
39
+
40
+ # changes_touch_changelog <base> <head> — exit 0 when the change TELLS ITS STORY,
41
+ # either by appending to CHANGELOG.md or by adding a CHANGELOG.d/ fragment.
42
+ changes_touch_changelog() {
43
+ local base=${1-} head=${2-} f
44
+ [ -n "$head" ] || return 1
45
+ if [ -z "$base" ]; then
46
+ # No base to compare against (root commit range): look at every commit.
47
+ f="$(git -C "$ROOT" ls-tree -r --name-only "$head" -- "$CHANGELOG" 2>/dev/null)"
48
+ [ -n "$f" ] && return 0
49
+ f="$(git -C "$ROOT" ls-tree -r --name-only "$head" -- "$FRAGMENT_DIR" 2>/dev/null | grep -v '/README.md$' | grep '\.md$')"
50
+ [ -n "$f" ] && return 0
51
+ return 1
52
+ fi
53
+ git -C "$ROOT" diff --name-only "$base" "$head" -- "$CHANGELOG" 2>/dev/null | grep -q . && return 0
54
+ # A fragment ADDED in the range satisfies the duty. A fragment merely deleted
55
+ # (the assembler folding it into the ledger) does not count on its own — but in
56
+ # that same push the ledger changed, which the test above already caught.
57
+ git -C "$ROOT" diff --name-only --diff-filter=A "$base" "$head" -- "$FRAGMENT_DIR" 2>/dev/null \
58
+ | grep -v '/README.md$' | grep -q '\.md$' && return 0
59
+ return 1
60
+ }
61
+
62
+ # branch_touches_changelog <sha> — the branch's own range since it left the trunk.
63
+ # The fallback for a follow-up push: a commit that merely lands a file already
64
+ # told by an earlier entry is not a new untold change. What must never happen is
65
+ # a branch whose whole range leaves without an entry.
66
+ branch_touches_changelog() {
67
+ local sha=${1-} default_ref base
68
+ [ -n "$sha" ] || return 1
69
+ for default_ref in "origin/HEAD" "origin/main" "origin/master"; do
70
+ git -C "$ROOT" rev-parse --verify --quiet "$default_ref" >/dev/null 2>&1 || continue
71
+ base="$(git -C "$ROOT" merge-base "$sha" "$default_ref" 2>/dev/null || true)"
72
+ [ -n "$base" ] && { changes_touch_changelog "$base" "$sha" && return 0; return 1; }
73
+ done
74
+ return 1
75
+ }
76
+
77
+ # check_ref <local_sha> <remote_sha> — resolve the range and test it
78
+ check_ref() {
79
+ local local_sha=${1-} remote_sha=${2-} base="" default_ref=""
80
+ [ -n "$local_sha" ] || return 1
81
+ case "$local_sha" in "$ZERO") return 1 ;; esac # a deletion pushes no content
82
+
83
+ if [ -n "$remote_sha" ] && [ "$remote_sha" != "$ZERO" ]; then
84
+ base="$remote_sha"
85
+ else
86
+ # A brand-new remote branch: measure from where it forked off the trunk.
87
+ for default_ref in "origin/HEAD" "origin/main" "origin/master"; do
88
+ git -C "$ROOT" rev-parse --verify --quiet "$default_ref" >/dev/null 2>&1 || continue
89
+ base="$(git -C "$ROOT" merge-base "$local_sha" "$default_ref" 2>/dev/null || true)"
90
+ [ -n "$base" ] && break
91
+ done
92
+ fi
93
+ changes_touch_changelog "$base" "$local_sha" && return 0
94
+ # Nothing in THIS push told the record; the branch may yet have told it.
95
+ branch_touches_changelog "$local_sha"
96
+ }
97
+
98
+ verdict() { # <ok|blocked>
99
+ if [ "$1" = "ok" ]; then
100
+ printf 'changelog-guard[1]{gate,result}:\n "push","ok"\n'
101
+ exit 0
102
+ fi
103
+ cat >&2 <<'EOF'
104
+ changelog-guard: blocked — this push carries no CHANGELOG entry.
105
+
106
+ Every change that ships is a change that was told. Tell it either way:
107
+
108
+ PREFERRED — add a fragment (no conflict with any other branch):
109
+ CHANGELOG.d/<YYYY-MM-DD>-<slug>.md starting with "## YYYY-MM-DD — title"
110
+ bin/changelog-assemble.sh folds it into CHANGELOG.md
111
+
112
+ OR — append an entry to CHANGELOG.md under the current date
113
+ (append-only — never rewrite an existing entry; RULES/06-append-only.md).
114
+
115
+ Commit it, and push again.
116
+
117
+ Deliberate override, when an entry truly does not belong:
118
+ YMIR_SKIP_CHANGELOG_GUARD=1 git push ...
119
+ EOF
120
+ printf 'error: changelog-guard blocked the push (no CHANGELOG entry or fragment in range)\n' >&2
121
+ printf 'help: add a CHANGELOG.d/ fragment (preferred), or append to CHANGELOG.md; override with YMIR_SKIP_CHANGELOG_GUARD=1\n' >&2
122
+ exit 1
123
+ }
124
+
125
+ case "${1:-}" in
126
+ -v|-V|--version) printf '1.0.0\n'; exit 0 ;;
127
+ -h|--help) usage ;;
128
+ --install)
129
+ hook="$ROOT/.git/hooks/pre-push"
130
+ mkdir -p "$(dirname "$hook")" || exit 1
131
+ cat >"$hook" <<EOF
132
+ #!/usr/bin/env bash
133
+ # pre-push hook — the delivery gate. Installed by bin/changelog-guard.sh --install.
134
+ # 0. changelog-assemble — fold CHANGELOG.d/ fragments into CHANGELOG.md, so the
135
+ # ledger is never behind what the fragments already tell. Folding is an
136
+ # append: existing entries are copied verbatim, never reordered.
137
+ # 1. branch-guard — Rule 08: never push a protected branch
138
+ # 2. changelog-guard — every push carries a CHANGELOG entry (or a fragment)
139
+ set -u
140
+ refs="\$(mktemp)"
141
+ trap 'rm -f "\$refs"' EXIT
142
+ cat >"\$refs"
143
+ if [ -x "$SCRIPT_DIR/changelog-assemble.sh" ]; then
144
+ "$SCRIPT_DIR/changelog-assemble.sh" >/dev/null 2>&1 || true
145
+ # If folding changed the ledger, it is now a working-tree change the push does
146
+ # not carry. Say so loudly rather than pushing a ledger the fragments are not in.
147
+ if ! git -C "$ROOT" diff --quiet -- "$CHANGELOG" 2>/dev/null; then
148
+ printf 'changelog-assemble[1]{state}:\n "folded fragments into %s — commit it, then push again"\n' "$CHANGELOG" >&2
149
+ exit 1
150
+ fi
151
+ fi
152
+ "$SCRIPT_DIR/branch-guard.sh" <"\$refs" || exit 1
153
+ "$SCRIPT_DIR/changelog-guard.sh" <"\$refs" || exit 1
154
+ exit 0
155
+ EOF
156
+ chmod +x "$hook"
157
+ printf 'changelog-guard[1]{action,path}:\n "install","%s"\n' "$hook"
158
+ exit 0 ;;
159
+ --range)
160
+ rng="${2:-}"; [ -n "$rng" ] || usage
161
+ base="${rng%%..*}"; head="${rng##*..}"
162
+ changes_touch_changelog "$base" "$head" || verdict blocked
163
+ verdict ok ;;
164
+ --all)
165
+ # Every tracked CHANGELOG must exist and be non-empty.
166
+ [ -s "$ROOT/$CHANGELOG" ] || verdict blocked
167
+ verdict ok ;;
168
+ "") : ;;
169
+ *) usage ;;
170
+ esac
171
+
172
+ [ "${YMIR_SKIP_CHANGELOG_GUARD:-0}" = "1" ] && {
173
+ printf 'changelog-guard[1]{gate,result}:\n "push","skipped (YMIR_SKIP_CHANGELOG_GUARD=1)"\n'
174
+ exit 0
175
+ }
176
+
177
+ # Hook mode: the refs git hands a pre-push hook, one per line:
178
+ # <local_ref> <local_sha> <remote_ref> <remote_sha>
179
+ pushed=0
180
+ while read -r local_ref local_sha remote_ref remote_sha; do
181
+ [ -n "${local_ref:-}" ] || continue
182
+ case "$local_ref" in "$ZERO"|"") continue ;; esac
183
+ pushed=1
184
+ check_ref "$local_sha" "$remote_sha" && verdict ok
185
+ done
186
+
187
+ # Nothing pushable on stdin (a manual run): measure HEAD against the trunk.
188
+ if [ "$pushed" = "0" ]; then
189
+ for default_ref in "origin/main" "origin/master" "origin/HEAD"; do
190
+ git -C "$ROOT" rev-parse --verify --quiet "$default_ref" >/dev/null 2>&1 || continue
191
+ base="$(git -C "$ROOT" merge-base HEAD "$default_ref" 2>/dev/null || true)"
192
+ changes_touch_changelog "$base" "HEAD" && verdict ok
193
+ break
194
+ done
195
+ fi
196
+
197
+ verdict blocked
@@ -0,0 +1,173 @@
1
+ #!/usr/bin/env bash
2
+ # crash-sense.sh — surface machine crashes to the Allfather on Omarchy.
3
+ #
4
+ # A crash nobody sees is a crash nobody fixes. This watches systemd-coredump for
5
+ # NEW crashes since the last look, records each one, and raises an Omarchy desktop
6
+ # notification so the Allfather learns about it the moment it happens.
7
+ #
8
+ # It is a sensor: it reads coredumpctl and notifies. It never fixes, deletes, or
9
+ # changes anything on the machine.
10
+ #
11
+ # Usage:
12
+ # bin/crash-sense.sh check [--quiet] [--no-notify]
13
+ # bin/crash-sense.sh status
14
+ # bin/crash-sense.sh --version
15
+ #
16
+ # State: state/crash-seen.json (gitignored — per machine)
17
+ # Output: Galdr TOON.
18
+ set -u
19
+
20
+ VERSION="1.0.0"
21
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
22
+ ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
23
+
24
+ # The roots that live OUTSIDE the code tree: this machine's records and the
25
+ # runtime state belong to the home the operator chose at installation, never in
26
+ # the tree — a packaged install replaces its tree on upgrade (Rule 04).
27
+ if [ -z "${YMIR_HOARD_LIB_LOADED:-}" ]; then
28
+ _yr="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
29
+ for _yc in "$_yr/hoard-lib.sh" "$(dirname "$_yr")/bin/hoard-lib.sh"; do
30
+ [ -r "$_yc" ] && { . "$_yc"; YMIR_HOARD_LIB_LOADED=1; break; }
31
+ done
32
+ unset _yr _yc
33
+ fi
34
+ hoard_state_dir YMIR_STATE_DIR
35
+ hoard_data_dir YMIR_DATA_DIR
36
+ STATE_DIR="${BROKK_STATE_OVERRIDE:-$YMIR_STATE_DIR}"
37
+ SEEN="$STATE_DIR/crash-seen.json"
38
+ QUIET=0; NOTIFY=1
39
+
40
+ case "${1-}" in
41
+ -v|-V|--version) printf '%s\n' "$VERSION"; exit 0 ;;
42
+ -h|--help|"") sed -n '2,16p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
43
+ esac
44
+ ACTION="${1:-check}"; shift || true
45
+ while [ $# -gt 0 ]; do
46
+ case "$1" in
47
+ --quiet) QUIET=1; shift ;;
48
+ --no-notify) NOTIFY=0; shift ;;
49
+ *) shift ;;
50
+ esac
51
+ done
52
+
53
+ have() { command -v "$1" >/dev/null 2>&1; }
54
+ have coredumpctl || { printf 'crash-sense[1]{state,detail}:\n "skip","no coredumpctl (not a systemd host)"\n'; exit 0; }
55
+
56
+ # Collect recent crashes as: <boot-id>|<pid>|<comm>|<sig>|<time>
57
+ collect() {
58
+ coredumpctl list --no-pager --since "7 days ago" 2>/dev/null \
59
+ | awk 'NR>1 && NF>=5 {print $NF"|"$5"|"$1" "$2" "$3}' \
60
+ | head -200
61
+ }
62
+
63
+ # Use a stable identity for a crash: the executable name + pid + signal.
64
+ fingerprints() {
65
+ coredumpctl list --no-pager --since "7 days ago" 2>/dev/null | awk 'NR>1 {print $NF"|"$1"|"$2"|"$3"|"$4"|"$5}' | head -200
66
+ }
67
+
68
+ notify() { # <headline> <body> [urgency]
69
+ local h="$1" b="$2" u="${3:-normal}"
70
+ [ "$NOTIFY" = 1 ] || return 0
71
+ # One voice: bin/ymir-say.sh owns the desktop manner.
72
+ if [ -x "$ROOT/bin/ymir-say.sh" ]; then
73
+ local mark=note
74
+ [ "$u" = critical ] && mark=alarm
75
+ "$ROOT/bin/ymir-say.sh" --mark "$mark" "$h" "$b" >/dev/null 2>&1 || true
76
+ return 0
77
+ fi
78
+ if have omarchy-notification-send; then
79
+ omarchy-notification-send -u "$u" -g "" "$h" "$b" >/dev/null 2>&1 || true
80
+ elif have notify-send; then
81
+ notify-send -u "$u" "$h" "$b" >/dev/null 2>&1 || true
82
+ fi
83
+ }
84
+
85
+ case "$ACTION" in
86
+ check)
87
+ mkdir -p "$STATE_DIR"
88
+ local_prev="{}"
89
+ [ -r "$SEEN" ] && local_prev="$(cat "$SEEN")"
90
+
91
+ # New fingerprints = anything not in the seen set.
92
+ new_rows="$(python3 - "$SEEN" <<'PY'
93
+ import json, os, subprocess, sys
94
+ seen_path = sys.argv[1]
95
+ seen = set()
96
+ if os.path.exists(seen_path):
97
+ try:
98
+ seen = set(json.load(open(seen_path)).get("fingerprints", []))
99
+ except Exception:
100
+ seen = set()
101
+ out = subprocess.run(["coredumpctl", "list", "--no-pager", "--since", "7 days ago"],
102
+ capture_output=True, text=True).stdout.splitlines()[1:]
103
+ new = []
104
+ all_fp = []
105
+ for line in out:
106
+ parts = line.split()
107
+ if len(parts) < 5:
108
+ continue
109
+ # TIME is 3 tokens (date, clock, tz); then PID UID GID SIG COREFILE EXE
110
+ date, clock, tz = parts[0], parts[1], parts[2]
111
+ rest = parts[3:]
112
+ pid = rest[0] if rest else "?"
113
+ comm = os.path.basename(rest[-1]) if rest else "?"
114
+ sig = rest[3] if len(rest) > 3 else "?"
115
+ fp = f"{pid}|{comm}|{sig}|{date} {clock}"
116
+ all_fp.append(fp)
117
+ if fp not in seen:
118
+ new.append({"pid": pid, "comm": comm, "sig": sig, "when": f"{date} {clock}", "fp": fp})
119
+ print(json.dumps({"new": new, "all": all_fp}))
120
+ PY
121
+ )"
122
+ count="$(printf '%s' "$new_rows" | python3 -c 'import json,sys; print(len(json.load(sys.stdin)["new"]))' 2>/dev/null || echo 0)"
123
+
124
+ if [ "$count" -gt 0 ]; then
125
+ # One notification per crash, newest first, capped so we never spam.
126
+ printf '%s' "$new_rows" | python3 -c '
127
+ import json, sys
128
+ d = json.load(sys.stdin)["new"]
129
+ for c in d[-3:]:
130
+ print(c["comm"] + "\t" + c["sig"] + "\t" + c["when"] + "\t" + c["pid"])
131
+ ' | while IFS=$'\t' read -r comm sig when pid; do
132
+ notify "Process crashed: $comm" "$sig at $when (pid $pid) — run bin/crash-sense.sh status, or ask Brokk to diagnose." "critical"
133
+ done
134
+ fi
135
+
136
+ # Persist the union as the new seen set (feed the captured string, not a pipe).
137
+ printf '%s' "$new_rows" >"$STATE_DIR/.crash-new.json"
138
+ python3 - "$SEEN" "$STATE_DIR/.crash-new.json" <<'PY'
139
+ import json, sys, tempfile, os, datetime
140
+ path, src = sys.argv[1], sys.argv[2]
141
+ d = json.load(open(src))
142
+ payload = {
143
+ "fingerprints": d["all"],
144
+ "updated_at": datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
145
+ }
146
+ fd, tmp = tempfile.mkstemp(dir=os.path.dirname(path) or ".")
147
+ with os.fdopen(fd, "w") as f:
148
+ json.dump(payload, f, indent=2)
149
+ os.replace(tmp, path)
150
+ PY
151
+ rm -f "$STATE_DIR/.crash-new.json"
152
+
153
+ [ "$QUIET" = 1 ] && exit 0
154
+ printf 'crash-sense[1]{new_crashes,notified,since}:\n %s,"%s","7 days"\n' "$count" "$([ "$count" -gt 0 ] && echo yes || echo no)"
155
+ if [ "$count" -gt 0 ]; then
156
+ printf '%s' "$new_rows" | python3 -c '
157
+ import json, sys
158
+ for c in json.load(sys.stdin)["new"][-5:]:
159
+ print(f'"'"' "{c["comm"]}","{c["sig"]}","{c["when"]}","pid {c["pid"]}"'"'"')
160
+ ' 2>/dev/null | sed '1i crashes[]:' || true
161
+ fi
162
+ ;;
163
+
164
+ status)
165
+ if have coredumpctl; then
166
+ total="$(coredumpctl list --no-pager --since "7 days ago" 2>/dev/null | awk 'NR>1' | wc -l | tr -d ' ')"
167
+ printf 'crash-sense[1]{window,total_crashes,state_file}:\n "7 days",%s,"%s"\n' "$total" "${SEEN#"$ROOT"/}"
168
+ coredumpctl list --no-pager --since "7 days ago" 2>/dev/null | awk 'NR>1 {print $NF}' | sort | uniq -c | sort -rn | head -5 | \
169
+ awk '{printf " \"%s\",%s\n", $2, $1}'
170
+ fi
171
+ ;;
172
+ *) printf 'error: unknown action %s\nhelp: bin/crash-sense.sh [check|status]\n' "$ACTION" >&2; exit 2 ;;
173
+ esac
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env bash
2
+ # design-check.sh — one identity, two renderers: they must agree.
3
+ #
4
+ # The design language is the landing page's cloth (stone · bone · bronze ·
5
+ # blood). It is carried in TWO places, on purpose:
6
+ #
7
+ # midgard/design-system/tokens.css the CSS variables every web surface imports
8
+ # apps/sessrumnir/…/themes/fensalir.json the seven SEEDS the seat derives ~40
9
+ # tokens from (the reference form)
10
+ #
11
+ # Two carriers of one identity drift the moment someone edits one. This is the
12
+ # guard: the same value must appear in both, or the build says so.
13
+ #
14
+ # Usage:
15
+ # bin/design-check.sh # compare, TOON, exit 0/1
16
+ # bin/design-check.sh --fix-hint
17
+ set -u
18
+
19
+ VERSION="1.0.0"
20
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
21
+ ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
22
+ TOKENS="$ROOT/midgard/design-system/tokens.css"
23
+ SEEDS="$ROOT/apps/sessrumnir/src/renderer/src/themes/fensalir.json"
24
+
25
+ case "${1-}" in
26
+ -v|-V|--version) printf '%s\n' "$VERSION"; exit 0 ;;
27
+ -h|--help) sed -n '2,18p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
28
+ esac
29
+
30
+ [ -r "$TOKENS" ] || { printf 'error: tokens not found: %s\n' "${TOKENS#"$ROOT"/}" >&2; exit 1; }
31
+ # The seat's cloth lives in the Sessrúmnir app repo (the apps split moved it out
32
+ # of the monorepo; `step_apps` clones it). In a fresh clone or a worktree it is
33
+ # absent until that step runs — so an absent seat is a clean SKIP, not a failure.
34
+ # Two carriers can only be compared when both are present; demanding the app's
35
+ # file would fail every worktree for a reason that is not drift.
36
+ if [ ! -r "$SEEDS" ]; then
37
+ printf 'design[1]{state,reason}:\n'
38
+ printf ' "SKIP","the seat'"'"'s cloth is app-provided (%s) — run bin/ymir-install.sh step_apps"\n' "${SEEDS#"$ROOT"/}"
39
+ exit 0
40
+ fi
41
+
42
+ # the pairs that MUST agree: CSS token <-> seed
43
+ python3 - "$TOKENS" "$SEEDS" <<'PY'
44
+ import json, re, sys
45
+
46
+ tokens_path, seeds_path = sys.argv[1], sys.argv[2]
47
+ css = open(tokens_path).read()
48
+ seeds = json.load(open(seeds_path))["seeds"]
49
+
50
+ def token(name):
51
+ m = re.search(r"--%s:\s*([^;]+);" % re.escape(name), css)
52
+ return m.group(1).strip() if m else None
53
+
54
+ PAIRS = [
55
+ ("ymir-bg-0", "app", "the ground"),
56
+ ("ymir-bg-1", "surface", "the panel"),
57
+ ("ymir-text-0", "text", "the bone"),
58
+ ("ymir-cyan-1", "accent", "the bronze"),
59
+ ("ymir-ok", "success", "the metal proved true"),
60
+ ("ymir-warn", "warning", "hot, heed it"),
61
+ ("ymir-danger", "error", "the wound"),
62
+ ]
63
+
64
+ bad = []
65
+ print("design[%d]{css_token,seed,value,agreement}:" % len(PAIRS))
66
+ for tok, seed, label in PAIRS:
67
+ a, b = token(tok), (seeds.get(seed) or "").lower()
68
+ ok = a is not None and a.lower() == b
69
+ if not ok:
70
+ bad.append((tok, seed, a, b))
71
+ print(' "%s","%s","%s","%s"' % (tok, seed, a or "-", "ok" if ok else "MISMATCH (seed %s)" % (b or "-")))
72
+
73
+ if bad:
74
+ print("error: the two carriers of the cloth disagree", file=sys.stderr)
75
+ for tok, seed, a, b in bad:
76
+ print(" --%s = %s ≠ seeds.%s = %s" % (tok, a, seed, b), file=sys.stderr)
77
+ print("help: change the value in midgard/design-system/tokens.css AND fensalir.json, or neither", file=sys.stderr)
78
+ sys.exit(1)
79
+ print("design-check: the cloth is one — %d pairs agree" % len(PAIRS))
80
+ PY