@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,543 @@
1
+ #!/usr/bin/env bash
2
+ # tests/fm-classify-corr-token.test.sh - a status line may carry the correlation
3
+ # token bin/fm-pending-reply-lib.sh embeds in a marked request and a secondmate
4
+ # echoes back (bin/fm-brief.sh), between the verb and the rest of the line. Every
5
+ # verb-driven classification must read straight through that token, in BOTH
6
+ # directions: a verb parse that keeps the token glued on matches no arm of the
7
+ # decision fold, so the opener never opens, the closer never closes, and a
8
+ # decision the captain is owed never reaches him.
9
+ #
10
+ # The parse is deliberately strict, and these tests defend that strictness as
11
+ # hard as they defend the fix: only the exact token a firstmate library writes is
12
+ # read through. Prose, a malformed or wrong-length token, and an arbitrary
13
+ # name=value word all keep their extra words and therefore stay non-transitions.
14
+ #
15
+ # Coverage is split by the interface each claim lives behind: the fold is driven
16
+ # through the REAL bin/fm-wake-drain.sh, the classifier predicates through the
17
+ # library's own sourced entry points (as tests/fm-watch-triage.test.sh does), and
18
+ # the token grammar itself is pinned against the REAL writers so this library's
19
+ # second statement of the shape cannot drift from the one that owns it.
20
+ set -u
21
+
22
+ # shellcheck source=tests/wake-helpers.sh
23
+ . "$(dirname "${BASH_SOURCE[0]}")/wake-helpers.sh"
24
+ # shellcheck source=/dev/null
25
+ . "$ROOT/bin/fm-classify-lib.sh"
26
+
27
+ DRAIN="$ROOT/bin/fm-wake-drain.sh"
28
+ REPORT="$ROOT/bin/fm-secondmate-report.sh"
29
+
30
+ TMP_ROOT=$(fm_test_tmproot fm-classify-corr-token-tests)
31
+
32
+ # A syntactically valid correlation token payload: 16 hex characters.
33
+ CORR=c44897ee2db4326b
34
+ CORR2=7ab3e5dd13c9a993
35
+
36
+ # Print the drain's OPEN DECISIONS view of <state>, or the empty string when the
37
+ # drain reports nothing open. Keeps each case's assertions about the CONTRACT
38
+ # (which decisions are open) rather than about the section's layout.
39
+ drain_open() { # <state> <out>
40
+ local state=$1 out=$2
41
+ FM_STATE_OVERRIDE="$state" "$DRAIN" > "$out" || fail "drain failed over $state"
42
+ grep -F 'OPEN DECISIONS' "$out" >/dev/null || return 0
43
+ cat "$out"
44
+ }
45
+
46
+ # --- the fold, both directions ----------------------------------------------
47
+
48
+ test_tokened_opener_opens_and_tokened_closer_closes() {
49
+ local dir state out view
50
+ dir=$(make_case tokened-both-directions)
51
+ state="$dir/state"
52
+ out="$dir/drain.out"
53
+
54
+ # OPENER. The half that loses a captain decision outright: it never appears in
55
+ # any listing, so nobody knows it is owed.
56
+ printf 'needs-decision corr=%s [key=texte-du-mur]: propose the wall text\n' "$CORR" \
57
+ > "$state/task-open.status"
58
+ view=$(drain_open "$state" "$out")
59
+ case "$view" in
60
+ *'task-open'*'[key=texte-du-mur]'*'propose the wall text'*) : ;;
61
+ *) fail "a needs-decision carrying a correlation token did not open its key: $view" ;;
62
+ esac
63
+
64
+ # CLOSER. The half that leaves an answered decision on the captain's board.
65
+ printf 'resolved corr=%s [key=texte-du-mur]: captain chose the third wording\n' "$CORR" \
66
+ >> "$state/task-open.status"
67
+ view=$(drain_open "$state" "$out")
68
+ case "$view" in
69
+ *'texte-du-mur'*) fail "a resolved carrying a correlation token did not close its key: $view" ;;
70
+ esac
71
+
72
+ # A blocked opener and a captain-held transfer close the same way.
73
+ printf 'blocked corr=%s [key=sortie-plan]: the only lever exceeds the ruling\n' "$CORR2" \
74
+ > "$state/task-blocked.status"
75
+ view=$(drain_open "$state" "$out")
76
+ case "$view" in
77
+ *'task-blocked'*'[key=sortie-plan]'*) : ;;
78
+ *) fail "a blocked carrying a correlation token did not open its key: $view" ;;
79
+ esac
80
+ printf 'captain-held corr=%s [key=sortie-plan]: tracked as a captain hold\n' "$CORR2" \
81
+ >> "$state/task-blocked.status"
82
+ view=$(drain_open "$state" "$out")
83
+ case "$view" in
84
+ *'sortie-plan'*) fail "a captain-held carrying a correlation token did not close its key: $view" ;;
85
+ esac
86
+
87
+ pass "a correlation token between the verb and the key breaks neither opening nor closing"
88
+ }
89
+
90
+ test_token_is_read_through_in_every_position_it_is_written_in() {
91
+ local dir state out view
92
+ dir=$(make_case token-positions)
93
+ state="$dir/state"
94
+ out="$dir/drain.out"
95
+
96
+ # Before the key, after the key, with no key at all, twice on one line (a
97
+ # recovery turn re-embedding), and in the bracketed shape the optional
98
+ # bin/fm-secondmate-report.sh helper writes. Every one is a real observed shape.
99
+ printf 'needs-decision corr=%s [key=before]: token ahead of the key\n' "$CORR" > "$state/t1.status"
100
+ printf 'needs-decision [key=after] corr=%s: token behind the key\n' "$CORR" > "$state/t2.status"
101
+ printf 'blocked corr=%s: token and no key at all\n' "$CORR" > "$state/t3.status"
102
+ printf 'needs-decision corr=%s corr=%s [key=twice]: two tokens on one line\n' "$CORR" "$CORR2" \
103
+ > "$state/t4.status"
104
+ printf 'needs-decision [corr=%s]: the helper bracket shape\n' "$CORR" > "$state/t5.status"
105
+
106
+ view=$(drain_open "$state" "$out")
107
+ case "$view" in *'t1'*'[key=before]'*) ;; *) fail "token before the key did not open: $view" ;; esac
108
+ case "$view" in *'t2'*'[key=after]'*) ;; *) fail "token after the key did not open: $view" ;; esac
109
+ # The drain prints the default key as a bare verb, with no [key=...] segment.
110
+ case "$view" in *'t3 blocked:'*) ;; *) fail "token with no key did not open the default key: $view" ;; esac
111
+ case "$view" in *'t4'*'[key=twice]'*) ;; *) fail "two tokens on one line did not open: $view" ;; esac
112
+ case "$view" in *'t5 needs-decision:'*) ;; *) fail "the bracketed helper token did not open: $view" ;; esac
113
+
114
+ # ...and each closes from the same position.
115
+ printf 'resolved corr=%s [key=before]: closed\n' "$CORR" >> "$state/t1.status"
116
+ printf 'resolved [key=after] corr=%s: closed\n' "$CORR" >> "$state/t2.status"
117
+ printf 'resolved corr=%s: closed\n' "$CORR" >> "$state/t3.status"
118
+ printf 'resolved corr=%s corr=%s [key=twice]: closed\n' "$CORR" "$CORR2" >> "$state/t4.status"
119
+ printf 'resolved [corr=%s]: closed\n' "$CORR" >> "$state/t5.status"
120
+
121
+ view=$(drain_open "$state" "$out")
122
+ [ -z "$view" ] || fail "a correlated closer failed to close from some position: $view"
123
+
124
+ pass "the token is read through before the key, after it, doubled, bracketed, and unkeyed"
125
+ }
126
+
127
+ test_untokened_pair_is_unchanged() {
128
+ local dir state out view
129
+ dir=$(make_case untokened-pair)
130
+ state="$dir/state"
131
+ out="$dir/drain.out"
132
+
133
+ # The same pair with no token at all, keyed and bare: the historical behavior
134
+ # this change must leave exactly as it was.
135
+ printf 'needs-decision [key=api-shape]: pick REST or RPC\n' > "$state/keyed.status"
136
+ printf 'blocked: no key at all\n' > "$state/bare.status"
137
+ view=$(drain_open "$state" "$out")
138
+ case "$view" in *'keyed'*'[key=api-shape]'*) ;; *) fail "an untokened keyed opener regressed: $view" ;; esac
139
+ case "$view" in *'bare blocked:'*) ;; *) fail "an untokened bare opener regressed: $view" ;; esac
140
+
141
+ printf 'resolved [key=api-shape]: went with REST\n' >> "$state/keyed.status"
142
+ printf 'resolved: cleared on its own\n' >> "$state/bare.status"
143
+ view=$(drain_open "$state" "$out")
144
+ [ -z "$view" ] || fail "an untokened closer regressed: $view"
145
+
146
+ pass "the untokened opener/closer pair behaves exactly as before"
147
+ }
148
+
149
+ # --- the strictness the parse exists for ------------------------------------
150
+
151
+ test_prose_and_malformed_tokens_never_become_transitions() {
152
+ local dir state out view line
153
+ dir=$(make_case no-prose-takeover)
154
+ state="$dir/state"
155
+ out="$dir/drain.out"
156
+
157
+ # Every one of these must stay a non-transition. If any became a verb, free
158
+ # text would be able to open decisions nobody raised - or silently close one
159
+ # the captain is owed, which is the takeover this strictness exists to stop.
160
+ #
161
+ # All of these are UNBRACKETED, which is the shape this parser owns. A
162
+ # BRACKETED tag is deliberately NOT listed: verb parsing ends at the first
163
+ # "[", so "resolved [corr=deadbeef] [key=victim]:" reads as the bare verb
164
+ # "resolved" and does close the decision. That is the tag rule's own
165
+ # contract, not a gap in this one, and tightening it here would silently
166
+ # narrow a separately reviewed rule. The strictness below is what keeps an
167
+ # unbracketed token honest, and a bracketed impostor still has to get a
168
+ # well-formed key past _fm_decision_key_transition_allowed.
169
+ local -a impostors=(
170
+ 'resolved the corr= issue yesterday [key=victim]'
171
+ 'resolved corr= [key=victim]'
172
+ 'resolved corr=deadbeef [key=victim]'
173
+ 'resolved corr=abcdef0123456789ab [key=victim]'
174
+ 'resolved corr=ZZZZbeefdeadbeef [key=victim]'
175
+ 'resolved xcorr=c44897ee2db4326b [key=victim]'
176
+ 'resolved corr=c44897ee2db4326 [key=victim]'
177
+ 'resolved anything=whatever [key=victim]'
178
+ 'resolved and then corr=c44897ee2db4326b happened [key=victim]'
179
+ )
180
+
181
+ # Each impostor gets its own task log, and every log is only ever appended to,
182
+ # the way a real status file is written. All of them are then folded in ONE
183
+ # drain, so a single pass proves every case at once.
184
+ local i=0
185
+ for line in "${impostors[@]}"; do
186
+ printf 'needs-decision [key=victim]: a real captain decision\n' > "$state/close-$i.status"
187
+ printf '%s: free text that must not close it\n' "$line" >> "$state/close-$i.status"
188
+ # The same shape must not OPEN one either.
189
+ printf '%s: free text that must not open anything\n' "${line/resolved/needs-decision}" \
190
+ > "$state/open-$i.status"
191
+ i=$((i + 1))
192
+ done
193
+
194
+ view=$(drain_open "$state" "$out")
195
+ i=0
196
+ for line in "${impostors[@]}"; do
197
+ case "$view" in
198
+ *"close-$i [key=victim] needs-decision: a real captain decision"*) : ;;
199
+ *) fail "an impostor closed a real decision: '$line' -> $view" ;;
200
+ esac
201
+ case "$view" in
202
+ *"open-$i "*) fail "an impostor opened a decision nobody raised: '$line' -> $view" ;;
203
+ esac
204
+ i=$((i + 1))
205
+ done
206
+
207
+ # A note mentioning the token AFTER the colon is ordinary prose and touches
208
+ # nothing, whichever verb carries it.
209
+ printf 'needs-decision [key=noted]: see corr=c44897ee2db4326b in the thread\n' > "$state/noted.status"
210
+ printf 'working: chasing corr=c44897ee2db4326b through the log\n' >> "$state/noted.status"
211
+ printf 'done: resolved corr=c44897ee2db4326b in passing\n' >> "$state/noted.status"
212
+ view=$(drain_open "$state" "$out")
213
+ case "$view" in
214
+ *'noted'*'[key=noted]'*) : ;;
215
+ *) fail "a token quoted inside notes disturbed the fold: $view" ;;
216
+ esac
217
+
218
+ pass "prose, malformed, wrong-length and unknown name=value tokens stay non-transitions"
219
+ }
220
+
221
+ test_token_first_word_never_impersonates_a_transition() {
222
+ local dir state out view
223
+ dir=$(make_case token-first)
224
+ state="$dir/state"
225
+ out="$dir/drain.out"
226
+
227
+ printf 'corr=%s needs-decision [key=token-first-needs]: prose\n' "$CORR" \
228
+ > "$state/token-first-needs.status"
229
+ printf 'corr=%s blocked [key=token-first-blocked]: prose\n' "$CORR" \
230
+ > "$state/token-first-blocked.status"
231
+
232
+ printf 'needs-decision [key=stays-open-resolved]: a real captain decision\n' \
233
+ > "$state/token-first-resolved.status"
234
+ printf 'corr=%s resolved [key=stays-open-resolved]: prose\n' "$CORR" \
235
+ >> "$state/token-first-resolved.status"
236
+
237
+ printf 'blocked [key=stays-open-held]: a real captain blocker\n' \
238
+ > "$state/token-first-held.status"
239
+ printf 'corr=%s captain-held [key=stays-open-held]: prose\n' "$CORR" \
240
+ >> "$state/token-first-held.status"
241
+
242
+ view=$(drain_open "$state" "$out")
243
+ case "$view" in
244
+ *'token-first-needs '*) fail "a token-first needs-decision opened a decision: $view" ;;
245
+ esac
246
+ case "$view" in
247
+ *'token-first-blocked '*) fail "a token-first blocked opened a decision: $view" ;;
248
+ esac
249
+ case "$view" in
250
+ *'token-first-resolved'*'[key=stays-open-resolved]'*'a real captain decision'*) : ;;
251
+ *) fail "a token-first resolved closed a real decision: $view" ;;
252
+ esac
253
+ case "$view" in
254
+ *'token-first-held'*'[key=stays-open-held]'*'a real captain blocker'*) : ;;
255
+ *) fail "a token-first captain-held closed a real blocker: $view" ;;
256
+ esac
257
+
258
+ pass "a token-first line cannot impersonate any opening or closing verb"
259
+ }
260
+
261
+ # --- every other status_line_verb consumer ----------------------------------
262
+
263
+ test_captain_relevance_and_pause_are_unchanged_without_a_token() {
264
+ # Pinned verdicts for the untokened shapes. These are the historical answers;
265
+ # the fast path in status_line_verb returns such a prefix byte-for-byte, so
266
+ # this is the regression wall for every consumer at once.
267
+ status_is_captain_relevant 'done: shipped' || fail "done: regressed"
268
+ status_is_captain_relevant 'needs-decision [key=q1]: pick one' || fail "keyed needs-decision regressed"
269
+ status_is_captain_relevant 'blocked: stuck' || fail "blocked: regressed"
270
+ status_is_captain_relevant 'failed: gave up' || fail "failed: regressed"
271
+ status_is_captain_relevant 'working: still going' && fail "working: regressed to captain-relevant"
272
+ status_is_captain_relevant 'working: rebased onto merged #76' \
273
+ && fail "nonterminal free-text guard regressed"
274
+ status_is_captain_relevant 'merged' || fail "legacy bare free-text regressed"
275
+ status_is_captain_relevant 'resolved [key=q1]: answered' && fail "resolved regressed to captain-relevant"
276
+
277
+ status_is_paused 'paused: waiting on the upstream release' || fail "paused: regressed"
278
+ status_is_paused ' paused: waiting on a reset' || fail "spaced paused: regressed"
279
+ status_is_paused 'blocked: the build is paused upstream' && fail "paused-in-prose regressed"
280
+ status_is_paused 'working: paused the animation loop' && fail "paused-in-prose regressed"
281
+ status_is_paused '' && fail "empty line regressed"
282
+
283
+ status_is_terminal_verb 'done: shipped' || fail "terminal verb regressed"
284
+ status_is_terminal_verb 'working: rebased onto merged #76' && fail "nonterminal terminal-verb regressed"
285
+ status_is_paused_or_captain_held 'captain-held [key=r]: tracked' || fail "captain-held regressed"
286
+ status_is_paused_or_captain_held 'resolved [key=r]: answered' && fail "resolved regressed"
287
+
288
+ pass "untokened captain-relevance, pause, terminal-verb and captain-held verdicts are unchanged"
289
+ }
290
+
291
+ test_consumer_verdicts_read_through_the_token() {
292
+ # A token must not hide a captain-facing event from the supervisors, and must
293
+ # not let a nonterminal line be escalated as one. Both were live: an untreated
294
+ # token made "done corr=...: PR ready" invisible to the terminal-verb test,
295
+ # while "working corr=...: rebased onto merged #76" leaked through the
296
+ # free-text fallback the nonterminal guard was supposed to stop.
297
+ status_is_captain_relevant "done corr=$CORR: shipped" \
298
+ || fail "a correlated done is not captain-relevant"
299
+ status_is_captain_relevant "needs-decision corr=$CORR [key=q]: pick one" \
300
+ || fail "a correlated needs-decision is not captain-relevant"
301
+ status_is_captain_relevant "blocked corr=$CORR: stuck" \
302
+ || fail "a correlated blocked is not captain-relevant"
303
+ status_is_captain_relevant "done [corr=$CORR]: shipped via the helper" \
304
+ || fail "a helper-bracketed done is not captain-relevant"
305
+
306
+ status_is_terminal_verb "done corr=$CORR: shipped" \
307
+ || fail "a correlated done is not a terminal verb"
308
+ status_is_terminal_verb "working corr=$CORR: still going" \
309
+ && fail "a correlated working became a terminal verb"
310
+
311
+ status_is_captain_relevant "working corr=$CORR: rebased onto merged #76" \
312
+ && fail "a correlated working leaked through the free-text fallback"
313
+ status_is_captain_relevant "resolved corr=$CORR [key=q]: answered" \
314
+ && fail "a correlated resolved leaked through the free-text fallback"
315
+
316
+ # The pause and captain-held declarations the watcher reads to leave a
317
+ # deliberately idle endpoint alone instead of aging it as a possible wedge.
318
+ status_is_paused "paused corr=$CORR: waiting on the upstream release" \
319
+ || fail "a correlated pause was not recognised as a declared external wait"
320
+ status_is_paused_or_captain_held "captain-held corr=$CORR [key=r]: tracked as a hold" \
321
+ || fail "a correlated captain-held was not recognised"
322
+ status_is_paused "blocked corr=$CORR: the build is paused upstream" \
323
+ && fail "a correlated blocked mentioning paused false-matched"
324
+
325
+ pass "captain-relevance, terminal-verb, pause and captain-held all read through the token"
326
+ }
327
+
328
+ test_daemon_and_crew_state_case_arms_read_through_the_token() {
329
+ # Two consumers switch on the verb STRING rather than on a helper, so they
330
+ # cannot be proven through status_is_*: bin/fm-supervise-daemon.sh matches
331
+ # working|resolved|captain-held to take the transient-stale path instead of
332
+ # the terminal one, and bin/fm-crew-state.sh's map_log_state maps each verb to
333
+ # a run state, falling through to "unknown" on anything else.
334
+ #
335
+ # Before this fix a correlated line matched no arm of either: a correlated
336
+ # working line was escalated as terminally stale, and every correlated line
337
+ # read as run state "unknown". Pin the exact strings those arms compare
338
+ # against, for both the tokened and untokened spellings.
339
+ local verb
340
+ for verb in working resolved captain-held; do
341
+ [ "$(status_line_verb "$verb corr=$CORR [key=k]: note")" = "$verb" ] \
342
+ || fail "the daemon transient-stale arm no longer matches a correlated $verb"
343
+ [ "$(status_line_verb "$verb [key=k]: note")" = "$verb" ] \
344
+ || fail "the daemon transient-stale arm regressed for an untokened $verb"
345
+ done
346
+ for verb in working needs-decision blocked 'done' failed; do
347
+ [ "$(status_line_verb "$verb corr=$CORR: note")" = "$verb" ] \
348
+ || fail "map_log_state would still read a correlated $verb as unknown"
349
+ [ "$(status_line_verb "$verb: note")" = "$verb" ] \
350
+ || fail "map_log_state regressed for an untokened $verb"
351
+ done
352
+
353
+ # The same arms must stay closed to prose and to a malformed token, or a
354
+ # stuck worker could dodge a stale escalation by writing one.
355
+ [ "$(status_line_verb "working the corr= thing [key=k]: prose")" = working ] \
356
+ && fail "prose reduced to a bare working verb"
357
+ [ "$(status_line_verb "working corr=deadbeef [key=k]: malformed")" = working ] \
358
+ && fail "a malformed token reduced to a bare working verb"
359
+
360
+ pass "the daemon and crew-state verb case arms read through the token"
361
+ }
362
+
363
+ test_pending_reply_escalation_matching_is_unaffected() {
364
+ # bin/fm-pending-reply-lib.sh filters a status file by verb when looking for
365
+ # the escalation IT published, then whole-line matches its own exact payload.
366
+ # Reading through the token widens the verb filter, so this pins that the exact
367
+ # match behind it still refuses everything that is not that library's own line.
368
+ local dir state out view
369
+ dir=$(make_case pending-reply-namespace)
370
+ state="$dir/state"
371
+ out="$dir/drain.out"
372
+
373
+ # The reserved namespace may only be opened by a note speaking its vocabulary.
374
+ # A correlated line must not become a way around that. Each claim gets its own
375
+ # append-only log so one drain proves both.
376
+ printf 'blocked corr=%s [key=pending-reply-%s]: unrelated note\n' "$CORR" "$CORR" \
377
+ > "$state/task-takeover.status"
378
+ printf 'blocked corr=%s [key=pending-reply-%s]: pending-reply-missed: task=t pending-reply-id=%s\n' \
379
+ "$CORR" "$CORR" "$CORR" > "$state/task-owner.status"
380
+ view=$(drain_open "$state" "$out")
381
+ case "$view" in
382
+ *'task-takeover'*) fail "a correlated line took over a reserved key: $view" ;;
383
+ esac
384
+ case "$view" in
385
+ *"task-owner [key=pending-reply-$CORR]"*) : ;;
386
+ *) fail "the reserved namespace owner could not open through a token: $view" ;;
387
+ esac
388
+
389
+ # ...and the owner closes it through a token just as completely.
390
+ printf 'resolved corr=%s [key=pending-reply-%s]: pending-reply-missed: answered\n' \
391
+ "$CORR" "$CORR" >> "$state/task-owner.status"
392
+ view=$(drain_open "$state" "$out")
393
+ case "$view" in
394
+ *'task-owner'*) fail "the reserved namespace owner could not close through a token: $view" ;;
395
+ esac
396
+
397
+ pass "reading through the token does not weaken the reserved-key namespace rule"
398
+ }
399
+
400
+ # --- the two folds must agree ------------------------------------------------
401
+
402
+ test_incremental_and_whole_file_folds_agree_over_correlated_lines() {
403
+ local dir state status whole inc round
404
+ dir=$(make_case fold-agreement)
405
+ state="$dir/state"
406
+ status="$state/task-agree.status"
407
+
408
+ # Grow the log the way a real one grows - correlated opens, unrelated routine
409
+ # traffic, correlated closes - and after EVERY append assert that the bounded
410
+ # cursor-backed fold and the whole-file fold report the identical open set.
411
+ : > "$status"
412
+ round=0
413
+ while [ "$round" -lt 6 ]; do
414
+ printf 'needs-decision corr=%s [key=k%s]: decision %s\n' "$CORR" "$round" "$round" >> "$status"
415
+ printf 'working corr=%s: routine progress %s\n' "$CORR2" "$round" >> "$status"
416
+ whole=$(FM_STATE_OVERRIDE="$state" bash -c '. "$1"; status_open_decisions "$2"' _ \
417
+ "$ROOT/bin/fm-classify-lib.sh" "$status")
418
+ inc=$(FM_STATE_OVERRIDE="$state" bash -c '. "$1"; status_open_decisions_incremental "$2"' _ \
419
+ "$ROOT/bin/fm-classify-lib.sh" "$status")
420
+ [ "$whole" = "$inc" ] \
421
+ || fail "folds disagreed after opening k$round: whole=[$whole] incremental=[$inc]"
422
+ # Agreement alone would be satisfied by both folds being blind in the same
423
+ # way, so pin the answer itself: every key opened so far, and only those.
424
+ [ "$(printf '%s' "$whole" | grep -c .)" -eq "$((round + 1))" ] \
425
+ || fail "after opening k$round the folds agreed on the wrong set: [$whole]"
426
+ case "$whole" in
427
+ *"k$round"*) : ;;
428
+ *) fail "the folds agreed but never saw the correlated opener k$round: [$whole]" ;;
429
+ esac
430
+ round=$((round + 1))
431
+ done
432
+
433
+ round=0
434
+ while [ "$round" -lt 6 ]; do
435
+ printf 'resolved corr=%s [key=k%s]: answered %s\n' "$CORR" "$round" "$round" >> "$status"
436
+ whole=$(FM_STATE_OVERRIDE="$state" bash -c '. "$1"; status_open_decisions "$2"' _ \
437
+ "$ROOT/bin/fm-classify-lib.sh" "$status")
438
+ inc=$(FM_STATE_OVERRIDE="$state" bash -c '. "$1"; status_open_decisions_incremental "$2"' _ \
439
+ "$ROOT/bin/fm-classify-lib.sh" "$status")
440
+ [ "$whole" = "$inc" ] \
441
+ || fail "folds disagreed after closing k$round: whole=[$whole] incremental=[$inc]"
442
+ [ "$(printf '%s' "$whole" | grep -c .)" -eq "$((5 - round))" ] \
443
+ || fail "after closing k$round the folds agreed on the wrong set: [$whole]"
444
+ case "$whole" in
445
+ *"k$round"*) fail "the correlated closer for k$round left it open in both folds: [$whole]" ;;
446
+ esac
447
+ round=$((round + 1))
448
+ done
449
+
450
+ [ -z "$whole" ] || fail "correlated closers left decisions open in both folds: $whole"
451
+
452
+ pass "the cursor-backed fold and the whole-file fold agree on every correlated transition"
453
+ }
454
+
455
+ test_a_cursor_written_before_this_change_is_rebuilt() {
456
+ # The persisted cursor carries a folded open set, so every one written under
457
+ # the previous reading holds decisions computed while correlated lines were
458
+ # invisible. Without a fold-version bump those homes would keep serving the old
459
+ # answer forever - the live openers would stay missing after the fix landed.
460
+ local dir state status cursor out view
461
+ dir=$(make_case stale-cursor)
462
+ state="$dir/state"
463
+ status="$state/task-stale.status"
464
+
465
+ printf 'needs-decision corr=%s [key=owed]: a decision the captain is owed\n' "$CORR" > "$status"
466
+ # A cursor claiming the whole file is already folded, with an empty open set -
467
+ # byte for byte what the previous reading would have persisted here.
468
+ cursor="$state/.task-stale.open-decisions-cursor"
469
+ {
470
+ printf 'version=4\n'
471
+ printf 'offset=%s\n' "$(LC_ALL=C wc -c < "$status" | tr -d '[:space:]')"
472
+ printf 'ident=%s\n' "$(bash -c '. "$1"; _fm_open_decisions_file_ident "$2"' _ \
473
+ "$ROOT/bin/fm-classify-lib.sh" "$status")"
474
+ } > "$cursor"
475
+
476
+ out="$dir/drain.out"
477
+ view=$(drain_open "$state" "$out")
478
+ case "$view" in
479
+ *'task-stale'*'[key=owed]'*) : ;;
480
+ *) fail "a cursor from the previous reading hid the decision instead of being rebuilt: $view" ;;
481
+ esac
482
+
483
+ pass "a cursor persisted under the previous reading is discarded and refolded"
484
+ }
485
+
486
+ # --- the grammar pin ---------------------------------------------------------
487
+
488
+ test_the_real_writers_produce_tokens_this_library_reads() {
489
+ # This library states the token SHAPE a second time because the library that
490
+ # OWNS the grammar sources this one and cannot be sourced back. That second
491
+ # statement is only safe while it is pinned to the real writers, so this drives
492
+ # both of them for real and asserts the classifier reads their output.
493
+ local dir state token line verb helper_line
494
+ dir=$(make_case writer-pin)
495
+ state="$dir/state"
496
+
497
+ # Writer 1: the correlation library's own token builder, over ids it generates.
498
+ local i=0 corr
499
+ while [ "$i" -lt 5 ]; do
500
+ corr=$(bash -c '. "$1"; fm_pending_reply_new_id' _ "$ROOT/bin/fm-pending-reply-lib.sh")
501
+ [ -n "$corr" ] || fail "the correlation library produced an empty id"
502
+ token=$(bash -c '. "$1"; fm_pending_reply_corr_token "$2"' _ \
503
+ "$ROOT/bin/fm-pending-reply-lib.sh" "$corr")
504
+ line="needs-decision $token [key=pinned]: a decision"
505
+ verb=$(status_line_verb "$line")
506
+ [ "$verb" = needs-decision ] \
507
+ || fail "the classifier did not read through a real correlation token '$token' (verb=[$verb])"
508
+ i=$((i + 1))
509
+ done
510
+
511
+ # Writer 2: the optional secondmate report helper, whose bracketed shape must
512
+ # be read through just as completely. Drive the real script.
513
+ "$REPORT" "$state/pinned.status" "done" "$corr" "audit clean" \
514
+ || fail "$REPORT failed writing a correlated report"
515
+ helper_line=$(tail -1 "$state/pinned.status")
516
+ verb=$(status_line_verb "$helper_line")
517
+ [ "$verb" = "done" ] \
518
+ || fail "the classifier did not read through the helper's own line '$helper_line' (verb=[$verb])"
519
+ status_is_terminal_verb "$helper_line" \
520
+ || fail "the helper's own line is not seen as a terminal captain verb"
521
+
522
+ "$REPORT" --doc "$state/pinned.status" needs-decision "$corr" data/x/report.md "see the report" \
523
+ || fail "$REPORT failed writing a correlated doc-pointer report"
524
+ helper_line=$(tail -1 "$state/pinned.status")
525
+ verb=$(status_line_verb "$helper_line")
526
+ [ "$verb" = needs-decision ] \
527
+ || fail "the classifier did not read through the helper's doc line '$helper_line' (verb=[$verb])"
528
+
529
+ pass "both real correlation-token writers produce lines this classifier reads through"
530
+ }
531
+
532
+ test_tokened_opener_opens_and_tokened_closer_closes
533
+ test_token_is_read_through_in_every_position_it_is_written_in
534
+ test_untokened_pair_is_unchanged
535
+ test_prose_and_malformed_tokens_never_become_transitions
536
+ test_token_first_word_never_impersonates_a_transition
537
+ test_captain_relevance_and_pause_are_unchanged_without_a_token
538
+ test_consumer_verdicts_read_through_the_token
539
+ test_daemon_and_crew_state_case_arms_read_through_the_token
540
+ test_pending_reply_escalation_matching_is_unaffected
541
+ test_incremental_and_whole_file_folds_agree_over_correlated_lines
542
+ test_a_cursor_written_before_this_change_is_rebuilt
543
+ test_the_real_writers_produce_tokens_this_library_reads