aether-colony 3.1.17 → 5.1.0

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 (378) hide show
  1. package/.aether/aether-utils.sh +5354 -0
  2. package/.aether/agents-claude/aether-ambassador.md +265 -0
  3. package/.aether/agents-claude/aether-archaeologist.md +327 -0
  4. package/.aether/agents-claude/aether-architect.md +236 -0
  5. package/.aether/agents-claude/aether-auditor.md +271 -0
  6. package/.aether/agents-claude/aether-builder.md +224 -0
  7. package/.aether/agents-claude/aether-chaos.md +269 -0
  8. package/.aether/agents-claude/aether-chronicler.md +305 -0
  9. package/.aether/agents-claude/aether-gatekeeper.md +330 -0
  10. package/.aether/agents-claude/aether-includer.md +374 -0
  11. package/.aether/agents-claude/aether-keeper.md +272 -0
  12. package/.aether/agents-claude/aether-measurer.md +322 -0
  13. package/.aether/agents-claude/aether-oracle.md +237 -0
  14. package/.aether/agents-claude/aether-probe.md +211 -0
  15. package/.aether/agents-claude/aether-queen.md +330 -0
  16. package/.aether/agents-claude/aether-route-setter.md +178 -0
  17. package/.aether/agents-claude/aether-sage.md +418 -0
  18. package/.aether/agents-claude/aether-scout.md +179 -0
  19. package/.aether/agents-claude/aether-surveyor-disciplines.md +417 -0
  20. package/.aether/agents-claude/aether-surveyor-nest.md +355 -0
  21. package/.aether/agents-claude/aether-surveyor-pathogens.md +289 -0
  22. package/.aether/agents-claude/aether-surveyor-provisions.md +360 -0
  23. package/.aether/agents-claude/aether-tracker.md +270 -0
  24. package/.aether/agents-claude/aether-watcher.md +280 -0
  25. package/.aether/agents-claude/aether-weaver.md +248 -0
  26. package/.aether/commands/archaeology.yaml +653 -0
  27. package/.aether/commands/build.yaml +1221 -0
  28. package/.aether/commands/chaos.yaml +653 -0
  29. package/.aether/commands/colonize.yaml +438 -0
  30. package/.aether/commands/continue.yaml +1484 -0
  31. package/.aether/commands/council.yaml +304 -0
  32. package/.aether/commands/data-clean.yaml +80 -0
  33. package/.aether/commands/dream.yaml +275 -0
  34. package/.aether/commands/entomb.yaml +863 -0
  35. package/.aether/commands/export-signals.yaml +64 -0
  36. package/.aether/commands/feedback.yaml +158 -0
  37. package/.aether/commands/flag.yaml +160 -0
  38. package/.aether/commands/flags.yaml +177 -0
  39. package/.aether/commands/focus.yaml +112 -0
  40. package/.aether/commands/help.yaml +167 -0
  41. package/.aether/commands/history.yaml +137 -0
  42. package/.aether/commands/import-signals.yaml +79 -0
  43. package/.aether/commands/init.yaml +469 -0
  44. package/.aether/commands/insert-phase.yaml +98 -0
  45. package/.aether/commands/interpret.yaml +285 -0
  46. package/.aether/commands/lay-eggs.yaml +224 -0
  47. package/.aether/commands/maturity.yaml +122 -0
  48. package/.aether/commands/memory-details.yaml +74 -0
  49. package/.aether/commands/migrate-state.yaml +174 -0
  50. package/.aether/commands/oracle.yaml +1224 -0
  51. package/.aether/commands/organize.yaml +446 -0
  52. package/.aether/commands/patrol.yaml +621 -0
  53. package/.aether/commands/pause-colony.yaml +424 -0
  54. package/.aether/commands/phase.yaml +124 -0
  55. package/.aether/commands/pheromones.yaml +153 -0
  56. package/.aether/commands/plan.yaml +1313 -0
  57. package/.aether/commands/preferences.yaml +63 -0
  58. package/.aether/commands/redirect.yaml +123 -0
  59. package/.aether/commands/resume-colony.yaml +373 -0
  60. package/.aether/commands/resume.yaml +398 -0
  61. package/.aether/commands/run.yaml +193 -0
  62. package/.aether/commands/seal.yaml +1205 -0
  63. package/.aether/commands/skill-create.yaml +337 -0
  64. package/.aether/commands/status.yaml +364 -0
  65. package/.aether/commands/swarm.yaml +352 -0
  66. package/.aether/commands/tunnels.yaml +814 -0
  67. package/.aether/commands/update.yaml +131 -0
  68. package/.aether/commands/verify-castes.yaml +159 -0
  69. package/.aether/commands/watch.yaml +454 -0
  70. package/.aether/docs/INCIDENT_TEMPLATE.md +32 -0
  71. package/.aether/docs/QUEEN-SYSTEM.md +211 -0
  72. package/.aether/docs/README.md +98 -0
  73. package/.aether/docs/caste-system.md +48 -0
  74. package/.aether/docs/command-playbooks/README.md +23 -0
  75. package/.aether/docs/command-playbooks/build-complete.md +349 -0
  76. package/.aether/docs/command-playbooks/build-context.md +282 -0
  77. package/.aether/docs/command-playbooks/build-full.md +1682 -0
  78. package/.aether/docs/command-playbooks/build-prep.md +283 -0
  79. package/.aether/docs/command-playbooks/build-verify.md +405 -0
  80. package/.aether/docs/command-playbooks/build-wave.md +749 -0
  81. package/.aether/docs/command-playbooks/continue-advance.md +524 -0
  82. package/.aether/docs/command-playbooks/continue-finalize.md +447 -0
  83. package/.aether/docs/command-playbooks/continue-full.md +1724 -0
  84. package/.aether/docs/command-playbooks/continue-gates.md +686 -0
  85. package/.aether/docs/command-playbooks/continue-verify.md +406 -0
  86. package/.aether/docs/context-continuity.md +84 -0
  87. package/{runtime → .aether/docs/disciplines}/DISCIPLINES.md +13 -11
  88. package/.aether/docs/error-codes.md +268 -0
  89. package/.aether/docs/known-issues.md +94 -0
  90. package/{runtime → .aether}/docs/pheromones.md +86 -6
  91. package/.aether/docs/plans/pheromone-display-plan.md +257 -0
  92. package/.aether/docs/queen-commands.md +98 -0
  93. package/.aether/docs/source-of-truth-map.md +132 -0
  94. package/.aether/docs/xml-utilities.md +47 -0
  95. package/{runtime → .aether}/exchange/pheromone-xml.sh +2 -1
  96. package/{runtime → .aether}/exchange/registry-xml.sh +7 -3
  97. package/{runtime → .aether}/exchange/wisdom-xml.sh +11 -4
  98. package/.aether/rules/aether-colony.md +144 -0
  99. package/.aether/schemas/example-prompt-builder.xml +234 -0
  100. package/.aether/scripts/incident-test-add.sh +47 -0
  101. package/.aether/scripts/weekly-audit.sh +79 -0
  102. package/.aether/skills/.index.json +649 -0
  103. package/.aether/skills/colony/.manifest.json +16 -0
  104. package/.aether/skills/colony/build-discipline/SKILL.md +78 -0
  105. package/.aether/skills/colony/colony-interaction/SKILL.md +56 -0
  106. package/.aether/skills/colony/colony-lifecycle/SKILL.md +77 -0
  107. package/.aether/skills/colony/colony-visuals/SKILL.md +112 -0
  108. package/.aether/skills/colony/context-management/SKILL.md +80 -0
  109. package/.aether/skills/colony/error-presentation/SKILL.md +99 -0
  110. package/.aether/skills/colony/pheromone-protocol/SKILL.md +79 -0
  111. package/.aether/skills/colony/pheromone-visibility/SKILL.md +81 -0
  112. package/.aether/skills/colony/state-safety/SKILL.md +84 -0
  113. package/.aether/skills/colony/worker-priming/SKILL.md +82 -0
  114. package/.aether/skills/domain/.manifest.json +24 -0
  115. package/.aether/skills/domain/README.md +33 -0
  116. package/.aether/skills/domain/django/SKILL.md +49 -0
  117. package/.aether/skills/domain/docker/SKILL.md +52 -0
  118. package/.aether/skills/domain/golang/SKILL.md +52 -0
  119. package/.aether/skills/domain/graphql/SKILL.md +51 -0
  120. package/.aether/skills/domain/html-css/SKILL.md +48 -0
  121. package/.aether/skills/domain/nextjs/SKILL.md +45 -0
  122. package/.aether/skills/domain/nodejs/SKILL.md +53 -0
  123. package/.aether/skills/domain/postgresql/SKILL.md +53 -0
  124. package/.aether/skills/domain/prisma/SKILL.md +59 -0
  125. package/.aether/skills/domain/python/SKILL.md +50 -0
  126. package/.aether/skills/domain/rails/SKILL.md +52 -0
  127. package/.aether/skills/domain/react/SKILL.md +45 -0
  128. package/.aether/skills/domain/rest-api/SKILL.md +58 -0
  129. package/.aether/skills/domain/svelte/SKILL.md +47 -0
  130. package/.aether/skills/domain/tailwind/SKILL.md +45 -0
  131. package/.aether/skills/domain/testing/SKILL.md +53 -0
  132. package/.aether/skills/domain/typescript/SKILL.md +58 -0
  133. package/.aether/skills/domain/vue/SKILL.md +49 -0
  134. package/.aether/templates/QUEEN.md.template +61 -0
  135. package/.aether/templates/colony-state-reset.jq.template +23 -0
  136. package/.aether/templates/colony-state.template.json +39 -0
  137. package/.aether/templates/constraints.template.json +9 -0
  138. package/.aether/templates/crowned-anthill.template.md +36 -0
  139. package/.aether/templates/handoff-build-error.template.md +30 -0
  140. package/.aether/templates/handoff-build-success.template.md +39 -0
  141. package/.aether/templates/handoff.template.md +40 -0
  142. package/.aether/templates/learning-observations.template.json +6 -0
  143. package/.aether/templates/midden.template.json +13 -0
  144. package/.aether/templates/pheromones.template.json +6 -0
  145. package/.aether/templates/session.template.json +9 -0
  146. package/{runtime → .aether}/utils/atomic-write.sh +68 -22
  147. package/{runtime → .aether}/utils/chamber-compare.sh +23 -10
  148. package/.aether/utils/chamber-utils.sh +440 -0
  149. package/.aether/utils/emoji-audit.sh +166 -0
  150. package/{runtime → .aether}/utils/error-handler.sh +34 -8
  151. package/.aether/utils/file-lock.sh +313 -0
  152. package/.aether/utils/flag.sh +267 -0
  153. package/.aether/utils/hive.sh +572 -0
  154. package/.aether/utils/learning.sh +1928 -0
  155. package/.aether/utils/midden.sh +342 -0
  156. package/.aether/utils/oracle/oracle.md +168 -0
  157. package/.aether/utils/oracle/oracle.sh +1023 -0
  158. package/.aether/utils/pheromone.sh +2029 -0
  159. package/.aether/utils/queen.sh +1698 -0
  160. package/.aether/utils/scan.sh +860 -0
  161. package/.aether/utils/semantic-cli.sh +415 -0
  162. package/.aether/utils/session.sh +552 -0
  163. package/.aether/utils/skills.sh +509 -0
  164. package/.aether/utils/spawn-tree.sh +260 -0
  165. package/.aether/utils/spawn.sh +260 -0
  166. package/.aether/utils/state-api.sh +199 -0
  167. package/{runtime → .aether}/utils/state-loader.sh +8 -6
  168. package/.aether/utils/suggest.sh +611 -0
  169. package/{runtime → .aether}/utils/swarm-display.sh +10 -1
  170. package/.aether/utils/swarm.sh +1004 -0
  171. package/{runtime → .aether}/utils/watch-spawn-tree.sh +11 -2
  172. package/{runtime → .aether}/utils/xml-compose.sh +9 -3
  173. package/.aether/utils/xml-convert.sh +277 -0
  174. package/{runtime → .aether}/utils/xml-core.sh +5 -9
  175. package/.aether/utils/xml-query.sh +201 -0
  176. package/.aether/utils/xml-utils.sh +110 -0
  177. package/{runtime → .aether}/workers.md +97 -81
  178. package/.claude/agents/ant/aether-ambassador.md +265 -0
  179. package/.claude/agents/ant/aether-archaeologist.md +327 -0
  180. package/.claude/agents/ant/aether-architect.md +236 -0
  181. package/.claude/agents/ant/aether-auditor.md +271 -0
  182. package/.claude/agents/ant/aether-builder.md +224 -0
  183. package/.claude/agents/ant/aether-chaos.md +269 -0
  184. package/.claude/agents/ant/aether-chronicler.md +305 -0
  185. package/.claude/agents/ant/aether-gatekeeper.md +330 -0
  186. package/.claude/agents/ant/aether-includer.md +374 -0
  187. package/.claude/agents/ant/aether-keeper.md +272 -0
  188. package/.claude/agents/ant/aether-measurer.md +322 -0
  189. package/.claude/agents/ant/aether-oracle.md +237 -0
  190. package/.claude/agents/ant/aether-probe.md +211 -0
  191. package/.claude/agents/ant/aether-queen.md +330 -0
  192. package/.claude/agents/ant/aether-route-setter.md +178 -0
  193. package/.claude/agents/ant/aether-sage.md +418 -0
  194. package/.claude/agents/ant/aether-scout.md +179 -0
  195. package/.claude/agents/ant/aether-surveyor-disciplines.md +417 -0
  196. package/.claude/agents/ant/aether-surveyor-nest.md +355 -0
  197. package/.claude/agents/ant/aether-surveyor-pathogens.md +289 -0
  198. package/.claude/agents/ant/aether-surveyor-provisions.md +360 -0
  199. package/.claude/agents/ant/aether-tracker.md +270 -0
  200. package/.claude/agents/ant/aether-watcher.md +280 -0
  201. package/.claude/agents/ant/aether-weaver.md +248 -0
  202. package/.claude/commands/ant/archaeology.md +16 -14
  203. package/.claude/commands/ant/build.md +43 -1028
  204. package/.claude/commands/ant/chaos.md +19 -23
  205. package/.claude/commands/ant/colonize.md +52 -31
  206. package/.claude/commands/ant/continue.md +40 -1016
  207. package/.claude/commands/ant/council.md +21 -18
  208. package/.claude/commands/ant/data-clean.md +81 -0
  209. package/.claude/commands/ant/dream.md +27 -15
  210. package/.claude/commands/ant/entomb.md +317 -225
  211. package/.claude/commands/ant/export-signals.md +57 -0
  212. package/.claude/commands/ant/feedback.md +48 -26
  213. package/.claude/commands/ant/flag.md +30 -10
  214. package/.claude/commands/ant/flags.md +34 -12
  215. package/.claude/commands/ant/focus.md +45 -19
  216. package/.claude/commands/ant/help.md +50 -8
  217. package/.claude/commands/ant/history.md +13 -0
  218. package/.claude/commands/ant/import-signals.md +71 -0
  219. package/.claude/commands/ant/init.md +345 -194
  220. package/.claude/commands/ant/insert-phase.md +101 -0
  221. package/.claude/commands/ant/interpret.md +26 -4
  222. package/.claude/commands/ant/lay-eggs.md +184 -127
  223. package/.claude/commands/ant/maturity.md +32 -11
  224. package/.claude/commands/ant/memory-details.md +77 -0
  225. package/.claude/commands/ant/migrate-state.md +20 -2
  226. package/.claude/commands/ant/oracle.md +337 -74
  227. package/.claude/commands/ant/organize.md +39 -25
  228. package/.claude/commands/ant/patrol.md +620 -0
  229. package/.claude/commands/ant/pause-colony.md +23 -27
  230. package/.claude/commands/ant/phase.md +40 -42
  231. package/.claude/commands/ant/pheromones.md +156 -0
  232. package/.claude/commands/ant/plan.md +185 -51
  233. package/.claude/commands/ant/preferences.md +65 -0
  234. package/.claude/commands/ant/redirect.md +45 -30
  235. package/.claude/commands/ant/resume-colony.md +51 -27
  236. package/.claude/commands/ant/resume.md +314 -94
  237. package/.claude/commands/ant/run.md +195 -0
  238. package/.claude/commands/ant/seal.md +650 -221
  239. package/.claude/commands/ant/skill-create.md +286 -0
  240. package/.claude/commands/ant/status.md +196 -31
  241. package/.claude/commands/ant/swarm.md +16 -46
  242. package/.claude/commands/ant/tunnels.md +280 -105
  243. package/.claude/commands/ant/update.md +73 -89
  244. package/.claude/commands/ant/verify-castes.md +100 -42
  245. package/.claude/commands/ant/watch.md +14 -12
  246. package/.opencode/agents/aether-ambassador.md +63 -20
  247. package/.opencode/agents/aether-archaeologist.md +29 -12
  248. package/.opencode/agents/aether-architect.md +103 -36
  249. package/.opencode/agents/aether-auditor.md +51 -18
  250. package/.opencode/agents/aether-builder.md +70 -20
  251. package/.opencode/agents/aether-chaos.md +29 -12
  252. package/.opencode/agents/aether-chronicler.md +60 -18
  253. package/.opencode/agents/aether-gatekeeper.md +27 -18
  254. package/.opencode/agents/aether-includer.md +27 -18
  255. package/.opencode/agents/aether-keeper.md +89 -18
  256. package/.opencode/agents/aether-measurer.md +27 -18
  257. package/.opencode/agents/aether-oracle.md +137 -0
  258. package/.opencode/agents/aether-probe.md +60 -18
  259. package/.opencode/agents/aether-queen.md +172 -24
  260. package/.opencode/agents/aether-route-setter.md +57 -12
  261. package/.opencode/agents/aether-sage.md +26 -18
  262. package/.opencode/agents/aether-scout.md +28 -20
  263. package/.opencode/agents/aether-surveyor-disciplines.md +59 -2
  264. package/.opencode/agents/aether-surveyor-nest.md +59 -2
  265. package/.opencode/agents/aether-surveyor-pathogens.md +57 -2
  266. package/.opencode/agents/aether-surveyor-provisions.md +59 -2
  267. package/.opencode/agents/aether-tracker.md +64 -18
  268. package/.opencode/agents/aether-watcher.md +66 -19
  269. package/.opencode/agents/aether-weaver.md +61 -18
  270. package/.opencode/commands/ant/archaeology.md +7 -14
  271. package/.opencode/commands/ant/build.md +437 -257
  272. package/.opencode/commands/ant/chaos.md +7 -24
  273. package/.opencode/commands/ant/colonize.md +8 -17
  274. package/.opencode/commands/ant/continue.md +661 -142
  275. package/.opencode/commands/ant/council.md +11 -22
  276. package/.opencode/commands/ant/data-clean.md +77 -0
  277. package/.opencode/commands/ant/dream.md +15 -17
  278. package/.opencode/commands/ant/entomb.md +133 -62
  279. package/.opencode/commands/ant/export-signals.md +54 -0
  280. package/.opencode/commands/ant/feedback.md +24 -5
  281. package/.opencode/commands/ant/flag.md +16 -4
  282. package/.opencode/commands/ant/flags.md +24 -10
  283. package/.opencode/commands/ant/focus.md +22 -5
  284. package/.opencode/commands/ant/help.md +41 -8
  285. package/.opencode/commands/ant/history.md +9 -0
  286. package/.opencode/commands/ant/import-signals.md +68 -0
  287. package/.opencode/commands/ant/init.md +374 -167
  288. package/.opencode/commands/ant/insert-phase.md +107 -0
  289. package/.opencode/commands/ant/interpret.md +16 -0
  290. package/.opencode/commands/ant/lay-eggs.md +184 -112
  291. package/.opencode/commands/ant/maturity.md +18 -2
  292. package/.opencode/commands/ant/memory-details.md +83 -0
  293. package/.opencode/commands/ant/migrate-state.md +12 -0
  294. package/.opencode/commands/ant/oracle.md +322 -67
  295. package/.opencode/commands/ant/organize.md +18 -16
  296. package/.opencode/commands/ant/patrol.md +626 -0
  297. package/.opencode/commands/ant/pause-colony.md +12 -29
  298. package/.opencode/commands/ant/phase.md +30 -40
  299. package/.opencode/commands/ant/pheromones.md +162 -0
  300. package/.opencode/commands/ant/plan.md +184 -56
  301. package/.opencode/commands/ant/preferences.md +71 -0
  302. package/.opencode/commands/ant/redirect.md +22 -5
  303. package/.opencode/commands/ant/resume-colony.md +38 -27
  304. package/.opencode/commands/ant/resume.md +385 -0
  305. package/.opencode/commands/ant/run.md +201 -0
  306. package/.opencode/commands/ant/seal.md +259 -45
  307. package/.opencode/commands/ant/skill-create.md +63 -0
  308. package/.opencode/commands/ant/status.md +135 -31
  309. package/.opencode/commands/ant/swarm.md +3 -345
  310. package/.opencode/commands/ant/tunnels.md +152 -9
  311. package/.opencode/commands/ant/update.md +70 -91
  312. package/.opencode/commands/ant/verify-castes.md +96 -42
  313. package/.opencode/commands/ant/watch.md +7 -0
  314. package/CHANGELOG.md +356 -0
  315. package/README.md +203 -573
  316. package/bin/cli.js +455 -527
  317. package/bin/generate-commands.js +186 -0
  318. package/bin/generate-commands.sh +127 -88
  319. package/bin/lib/init.js +13 -3
  320. package/bin/lib/spawn-logger.js +0 -15
  321. package/bin/lib/update-transaction.js +392 -140
  322. package/bin/npx-install.js +178 -0
  323. package/bin/sync-to-runtime.sh +5 -137
  324. package/bin/validate-package.sh +166 -0
  325. package/package.json +14 -7
  326. package/.opencode/agents/aether-guardian.md +0 -107
  327. package/.opencode/agents/workers.md +0 -1034
  328. package/bin/lib/model-profiles.js +0 -445
  329. package/bin/lib/model-verify.js +0 -288
  330. package/bin/lib/proxy-health.js +0 -253
  331. package/bin/lib/telemetry.js +0 -441
  332. package/runtime/CONTEXT.md +0 -160
  333. package/runtime/QUEEN_ANT_ARCHITECTURE.md +0 -402
  334. package/runtime/aether-utils.sh +0 -3879
  335. package/runtime/data/signatures.json +0 -41
  336. package/runtime/docs/AETHER-2.0-IMPLEMENTATION-PLAN.md +0 -1343
  337. package/runtime/docs/AETHER-PHEROMONE-SYSTEM-MASTER-SPEC.md +0 -2642
  338. package/runtime/docs/PHEROMONE-INJECTION.md +0 -240
  339. package/runtime/docs/PHEROMONE-INTEGRATION.md +0 -192
  340. package/runtime/docs/PHEROMONE-SYSTEM-DESIGN.md +0 -426
  341. package/runtime/docs/README.md +0 -94
  342. package/runtime/docs/VISUAL-OUTPUT-SPEC.md +0 -219
  343. package/runtime/docs/biological-reference.md +0 -272
  344. package/runtime/docs/codebase-review.md +0 -399
  345. package/runtime/docs/command-sync.md +0 -164
  346. package/runtime/docs/constraints.md +0 -116
  347. package/runtime/docs/implementation-learnings.md +0 -89
  348. package/runtime/docs/known-issues.md +0 -217
  349. package/runtime/docs/namespace.md +0 -148
  350. package/runtime/docs/pathogen-schema-example.json +0 -36
  351. package/runtime/docs/pathogen-schema.md +0 -111
  352. package/runtime/docs/planning-discipline.md +0 -159
  353. package/runtime/docs/progressive-disclosure.md +0 -184
  354. package/runtime/lib/queen-utils.sh +0 -729
  355. package/runtime/model-profiles.yaml +0 -100
  356. package/runtime/planning.md +0 -159
  357. package/runtime/recover.sh +0 -136
  358. package/runtime/templates/QUEEN.md.template +0 -79
  359. package/runtime/utils/chamber-utils.sh +0 -285
  360. package/runtime/utils/file-lock.sh +0 -122
  361. package/runtime/utils/spawn-tree.sh +0 -428
  362. package/runtime/utils/spawn-with-model.sh +0 -56
  363. package/runtime/utils/xml-utils.sh +0 -2196
  364. package/runtime/workers-new-castes.md +0 -516
  365. /package/{runtime → .aether/docs/disciplines}/coding-standards.md +0 -0
  366. /package/{runtime → .aether/docs/disciplines}/debugging.md +0 -0
  367. /package/{runtime → .aether/docs/disciplines}/learning.md +0 -0
  368. /package/{runtime → .aether/docs/disciplines}/tdd.md +0 -0
  369. /package/{runtime → .aether/docs/disciplines}/verification-loop.md +0 -0
  370. /package/{runtime → .aether/docs/disciplines}/verification.md +0 -0
  371. /package/{runtime → .aether}/schemas/aether-types.xsd +0 -0
  372. /package/{runtime → .aether}/schemas/colony-registry.xsd +0 -0
  373. /package/{runtime → .aether}/schemas/pheromone.xsd +0 -0
  374. /package/{runtime → .aether}/schemas/prompt.xsd +0 -0
  375. /package/{runtime → .aether}/schemas/queen-wisdom.xsd +0 -0
  376. /package/{runtime → .aether}/schemas/worker-priming.xsd +0 -0
  377. /package/{runtime → .aether}/utils/colorize-log.sh +0 -0
  378. /package/{runtime → .aether}/utils/queen-to-md.xsl +0 -0
@@ -0,0 +1,260 @@
1
+ #!/bin/bash
2
+ # Spawn Tree Reconstruction Module
3
+ # Parses spawn-tree.txt and provides tree traversal functions
4
+ #
5
+ # Usage: source .aether/utils/spawn-tree.sh
6
+ # All functions output JSON to stdout
7
+
8
+ # Data directory - can be overridden
9
+ SPAWN_TREE_DATA_DIR="${SPAWN_TREE_DATA_DIR:-.aether/data}"
10
+ SPAWN_TREE_FILE="${SPAWN_TREE_FILE:-$SPAWN_TREE_DATA_DIR/spawn-tree.txt}"
11
+
12
+ # Parse spawn-tree.txt into structured data
13
+ # Usage: parse_spawn_tree [file_path]
14
+ # Outputs: JSON representation of all spawns
15
+ parse_spawn_tree() {
16
+ local file_path="${1:-$SPAWN_TREE_FILE}"
17
+
18
+ if [[ ! -f "$file_path" ]] || [[ ! -s "$file_path" ]]; then
19
+ echo '{"spawns":[],"metadata":{"total_count":0,"active_count":0,"completed_count":0,"file_exists":false}}'
20
+ return 0
21
+ fi
22
+
23
+ awk -F'|' '
24
+ BEGIN { n=0; active=0; completed_n=0 }
25
+ NF == 7 && $7 == "spawned" {
26
+ names[n] = $4; parents[n] = $2; castes[n] = $3
27
+ tasks[n] = $5; statuses[n] = "spawned"; timestamps[n] = $1
28
+ completed_at[n] = ""; children_str[n] = ""
29
+ name_to_idx[$4] = n; n++
30
+ }
31
+ $3 ~ /^(completed|failed|blocked)$/ && NF >= 4 {
32
+ ant = $2
33
+ if (ant in name_to_idx) {
34
+ idx = name_to_idx[ant]; statuses[idx] = $3; completed_at[idx] = $1
35
+ }
36
+ }
37
+ END {
38
+ for (i = 0; i < n; i++) {
39
+ p = parents[i]
40
+ if (p in name_to_idx) {
41
+ pidx = name_to_idx[p]
42
+ if (children_str[pidx] == "") children_str[pidx] = i
43
+ else children_str[pidx] = children_str[pidx] " " i
44
+ }
45
+ }
46
+ for (i = 0; i < n; i++) {
47
+ if (statuses[i] == "spawned" || statuses[i] == "active") active++
48
+ else if (statuses[i] ~ /^(completed|failed|blocked)$/) completed_n++
49
+ }
50
+ printf "{"
51
+ printf "\"spawns\":["
52
+ for (i = 0; i < n; i++) {
53
+ if (i > 0) printf ","
54
+ nm = names[i]; gsub(/\\/, "\\\\", nm); gsub(/"/, "\\\"", nm); gsub(/\t/, "\\t", nm)
55
+ pr = parents[i]; gsub(/\\/, "\\\\", pr); gsub(/"/, "\\\"", pr); gsub(/\t/, "\\t", pr)
56
+ tk = tasks[i]; gsub(/\\/, "\\\\", tk); gsub(/"/, "\\\"", tk); gsub(/\t/, "\\t", tk)
57
+ printf "{\"name\":\"%s\",\"parent\":\"%s\",\"caste\":\"%s\",", nm, pr, castes[i]
58
+ printf "\"task\":\"%s\",\"status\":\"%s\",", tk, statuses[i]
59
+ printf "\"spawned_at\":\"%s\",\"completed_at\":\"%s\",", timestamps[i], completed_at[i]
60
+ printf "\"children\":["
61
+ if (children_str[i] != "") {
62
+ split(children_str[i], cidxs, " ")
63
+ for (j = 1; j <= length(cidxs); j++) {
64
+ if (j > 1) printf ","
65
+ cn = names[cidxs[j]+0]
66
+ gsub(/\\/, "\\\\", cn); gsub(/"/, "\\\"", cn); gsub(/\t/, "\\t", cn)
67
+ printf "\"%s\"", cn
68
+ }
69
+ }
70
+ printf "]}"
71
+ }
72
+ printf "],"
73
+ printf "\"metadata\":{\"total_count\":%d,\"active_count\":%d,\"completed_count\":%d,\"file_exists\":true}", n, active, completed_n
74
+ printf "}"
75
+ }
76
+ ' "$file_path"
77
+ }
78
+
79
+ # Get spawn depth for a given ant name
80
+ # Usage: get_spawn_depth <ant_name>
81
+ # Returns: JSON with ant name and depth
82
+ get_spawn_depth() {
83
+ local ant_name="${1:-}"
84
+
85
+ if [[ -z "$ant_name" || "$ant_name" == "Queen" ]]; then
86
+ jq -n --arg ant "${ant_name:-Queen}" '{ant: $ant, depth: 0}'
87
+ return 0
88
+ fi
89
+
90
+ local file_path="${SPAWN_TREE_FILE}"
91
+
92
+ if [[ ! -f "$file_path" ]]; then
93
+ jq -n --arg ant "$ant_name" '{ant: $ant, depth: 1, found: false}'
94
+ return 0
95
+ fi
96
+
97
+ # Check if ant exists
98
+ # -F: ant_name may contain regex metacharacters (dots, plus, brackets, etc.)
99
+ if ! grep -qF "|$ant_name|" "$file_path" 2>/dev/null; then
100
+ jq -n --arg ant "$ant_name" '{ant: $ant, depth: 1, found: false}'
101
+ return 0
102
+ fi
103
+
104
+ # Calculate depth by traversing parent chain
105
+ local depth=1
106
+ local current="$ant_name"
107
+ local safety=0
108
+
109
+ while [[ $safety -lt 5 ]]; do
110
+ # Find who spawned this ant
111
+ local parent
112
+ parent=$(grep -F "|$current|" "$file_path" 2>/dev/null | grep "|spawned$" | head -1 | cut -d'|' -f2 || echo "")
113
+
114
+ if [[ -z "$parent" || "$parent" == "Queen" ]]; then
115
+ break
116
+ fi
117
+
118
+ ((depth++))
119
+ current="$parent"
120
+ ((safety++))
121
+ done
122
+
123
+ jq -n --arg ant "$ant_name" --argjson depth "$depth" '{ant: $ant, depth: $depth, found: true}'
124
+ }
125
+
126
+ # Get list of active spawns
127
+ # Usage: get_active_spawns [file_path]
128
+ # Returns: JSON array of active spawns
129
+ get_active_spawns() {
130
+ local file_path="${1:-$SPAWN_TREE_FILE}"
131
+
132
+ if [[ ! -f "$file_path" ]] || [[ ! -s "$file_path" ]]; then
133
+ echo "[]"
134
+ return 0
135
+ fi
136
+
137
+ awk -F'|' '
138
+ BEGIN { spawn_n=0 }
139
+ $3 ~ /^(completed|failed|blocked)$/ && NF >= 4 { done_set[$2] = 1 }
140
+ NF == 7 && $7 == "spawned" {
141
+ spawn_names[spawn_n] = $4; spawn_parents[spawn_n] = $2
142
+ spawn_castes[spawn_n] = $3; spawn_tasks[spawn_n] = $5
143
+ spawn_ts[spawn_n] = $1; spawn_n++
144
+ }
145
+ END {
146
+ printf "["
147
+ first = 1
148
+ for (i = 0; i < spawn_n; i++) {
149
+ if (!(spawn_names[i] in done_set)) {
150
+ if (!first) printf ","
151
+ first = 0
152
+ nm = spawn_names[i]; gsub(/\\/, "\\\\", nm); gsub(/"/, "\\\"", nm); gsub(/\t/, "\\t", nm)
153
+ pr = spawn_parents[i]; gsub(/\\/, "\\\\", pr); gsub(/"/, "\\\"", pr); gsub(/\t/, "\\t", pr)
154
+ tk = spawn_tasks[i]; gsub(/\\/, "\\\\", tk); gsub(/"/, "\\\"", tk); gsub(/\t/, "\\t", tk)
155
+ printf "{\"name\":\"%s\",\"caste\":\"%s\",\"parent\":\"%s\",\"task\":\"%s\",\"spawned_at\":\"%s\"}", nm, spawn_castes[i], pr, tk, spawn_ts[i]
156
+ }
157
+ }
158
+ printf "]"
159
+ }
160
+ ' "$file_path"
161
+ }
162
+
163
+ # Get direct children of a spawn
164
+ # Usage: get_spawn_children <ant_name> [file_path]
165
+ # Returns: JSON array of child names
166
+ get_spawn_children() {
167
+ local ant_name="${1:-}"
168
+ local file_path="${2:-$SPAWN_TREE_FILE}"
169
+
170
+ if [[ -z "$ant_name" || ! -f "$file_path" ]]; then
171
+ echo "[]"
172
+ return 0
173
+ fi
174
+
175
+ # Collect children names safely, then build JSON array via jq
176
+ local -a children_arr=()
177
+
178
+ # Find all spawns where parent matches
179
+ while IFS= read -r line || [[ -n "$line" ]]; do
180
+ [[ -z "$line" ]] && continue
181
+
182
+ local pipe_count
183
+ pipe_count=$(echo "$line" | tr -cd '|' | wc -c | tr -d ' ')
184
+
185
+ if [[ $pipe_count -eq 6 ]]; then
186
+ local parent child_name
187
+ parent=$(echo "$line" | cut -d'|' -f2)
188
+ child_name=$(echo "$line" | cut -d'|' -f4)
189
+
190
+ if [[ "$parent" == "$ant_name" ]]; then
191
+ children_arr+=("$child_name")
192
+ fi
193
+ fi
194
+ done < "$file_path"
195
+
196
+ if [[ ${#children_arr[@]} -eq 0 ]]; then
197
+ echo "[]"
198
+ else
199
+ printf '%s\n' "${children_arr[@]}" | jq -R . | jq -s .
200
+ fi
201
+ }
202
+
203
+ # Get full lineage from ant up to Queen
204
+ # Usage: get_spawn_lineage <ant_name> [file_path]
205
+ # Returns: JSON array from ant up to Queen (inclusive)
206
+ get_spawn_lineage() {
207
+ local ant_name="${1:-}"
208
+ local file_path="${2:-$SPAWN_TREE_FILE}"
209
+
210
+ if [[ -z "$ant_name" ]]; then
211
+ echo "[]"
212
+ return 0
213
+ fi
214
+
215
+ if [[ ! -f "$file_path" ]]; then
216
+ jq -n --arg ant "$ant_name" '[$ant, "Queen"]'
217
+ return 0
218
+ fi
219
+
220
+ # Build lineage array (ant first, then ancestors) using jq for safe JSON escaping
221
+ local -a lineage_arr=("$ant_name")
222
+ local current="$ant_name"
223
+ local safety=0
224
+
225
+ while [[ $safety -lt 5 ]]; do
226
+ # Find who spawned this ant
227
+ local parent
228
+ parent=$(grep -F "|$current|" "$file_path" 2>/dev/null | grep "|spawned$" | head -1 | cut -d'|' -f2 || echo "")
229
+
230
+ if [[ -z "$parent" || "$parent" == "Queen" ]]; then
231
+ lineage_arr+=("Queen")
232
+ break
233
+ fi
234
+
235
+ lineage_arr+=("$parent")
236
+ current="$parent"
237
+ ((safety++))
238
+ done
239
+
240
+ # Build JSON array safely via jq
241
+ printf '%s\n' "${lineage_arr[@]}" | jq -R . | jq -s .
242
+ }
243
+
244
+ # Reconstruct full tree as JSON
245
+ # Usage: reconstruct_tree_json [file_path]
246
+ # Returns: Complete spawn tree with metadata
247
+ reconstruct_tree_json() {
248
+ local file_path="${1:-$SPAWN_TREE_FILE}"
249
+ parse_spawn_tree "$file_path"
250
+ }
251
+
252
+ # Export functions if being sourced (Bash 3.2 compatible)
253
+ if [[ "${BASH_SOURCE[0]:-}" != "${0}" ]]; then
254
+ export -f parse_spawn_tree 2>/dev/null || true
255
+ export -f get_spawn_depth 2>/dev/null || true
256
+ export -f get_active_spawns 2>/dev/null || true
257
+ export -f get_spawn_children 2>/dev/null || true
258
+ export -f get_spawn_lineage 2>/dev/null || true
259
+ export -f reconstruct_tree_json 2>/dev/null || true
260
+ fi
@@ -0,0 +1,260 @@
1
+ #!/bin/bash
2
+ # Spawn utility functions — extracted from aether-utils.sh
3
+ # Provides: _spawn_log, _spawn_complete, _spawn_can_spawn, _spawn_get_depth, _spawn_can_spawn_swarm, _spawn_tree_load, _spawn_tree_active, _spawn_tree_depth, _spawn_efficiency
4
+ #
5
+ # These functions are sourced by aether-utils.sh at startup.
6
+ # All shared infrastructure (json_ok, json_err, json_warn, atomic_write, acquire_lock,
7
+ # release_lock, feature_enabled, LOCK_DIR, DATA_DIR, SCRIPT_DIR, error constants) is available.
8
+ # Note: get_caste_emoji is defined in the main file and available to this module at call time.
9
+
10
+ _spawn_log() {
11
+ # Usage: spawn-log <parent_id> <child_caste> <child_name> <task_summary> [model] [status]
12
+ parent_id="${1:-}"
13
+ child_caste="${2:-}"
14
+ child_name="${3:-}"
15
+ task_summary="${4:-}"
16
+ model="${5:-default}"
17
+ status="${6:-spawned}"
18
+ # Model slot resolution removed (archived: .aether/archive/model-routing/)
19
+ # Agent frontmatter model: fields handle routing natively via Claude Code.
20
+ [[ "$model" == "default" ]] && model="inherit"
21
+ [[ -z "$parent_id" || -z "$child_caste" || -z "$task_summary" ]] && json_err "$E_VALIDATION_FAILED" "Usage: spawn-log <parent_id> <child_caste> <child_name> <task_summary> [model] [status]"
22
+ mkdir -p "$COLONY_DATA_DIR"
23
+ ts=$(date -u +"%H:%M:%S")
24
+ ts_full=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
25
+ emoji=$(get_caste_emoji "$child_caste")
26
+ parent_emoji=$(get_caste_emoji "$parent_id")
27
+ # Log to activity log with spawn format, emojis, and model info
28
+ echo "[$ts] ⚡ SPAWN $parent_emoji $parent_id -> $emoji $child_name ($child_caste): $task_summary [model: $model]" >> "$COLONY_DATA_DIR/activity.log"
29
+ # Log to spawn tree file for visualization (NEW FORMAT: includes model field)
30
+ echo "$ts_full|$parent_id|$child_caste|$child_name|$task_summary|$model|$status" >> "$COLONY_DATA_DIR/spawn-tree.txt"
31
+ # Return emoji-formatted result for display (jq-safe: child_name may contain JSON-special chars)
32
+ json_ok "$(jq -n --arg msg "⚡ $emoji $child_name spawned" '$msg')"
33
+ }
34
+
35
+ _spawn_complete() {
36
+ # Migrated to state-api facade: uses _state_mutate for failed spawn event logging
37
+ # Usage: spawn-complete <ant_name> <status> [summary]
38
+ ant_name="${1:-}"
39
+ status="${2:-completed}"
40
+ summary="${3:-}"
41
+ [[ -z "$ant_name" ]] && json_err "$E_VALIDATION_FAILED" "Usage: spawn-complete <ant_name> <status> [summary]"
42
+ mkdir -p "$COLONY_DATA_DIR"
43
+ ts=$(date -u +"%H:%M:%S")
44
+ ts_full=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
45
+ emoji=$(get_caste_emoji "$ant_name")
46
+ status_icon="✅"
47
+ [[ "$status" == "failed" ]] && status_icon="❌"
48
+ [[ "$status" == "blocked" ]] && status_icon="🚫"
49
+ echo "[$ts] $status_icon $emoji $ant_name: $status${summary:+ - $summary}" >> "$COLONY_DATA_DIR/activity.log"
50
+ # Update spawn tree
51
+ echo "$ts_full|$ant_name|$status|$summary" >> "$COLONY_DATA_DIR/spawn-tree.txt"
52
+ # Log failed spawns to events array as pipe-delimited strings (matching template format)
53
+ if [[ "$status" == "failed" ]] || [[ "$status" == "error" ]]; then
54
+ if [[ -f "$DATA_DIR/COLONY_STATE.json" ]]; then
55
+ SC_EVENT="$ts_full|spawn_failed|$ant_name|${summary:-unknown}" \
56
+ _state_mutate '
57
+ .events += [env.SC_EVENT]
58
+ ' >/dev/null 2>&1 || _aether_log_error "Failed to log spawn failure to colony state"
59
+ fi
60
+ fi
61
+ # Return emoji-formatted result for display (jq-safe: ant_name/summary may contain JSON-special chars)
62
+ json_ok "$(jq -n --arg msg "$status_icon $emoji $ant_name: ${summary:-$status}" '$msg')"
63
+ }
64
+
65
+ _spawn_can_spawn() {
66
+ # Check if spawning is allowed at given depth
67
+ # Usage: spawn-can-spawn [depth] [--enforce]
68
+ # Returns: {can_spawn: bool, depth: N, max_spawns: N, current_total: N, global_cap: N}
69
+ # --enforce: fail with non-zero exit when spawning is not allowed
70
+ depth=""
71
+ enforce_mode=false
72
+ for arg in "$@"; do
73
+ case "$arg" in
74
+ --enforce) enforce_mode=true ;;
75
+ *)
76
+ if [[ -z "$depth" ]]; then
77
+ depth="$arg"
78
+ else
79
+ json_err "$E_VALIDATION_FAILED" "Usage: spawn-can-spawn [depth] [--enforce]"
80
+ fi
81
+ ;;
82
+ esac
83
+ done
84
+ [[ -z "$depth" ]] && depth=1
85
+ [[ "$depth" =~ ^[0-9]+$ ]] || json_err "$E_VALIDATION_FAILED" "Depth must be a non-negative integer" "{\"provided\":\"$depth\"}"
86
+
87
+ # Depth limits: 1→4 spawns, 2→2 spawns, 3+→0 spawns
88
+ if [[ $depth -eq 1 ]]; then
89
+ max_for_depth=4
90
+ elif [[ $depth -eq 2 ]]; then
91
+ max_for_depth=2
92
+ else
93
+ max_for_depth=0
94
+ fi
95
+
96
+ # Count current spawns in this session (from spawn-tree.txt)
97
+ current=0
98
+ if [[ -f "$COLONY_DATA_DIR/spawn-tree.txt" ]]; then
99
+ current=$(grep -c "|spawned$" "$COLONY_DATA_DIR/spawn-tree.txt" 2>/dev/null || echo 0) # SUPPRESS:OK -- read-default: count defaults to 0 if file missing
100
+ fi
101
+
102
+ # Global cap of 10 workers per phase
103
+ global_cap=10
104
+
105
+ # Can spawn if: depth < 3 AND under global cap
106
+ if [[ $depth -lt 3 && $current -lt $global_cap ]]; then
107
+ can="true"
108
+ else
109
+ can="false"
110
+ fi
111
+
112
+ if [[ "$enforce_mode" == "true" && "$can" == "false" ]]; then
113
+ json_err "$E_VALIDATION_FAILED" "Spawn cap exceeded: depth=$depth current=$current max=$global_cap"
114
+ fi
115
+
116
+ json_ok "{\"can_spawn\":$can,\"depth\":$depth,\"max_spawns\":$max_for_depth,\"current_total\":$current,\"global_cap\":$global_cap}"
117
+ }
118
+
119
+ _spawn_get_depth() {
120
+ # Return depth for a given ant name by tracing spawn tree
121
+ # Usage: spawn-get-depth <ant_name>
122
+ # Queen = depth 0, Queen's spawns = depth 1, their spawns = depth 2, etc.
123
+ ant_name="${1:-Queen}"
124
+
125
+ if [[ "$ant_name" == "Queen" ]]; then
126
+ json_ok '{"ant":"Queen","depth":0}'
127
+ exit 0
128
+ fi
129
+
130
+ # Check if spawn tree exists
131
+ if [[ ! -f "$COLONY_DATA_DIR/spawn-tree.txt" ]]; then
132
+ json_ok "$(jq -n --arg ant "$ant_name" '{ant: $ant, depth: 1, found: false}')"
133
+ exit 0
134
+ fi
135
+
136
+ # Check if ant exists in spawn tree (gracefully handle missing ants)
137
+ if ! grep -qF "|$ant_name|" "$COLONY_DATA_DIR/spawn-tree.txt" 2>/dev/null; then # SUPPRESS:OK -- existence-test: file may not exist; -F: ant_name may contain regex metacharacters
138
+ json_ok "$(jq -n --arg ant "$ant_name" '{ant: $ant, depth: 1, found: false}')"
139
+ exit 0
140
+ fi
141
+
142
+ # Find the spawn record for this ant and trace parents
143
+ depth=1
144
+ current_ant="$ant_name"
145
+
146
+ # Find who spawned this ant (look for lines with |spawned)
147
+ while true; do
148
+ # Format: timestamp|parent|caste|child_name|task|spawned
149
+ # SUPPRESS:OK -- read-default: returns fallback on failure
150
+ parent=$(grep -F "|$current_ant|" "$COLONY_DATA_DIR/spawn-tree.txt" 2>/dev/null | grep "|spawned$" | head -1 | cut -d'|' -f2 || echo "")
151
+
152
+ if [[ -z "$parent" || "$parent" == "Queen" ]]; then
153
+ break
154
+ fi
155
+
156
+ depth=$((depth + 1))
157
+ current_ant="$parent"
158
+
159
+ # Safety limit
160
+ if [[ $depth -gt 5 ]]; then
161
+ break
162
+ fi
163
+ done
164
+
165
+ json_ok "$(jq -n --arg ant "$ant_name" --argjson depth "$depth" '{ant: $ant, depth: $depth, found: true}')"
166
+ }
167
+
168
+ _spawn_can_spawn_swarm() {
169
+ # Check if swarm can spawn more scouts (separate from phase workers)
170
+ # Usage: spawn-can-spawn-swarm <swarm_id>
171
+ # Swarm has its own cap of 6 (4 scouts + 2 sub-scouts max)
172
+ swarm_id="${1:-swarm}"
173
+ swarm_cap=6
174
+
175
+ current=0
176
+ if [[ -f "$COLONY_DATA_DIR/spawn-tree.txt" ]]; then
177
+ # SUPPRESS:OK -- existence-test: grep returns 1 when no matches
178
+ # -F: swarm_id may contain regex metacharacters; anchor $ dropped (swarm_id is unique, no substring collision risk)
179
+ current=$(grep -cF "|swarm:$swarm_id" "$COLONY_DATA_DIR/spawn-tree.txt" 2>/dev/null) || current=0
180
+ fi
181
+
182
+ if [[ $current -lt $swarm_cap ]]; then
183
+ can="true"
184
+ remaining=$((swarm_cap - current))
185
+ else
186
+ can="false"
187
+ remaining=0
188
+ fi
189
+
190
+ json_ok "$(jq -n --argjson can_spawn "$can" --argjson current "$current" \
191
+ --argjson cap "$swarm_cap" --argjson remaining "$remaining" --arg swarm_id "$swarm_id" \
192
+ '{can_spawn: $can_spawn, current: $current, cap: $cap, remaining: $remaining, swarm_id: $swarm_id}')"
193
+ }
194
+
195
+ _spawn_tree_load() {
196
+ source "$SCRIPT_DIR/utils/spawn-tree.sh" 2>/dev/null || { # SUPPRESS:OK -- read-default: utility may not be installed
197
+ json_err "$E_FILE_NOT_FOUND" "spawn-tree.sh not found"
198
+ exit 1
199
+ }
200
+ tree_json=$(reconstruct_tree_json)
201
+ if echo "$tree_json" | jq -e . >/dev/null 2>&1; then
202
+ json_ok "$tree_json"
203
+ else
204
+ json_err "$E_VALIDATION_FAILED" "spawn tree reconstruction produced invalid JSON"
205
+ return 1
206
+ fi
207
+ }
208
+
209
+ _spawn_tree_active() {
210
+ source "$SCRIPT_DIR/utils/spawn-tree.sh" 2>/dev/null || { # SUPPRESS:OK -- read-default: utility may not be installed
211
+ json_err "$E_FILE_NOT_FOUND" "spawn-tree.sh not found"
212
+ exit 1
213
+ }
214
+ active=$(get_active_spawns)
215
+ if echo "$active" | jq -e . >/dev/null 2>&1; then
216
+ json_ok "$active"
217
+ else
218
+ json_err "$E_VALIDATION_FAILED" "spawn-tree active produced invalid JSON"
219
+ return 1
220
+ fi
221
+ }
222
+
223
+ _spawn_tree_depth() {
224
+ ant_name="${1:-}"
225
+ [[ -z "$ant_name" ]] && json_err "$E_VALIDATION_FAILED" "Usage: spawn-tree-depth <ant_name>"
226
+ source "$SCRIPT_DIR/utils/spawn-tree.sh" 2>/dev/null || { # SUPPRESS:OK -- read-default: utility may not be installed
227
+ json_err "$E_FILE_NOT_FOUND" "spawn-tree.sh not found"
228
+ exit 1
229
+ }
230
+ depth=$(get_spawn_depth "$ant_name")
231
+ if echo "$depth" | jq -e . >/dev/null 2>&1; then
232
+ json_ok "$depth"
233
+ else
234
+ json_err "$E_VALIDATION_FAILED" "spawn-tree depth produced invalid JSON"
235
+ return 1
236
+ fi
237
+ }
238
+
239
+ _spawn_efficiency() {
240
+ # Calculate spawn efficiency metrics from spawn-tree.txt
241
+ # Usage: spawn-efficiency
242
+ spawn_tree_file="$COLONY_DATA_DIR/spawn-tree.txt"
243
+ total=0
244
+ completed=0
245
+ failed=0
246
+
247
+ if [[ -f "$spawn_tree_file" ]]; then
248
+ total=$(grep -c "|spawned$" "$spawn_tree_file" 2>/dev/null || echo 0) # SUPPRESS:OK -- read-default: count defaults to 0 if file missing
249
+ completed=$(grep -c "|completed$" "$spawn_tree_file" 2>/dev/null || echo 0) # SUPPRESS:OK -- read-default: count defaults to 0 if file missing
250
+ failed=$(grep -c "|failed$" "$spawn_tree_file" 2>/dev/null || echo 0) # SUPPRESS:OK -- read-default: count defaults to 0 if file missing
251
+ fi
252
+
253
+ if [[ "$total" -gt 0 ]]; then
254
+ efficiency=$(( completed * 100 / total ))
255
+ else
256
+ efficiency=0
257
+ fi
258
+
259
+ json_ok "{\"total\":$total,\"completed\":$completed,\"failed\":$failed,\"efficiency_pct\":$efficiency}"
260
+ }