aether-colony 5.0.0 → 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 (312) hide show
  1. package/.aether/aether-utils.sh +3150 -3349
  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 +11 -11
  72. package/.aether/docs/README.md +32 -2
  73. package/.aether/docs/command-playbooks/README.md +23 -0
  74. package/.aether/docs/command-playbooks/build-complete.md +349 -0
  75. package/.aether/docs/command-playbooks/build-context.md +282 -0
  76. package/.aether/docs/command-playbooks/build-full.md +1682 -0
  77. package/.aether/docs/command-playbooks/build-prep.md +283 -0
  78. package/.aether/docs/command-playbooks/build-verify.md +405 -0
  79. package/.aether/docs/command-playbooks/build-wave.md +749 -0
  80. package/.aether/docs/command-playbooks/continue-advance.md +524 -0
  81. package/.aether/docs/command-playbooks/continue-finalize.md +447 -0
  82. package/.aether/docs/command-playbooks/continue-full.md +1724 -0
  83. package/.aether/docs/command-playbooks/continue-gates.md +686 -0
  84. package/.aether/docs/command-playbooks/continue-verify.md +406 -0
  85. package/.aether/docs/context-continuity.md +84 -0
  86. package/.aether/docs/disciplines/DISCIPLINES.md +9 -7
  87. package/.aether/docs/error-codes.md +1 -1
  88. package/.aether/docs/known-issues.md +34 -173
  89. package/.aether/docs/pheromones.md +86 -6
  90. package/.aether/docs/plans/pheromone-display-plan.md +257 -0
  91. package/.aether/docs/queen-commands.md +10 -9
  92. package/.aether/docs/source-of-truth-map.md +132 -0
  93. package/.aether/docs/xml-utilities.md +47 -0
  94. package/.aether/rules/aether-colony.md +23 -13
  95. package/.aether/scripts/incident-test-add.sh +47 -0
  96. package/.aether/scripts/weekly-audit.sh +79 -0
  97. package/.aether/skills/.index.json +649 -0
  98. package/.aether/skills/colony/.manifest.json +16 -0
  99. package/.aether/skills/colony/build-discipline/SKILL.md +78 -0
  100. package/.aether/skills/colony/colony-interaction/SKILL.md +56 -0
  101. package/.aether/skills/colony/colony-lifecycle/SKILL.md +77 -0
  102. package/.aether/skills/colony/colony-visuals/SKILL.md +112 -0
  103. package/.aether/skills/colony/context-management/SKILL.md +80 -0
  104. package/.aether/skills/colony/error-presentation/SKILL.md +99 -0
  105. package/.aether/skills/colony/pheromone-protocol/SKILL.md +79 -0
  106. package/.aether/skills/colony/pheromone-visibility/SKILL.md +81 -0
  107. package/.aether/skills/colony/state-safety/SKILL.md +84 -0
  108. package/.aether/skills/colony/worker-priming/SKILL.md +82 -0
  109. package/.aether/skills/domain/.manifest.json +24 -0
  110. package/.aether/skills/domain/README.md +33 -0
  111. package/.aether/skills/domain/django/SKILL.md +49 -0
  112. package/.aether/skills/domain/docker/SKILL.md +52 -0
  113. package/.aether/skills/domain/golang/SKILL.md +52 -0
  114. package/.aether/skills/domain/graphql/SKILL.md +51 -0
  115. package/.aether/skills/domain/html-css/SKILL.md +48 -0
  116. package/.aether/skills/domain/nextjs/SKILL.md +45 -0
  117. package/.aether/skills/domain/nodejs/SKILL.md +53 -0
  118. package/.aether/skills/domain/postgresql/SKILL.md +53 -0
  119. package/.aether/skills/domain/prisma/SKILL.md +59 -0
  120. package/.aether/skills/domain/python/SKILL.md +50 -0
  121. package/.aether/skills/domain/rails/SKILL.md +52 -0
  122. package/.aether/skills/domain/react/SKILL.md +45 -0
  123. package/.aether/skills/domain/rest-api/SKILL.md +58 -0
  124. package/.aether/skills/domain/svelte/SKILL.md +47 -0
  125. package/.aether/skills/domain/tailwind/SKILL.md +45 -0
  126. package/.aether/skills/domain/testing/SKILL.md +53 -0
  127. package/.aether/skills/domain/typescript/SKILL.md +58 -0
  128. package/.aether/skills/domain/vue/SKILL.md +49 -0
  129. package/.aether/templates/QUEEN.md.template +23 -41
  130. package/.aether/templates/colony-state-reset.jq.template +1 -0
  131. package/.aether/templates/colony-state.template.json +4 -0
  132. package/.aether/templates/learning-observations.template.json +6 -0
  133. package/.aether/templates/midden.template.json +13 -0
  134. package/.aether/templates/pheromones.template.json +6 -0
  135. package/.aether/templates/session.template.json +9 -0
  136. package/.aether/utils/atomic-write.sh +63 -17
  137. package/.aether/utils/chamber-utils.sh +145 -2
  138. package/.aether/utils/emoji-audit.sh +166 -0
  139. package/.aether/utils/error-handler.sh +21 -7
  140. package/.aether/utils/file-lock.sh +182 -27
  141. package/.aether/utils/flag.sh +267 -0
  142. package/.aether/utils/hive.sh +572 -0
  143. package/.aether/utils/learning.sh +1928 -0
  144. package/.aether/utils/midden.sh +342 -0
  145. package/.aether/utils/oracle/oracle.md +168 -0
  146. package/.aether/utils/oracle/oracle.sh +1023 -0
  147. package/.aether/utils/pheromone.sh +2029 -0
  148. package/.aether/utils/queen.sh +1698 -0
  149. package/.aether/utils/scan.sh +860 -0
  150. package/.aether/utils/semantic-cli.sh +10 -8
  151. package/.aether/utils/session.sh +552 -0
  152. package/.aether/utils/skills.sh +509 -0
  153. package/.aether/utils/spawn-tree.sh +103 -271
  154. package/.aether/utils/spawn.sh +260 -0
  155. package/.aether/utils/state-api.sh +199 -0
  156. package/.aether/utils/state-loader.sh +8 -6
  157. package/.aether/utils/suggest.sh +611 -0
  158. package/.aether/utils/swarm-display.sh +10 -1
  159. package/.aether/utils/swarm.sh +1004 -0
  160. package/.aether/utils/watch-spawn-tree.sh +11 -2
  161. package/.aether/utils/xml-compose.sh +2 -2
  162. package/.aether/utils/xml-convert.sh +9 -5
  163. package/.aether/utils/xml-core.sh +5 -9
  164. package/.aether/utils/xml-query.sh +4 -4
  165. package/.aether/workers.md +86 -67
  166. package/.claude/agents/ant/aether-ambassador.md +2 -1
  167. package/.claude/agents/ant/aether-archaeologist.md +6 -1
  168. package/.claude/agents/ant/aether-architect.md +236 -0
  169. package/.claude/agents/ant/aether-auditor.md +6 -1
  170. package/.claude/agents/ant/aether-builder.md +38 -1
  171. package/.claude/agents/ant/aether-chaos.md +2 -1
  172. package/.claude/agents/ant/aether-chronicler.md +1 -0
  173. package/.claude/agents/ant/aether-gatekeeper.md +6 -1
  174. package/.claude/agents/ant/aether-includer.md +1 -0
  175. package/.claude/agents/ant/aether-keeper.md +1 -0
  176. package/.claude/agents/ant/aether-measurer.md +6 -1
  177. package/.claude/agents/ant/aether-oracle.md +237 -0
  178. package/.claude/agents/ant/aether-probe.md +2 -1
  179. package/.claude/agents/ant/aether-queen.md +6 -1
  180. package/.claude/agents/ant/aether-route-setter.md +6 -1
  181. package/.claude/agents/ant/aether-sage.md +68 -3
  182. package/.claude/agents/ant/aether-scout.md +38 -1
  183. package/.claude/agents/ant/aether-surveyor-disciplines.md +2 -1
  184. package/.claude/agents/ant/aether-surveyor-nest.md +2 -1
  185. package/.claude/agents/ant/aether-surveyor-pathogens.md +2 -1
  186. package/.claude/agents/ant/aether-surveyor-provisions.md +2 -1
  187. package/.claude/agents/ant/aether-tracker.md +6 -1
  188. package/.claude/agents/ant/aether-watcher.md +37 -1
  189. package/.claude/agents/ant/aether-weaver.md +2 -1
  190. package/.claude/commands/ant/archaeology.md +1 -8
  191. package/.claude/commands/ant/build.md +43 -1159
  192. package/.claude/commands/ant/chaos.md +1 -14
  193. package/.claude/commands/ant/colonize.md +1 -14
  194. package/.claude/commands/ant/continue.md +40 -1026
  195. package/.claude/commands/ant/council.md +9 -16
  196. package/.claude/commands/ant/data-clean.md +81 -0
  197. package/.claude/commands/ant/dream.md +12 -9
  198. package/.claude/commands/ant/entomb.md +62 -87
  199. package/.claude/commands/ant/export-signals.md +57 -0
  200. package/.claude/commands/ant/feedback.md +18 -0
  201. package/.claude/commands/ant/flag.md +12 -0
  202. package/.claude/commands/ant/flags.md +22 -8
  203. package/.claude/commands/ant/focus.md +18 -0
  204. package/.claude/commands/ant/help.md +40 -8
  205. package/.claude/commands/ant/history.md +3 -0
  206. package/.claude/commands/ant/import-signals.md +71 -0
  207. package/.claude/commands/ant/init.md +316 -191
  208. package/.claude/commands/ant/insert-phase.md +101 -0
  209. package/.claude/commands/ant/interpret.md +11 -0
  210. package/.claude/commands/ant/lay-eggs.md +167 -158
  211. package/.claude/commands/ant/maturity.md +22 -11
  212. package/.claude/commands/ant/memory-details.md +77 -0
  213. package/.claude/commands/ant/migrate-state.md +6 -0
  214. package/.claude/commands/ant/oracle.md +317 -62
  215. package/.claude/commands/ant/organize.md +10 -5
  216. package/.claude/commands/ant/patrol.md +620 -0
  217. package/.claude/commands/ant/pause-colony.md +8 -22
  218. package/.claude/commands/ant/phase.md +26 -37
  219. package/.claude/commands/ant/pheromones.md +156 -0
  220. package/.claude/commands/ant/plan.md +175 -52
  221. package/.claude/commands/ant/preferences.md +65 -0
  222. package/.claude/commands/ant/redirect.md +18 -0
  223. package/.claude/commands/ant/resume-colony.md +34 -20
  224. package/.claude/commands/ant/resume.md +51 -7
  225. package/.claude/commands/ant/run.md +195 -0
  226. package/.claude/commands/ant/seal.md +497 -78
  227. package/.claude/commands/ant/skill-create.md +286 -0
  228. package/.claude/commands/ant/status.md +127 -1
  229. package/.claude/commands/ant/swarm.md +11 -23
  230. package/.claude/commands/ant/tunnels.md +1 -0
  231. package/.claude/commands/ant/update.md +58 -135
  232. package/.claude/commands/ant/verify-castes.md +90 -42
  233. package/.claude/commands/ant/watch.md +1 -0
  234. package/.opencode/agents/aether-ambassador.md +1 -1
  235. package/.opencode/agents/aether-architect.md +133 -0
  236. package/.opencode/agents/aether-builder.md +3 -3
  237. package/.opencode/agents/aether-oracle.md +137 -0
  238. package/.opencode/agents/aether-queen.md +1 -1
  239. package/.opencode/agents/aether-route-setter.md +1 -1
  240. package/.opencode/agents/aether-scout.md +1 -1
  241. package/.opencode/agents/aether-surveyor-disciplines.md +6 -1
  242. package/.opencode/agents/aether-surveyor-nest.md +6 -1
  243. package/.opencode/agents/aether-surveyor-pathogens.md +6 -1
  244. package/.opencode/agents/aether-surveyor-provisions.md +6 -1
  245. package/.opencode/agents/aether-tracker.md +1 -1
  246. package/.opencode/agents/aether-watcher.md +1 -1
  247. package/.opencode/agents/aether-weaver.md +1 -1
  248. package/.opencode/commands/ant/archaeology.md +7 -14
  249. package/.opencode/commands/ant/build.md +54 -88
  250. package/.opencode/commands/ant/chaos.md +7 -24
  251. package/.opencode/commands/ant/colonize.md +8 -17
  252. package/.opencode/commands/ant/continue.md +595 -66
  253. package/.opencode/commands/ant/council.md +11 -22
  254. package/.opencode/commands/ant/data-clean.md +77 -0
  255. package/.opencode/commands/ant/dream.md +15 -17
  256. package/.opencode/commands/ant/entomb.md +28 -18
  257. package/.opencode/commands/ant/export-signals.md +54 -0
  258. package/.opencode/commands/ant/feedback.md +24 -5
  259. package/.opencode/commands/ant/flag.md +16 -4
  260. package/.opencode/commands/ant/flags.md +24 -10
  261. package/.opencode/commands/ant/focus.md +22 -5
  262. package/.opencode/commands/ant/help.md +41 -8
  263. package/.opencode/commands/ant/history.md +9 -0
  264. package/.opencode/commands/ant/import-signals.md +68 -0
  265. package/.opencode/commands/ant/init.md +365 -156
  266. package/.opencode/commands/ant/insert-phase.md +107 -0
  267. package/.opencode/commands/ant/interpret.md +16 -0
  268. package/.opencode/commands/ant/lay-eggs.md +184 -112
  269. package/.opencode/commands/ant/maturity.md +18 -2
  270. package/.opencode/commands/ant/memory-details.md +83 -0
  271. package/.opencode/commands/ant/migrate-state.md +12 -0
  272. package/.opencode/commands/ant/oracle.md +322 -67
  273. package/.opencode/commands/ant/organize.md +14 -12
  274. package/.opencode/commands/ant/patrol.md +626 -0
  275. package/.opencode/commands/ant/pause-colony.md +12 -29
  276. package/.opencode/commands/ant/phase.md +30 -40
  277. package/.opencode/commands/ant/pheromones.md +162 -0
  278. package/.opencode/commands/ant/plan.md +184 -56
  279. package/.opencode/commands/ant/preferences.md +71 -0
  280. package/.opencode/commands/ant/redirect.md +22 -5
  281. package/.opencode/commands/ant/resume-colony.md +38 -27
  282. package/.opencode/commands/ant/resume.md +71 -20
  283. package/.opencode/commands/ant/run.md +201 -0
  284. package/.opencode/commands/ant/seal.md +230 -25
  285. package/.opencode/commands/ant/skill-create.md +63 -0
  286. package/.opencode/commands/ant/status.md +124 -31
  287. package/.opencode/commands/ant/swarm.md +3 -345
  288. package/.opencode/commands/ant/tunnels.md +3 -9
  289. package/.opencode/commands/ant/update.md +63 -127
  290. package/.opencode/commands/ant/verify-castes.md +96 -42
  291. package/.opencode/commands/ant/watch.md +7 -0
  292. package/CHANGELOG.md +278 -1
  293. package/README.md +188 -340
  294. package/bin/cli.js +236 -429
  295. package/bin/generate-commands.js +186 -0
  296. package/bin/generate-commands.sh +128 -89
  297. package/bin/lib/spawn-logger.js +0 -15
  298. package/bin/lib/update-transaction.js +285 -35
  299. package/bin/npx-install.js +178 -0
  300. package/bin/validate-package.sh +85 -3
  301. package/package.json +7 -3
  302. package/.aether/CONTEXT.md +0 -160
  303. package/.aether/docs/QUEEN.md +0 -84
  304. package/.aether/exchange/colony-registry.xml +0 -11
  305. package/.aether/exchange/pheromones.xml +0 -87
  306. package/.aether/exchange/queen-wisdom.xml +0 -14
  307. package/.aether/model-profiles.yaml +0 -100
  308. package/.aether/utils/spawn-with-model.sh +0 -56
  309. package/bin/lib/model-profiles.js +0 -445
  310. package/bin/lib/model-verify.js +0 -288
  311. package/bin/lib/proxy-health.js +0 -253
  312. package/bin/lib/telemetry.js +0 -441
@@ -0,0 +1,342 @@
1
+ #!/bin/bash
2
+ # Midden (failure tracking) utility functions — extracted from aether-utils.sh
3
+ # Provides: _midden_write, _midden_recent_failures, _midden_review, _midden_acknowledge
4
+ #
5
+ # These functions are sourced by aether-utils.sh at startup.
6
+ # All shared infrastructure (json_ok, json_err, atomic_write, acquire_lock,
7
+ # release_lock, LOCK_DIR, DATA_DIR, SCRIPT_DIR, error constants) is available.
8
+
9
+ _midden_try_write() {
10
+ # Helper: write updated JSON to midden file with retry
11
+ # Usage: _midden_try_write <updated_json> <midden_file>
12
+ # Returns: 0 on success, 1 on failure
13
+ local mtw_json="$1"
14
+ local mtw_file="$2"
15
+ local mtw_tmp="${mtw_file}.tmp.$$"
16
+
17
+ if ! { printf '%s\n' "$mtw_json" > "$mtw_tmp" && mv "$mtw_tmp" "$mtw_file"; }; then
18
+ # Silent retry (once)
19
+ if ! { printf '%s\n' "$mtw_json" > "$mtw_tmp" && mv "$mtw_tmp" "$mtw_file"; }; then
20
+ echo "Warning: Midden write failed after retry -- entry may not have been saved." >&2
21
+ return 1
22
+ fi
23
+ fi
24
+ return 0
25
+ }
26
+
27
+ _midden_write() {
28
+ # Write a warning/observation to the midden for later review
29
+ # Usage: midden-write <category> <message> <source>
30
+ # Example: midden-write "security" "High CVEs found: 3" "gatekeeper"
31
+ # Returns: JSON with success status and entry details
32
+
33
+ mw_category="${1:-general}"
34
+ mw_message="${2:-}"
35
+ mw_source="${3:-unknown}"
36
+
37
+ # Graceful degradation: if no message, return success but note it
38
+ if [[ -z "$mw_message" ]]; then
39
+ json_ok "{\"success\":true,\"warning\":\"no_message_provided\",\"entry_id\":null}"
40
+ return 0
41
+ fi
42
+
43
+ mw_midden_dir="$COLONY_DATA_DIR/midden"
44
+ mw_midden_file="$mw_midden_dir/midden.json"
45
+ mw_timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
46
+ mw_entry_id="midden_$(date +%s)_$$"
47
+
48
+ # Create midden directory if it doesn't exist
49
+ mkdir -p "$mw_midden_dir"
50
+
51
+ # Initialize midden.json if it doesn't exist
52
+ if [[ ! -f "$mw_midden_file" ]]; then
53
+ printf '%s\n' '{"version":"1.0.0","entries":[]}' > "$mw_midden_file"
54
+ fi
55
+
56
+ # Create the new entry using jq for safe JSON construction
57
+ mw_new_entry=$(jq -n \
58
+ --arg id "$mw_entry_id" \
59
+ --arg ts "$mw_timestamp" \
60
+ --arg cat "$mw_category" \
61
+ --arg src "$mw_source" \
62
+ --arg msg "$mw_message" \
63
+ '{id: $id, timestamp: $ts, category: $cat, source: $src, message: $msg, reviewed: false}')
64
+
65
+ # Append to midden.json using jq with locking
66
+ if acquire_lock "$mw_midden_file" 2>/dev/null; then
67
+ mw_updated_midden=$(jq --argjson entry "$mw_new_entry" '
68
+ .entries += [$entry] |
69
+ .entry_count = (.entries | length)
70
+ ' "$mw_midden_file" 2>/dev/null)
71
+
72
+ if [[ -n "$mw_updated_midden" ]]; then
73
+ _midden_try_write "$mw_updated_midden" "$mw_midden_file"
74
+ release_lock 2>/dev/null || true
75
+ mw_total=$(jq '.entries | length' "$mw_midden_file" 2>/dev/null || echo 0)
76
+ json_ok "$(jq -n --arg entry_id "$mw_entry_id" --arg category "$mw_category" --argjson midden_total "$mw_total" \
77
+ '{success: true, entry_id: $entry_id, category: $category, midden_total: $midden_total}')"
78
+ else
79
+ release_lock 2>/dev/null || true
80
+ json_ok "{\"success\":true,\"warning\":\"jq_processing_failed\",\"entry_id\":null}"
81
+ fi
82
+ else
83
+ # Lock failed — graceful degradation, try without lock
84
+ echo "Warning: Midden write completed without lock -- if another write happened at the same time, one entry may be missing." >&2
85
+ mw_updated_midden=$(jq --argjson entry "$mw_new_entry" '
86
+ .entries += [$entry] |
87
+ .entry_count = (.entries | length)
88
+ ' "$mw_midden_file" 2>/dev/null)
89
+
90
+ if [[ -n "$mw_updated_midden" ]]; then
91
+ _midden_try_write "$mw_updated_midden" "$mw_midden_file"
92
+ json_ok "$(jq -n --arg entry_id "$mw_entry_id" --arg category "$mw_category" \
93
+ '{success: true, entry_id: $entry_id, category: $category, warning: "lock_unavailable"}')"
94
+ else
95
+ json_ok "{\"success\":true,\"warning\":\"jq_processing_failed\",\"entry_id\":null}"
96
+ fi
97
+ fi
98
+ }
99
+
100
+ _midden_recent_failures() {
101
+ # Extract recent failure entries from midden.json
102
+ # Usage: midden-recent-failures [limit]
103
+ # Returns: JSON with count and failures array
104
+
105
+ limit="${1:-5}"
106
+ midden_file="$COLONY_DATA_DIR/midden/midden.json"
107
+
108
+ if [[ ! -f "$midden_file" ]]; then
109
+ echo '{"count":0,"failures":[]}'
110
+ return 0
111
+ fi
112
+
113
+ # Extract failures from .entries[], sort by timestamp descending, limit results
114
+ result=$(jq --argjson limit "$limit" '{
115
+ "count": ([.entries[]?] | length),
116
+ "failures": ([.entries[]?] | sort_by(.timestamp) | reverse | .[:$limit] | [.[] | {timestamp, category, source, message}])
117
+ }' "$midden_file" 2>/dev/null)
118
+
119
+ if [[ -z "$result" ]]; then
120
+ echo '{"count":0,"failures":[]}'
121
+ else
122
+ echo "$result"
123
+ fi
124
+ return 0
125
+ }
126
+
127
+ _midden_review() {
128
+ # Review unacknowledged midden entries grouped by category
129
+ # Usage: midden-review [--category <cat>] [--limit N] [--include-acknowledged]
130
+ # Returns: JSON with unacknowledged_count, categories summary, and entries array
131
+
132
+ mr_category=""
133
+ mr_limit=20
134
+ mr_include_ack=false
135
+
136
+ while [[ $# -gt 0 ]]; do
137
+ case "$1" in
138
+ --category) mr_category="${2:-}"; shift 2 ;;
139
+ --limit) mr_limit="${2:-20}"; shift 2 ;;
140
+ --include-acknowledged) mr_include_ack=true; shift ;;
141
+ *) shift ;;
142
+ esac
143
+ done
144
+
145
+ mr_midden_file="$COLONY_DATA_DIR/midden/midden.json"
146
+
147
+ if [[ ! -f "$mr_midden_file" ]]; then
148
+ json_ok '{"unacknowledged_count":0,"categories":{},"entries":[]}'
149
+ return 0
150
+ fi
151
+
152
+ # Build jq filter based on options
153
+ mr_result=$(jq \
154
+ --arg category "$mr_category" \
155
+ --argjson limit "$mr_limit" \
156
+ --argjson include_ack "$mr_include_ack" \
157
+ '
158
+ # Start with all entries
159
+ [.entries // [] | .[] |
160
+ # Filter acknowledged unless --include-acknowledged
161
+ if $include_ack then . else select(.acknowledged != true) end |
162
+ # Filter by category if specified
163
+ if ($category | length) > 0 then select(.category == $category) else . end
164
+ ] |
165
+ # Sort by timestamp descending
166
+ sort_by(.timestamp) | reverse |
167
+ # Compute categories before limiting
168
+ . as $all |
169
+ # Apply limit
170
+ ($all | .[:$limit]) as $limited |
171
+ # Group $all by category for counts
172
+ ($all | group_by(.category) | map({key: .[0].category, value: length}) | from_entries) as $cats |
173
+ {
174
+ unacknowledged_count: ($all | length),
175
+ categories: $cats,
176
+ entries: $limited
177
+ }
178
+ ' "$mr_midden_file" 2>/dev/null)
179
+
180
+ if [[ -z "$mr_result" ]]; then
181
+ json_ok '{"unacknowledged_count":0,"categories":{},"entries":[]}'
182
+ else
183
+ json_ok "$mr_result"
184
+ fi
185
+ return 0
186
+ }
187
+
188
+ _midden_ingest_errors() {
189
+ # Ingest entries from errors.log into midden
190
+ # Usage: midden-ingest-errors [--dry-run]
191
+ # Returns: JSON with count of ingested entries
192
+ # After ingestion, moves errors.log to errors.log.ingested
193
+
194
+ mie_dry_run=false
195
+ while [[ $# -gt 0 ]]; do
196
+ case "$1" in
197
+ --dry-run) mie_dry_run=true; shift ;;
198
+ *) shift ;;
199
+ esac
200
+ done
201
+
202
+ mie_errors_file="$COLONY_DATA_DIR/errors.log"
203
+
204
+ # No errors.log → nothing to ingest
205
+ if [[ ! -f "$mie_errors_file" ]]; then
206
+ json_ok '{"ingested":0}'
207
+ return 0
208
+ fi
209
+
210
+ # Empty file → nothing to ingest
211
+ if [[ ! -s "$mie_errors_file" ]]; then
212
+ json_ok '{"ingested":0}'
213
+ return 0
214
+ fi
215
+
216
+ mie_count=0
217
+
218
+ # Read line by line (avoid pipe-to-while subshell)
219
+ while IFS= read -r mie_line; do
220
+ # Skip blank lines
221
+ [[ -z "$mie_line" ]] && continue
222
+
223
+ # Parse timestamp from [YYYY-...Z] prefix
224
+ mie_timestamp=""
225
+ mie_message="$mie_line"
226
+ if [[ "$mie_line" =~ ^\[([^\]]+)\]\ (.*) ]]; then
227
+ mie_timestamp="${BASH_REMATCH[1]}"
228
+ mie_message="${BASH_REMATCH[2]}"
229
+ fi
230
+
231
+ mie_count=$((mie_count + 1))
232
+
233
+ if [[ "$mie_dry_run" == "false" ]]; then
234
+ _midden_write "error_log" "$mie_message" "error-handler" >/dev/null 2>&1 || true
235
+ fi
236
+ done < "$mie_errors_file"
237
+
238
+ # Move the file (not dry-run only)
239
+ if [[ "$mie_dry_run" == "false" && "$mie_count" -gt 0 ]]; then
240
+ mv "$mie_errors_file" "${mie_errors_file}.ingested"
241
+ fi
242
+
243
+ json_ok "{\"ingested\":$mie_count}"
244
+ return 0
245
+ }
246
+
247
+ _midden_acknowledge() {
248
+ # Acknowledge midden entries by id or by category
249
+ # Usage: midden-acknowledge --id <entry_id> [--reason <reason>]
250
+ # OR: midden-acknowledge --category <cat> --reason <reason>
251
+ # Returns: JSON with acknowledged=true, count, and reason
252
+
253
+ ma_id=""
254
+ ma_category=""
255
+ ma_reason=""
256
+
257
+ while [[ $# -gt 0 ]]; do
258
+ case "$1" in
259
+ --id) ma_id="${2:-}"; shift 2 ;;
260
+ --category) ma_category="${2:-}"; shift 2 ;;
261
+ --reason) ma_reason="${2:-}"; shift 2 ;;
262
+ *) shift ;;
263
+ esac
264
+ done
265
+
266
+ # Validate: need either --id or --category
267
+ if [[ -z "$ma_id" && -z "$ma_category" ]]; then
268
+ json_err "$E_VALIDATION_FAILED" "midden-acknowledge requires --id or --category"
269
+ fi
270
+
271
+ ma_midden_file="$COLONY_DATA_DIR/midden/midden.json"
272
+
273
+ if [[ ! -f "$ma_midden_file" ]]; then
274
+ json_err "$E_FILE_NOT_FOUND" "midden.json not found"
275
+ fi
276
+
277
+ ma_now=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
278
+
279
+ # Acquire lock with trap-based cleanup
280
+ acquire_lock "$ma_midden_file" || {
281
+ json_err "$E_LOCK_FAILED" "Failed to acquire lock on midden.json"
282
+ }
283
+ trap 'release_lock 2>/dev/null || true' EXIT
284
+
285
+ if [[ -n "$ma_id" ]]; then
286
+ # Acknowledge single entry by id
287
+ ma_exists=$(jq --arg id "$ma_id" '[.entries[]? | select(.id == $id)] | length > 0' "$ma_midden_file" 2>/dev/null || echo "false")
288
+ if [[ "$ma_exists" != "true" ]]; then
289
+ trap - EXIT
290
+ release_lock 2>/dev/null || true
291
+ json_err "$E_RESOURCE_NOT_FOUND" "Midden entry '$ma_id' not found"
292
+ fi
293
+
294
+ ma_updated=$(jq \
295
+ --arg id "$ma_id" \
296
+ --arg now "$ma_now" \
297
+ --arg reason "$ma_reason" \
298
+ '
299
+ .entries = [.entries[] |
300
+ if .id == $id then
301
+ . + {acknowledged: true, acknowledged_at: $now, acknowledge_reason: $reason}
302
+ else
303
+ .
304
+ end
305
+ ]
306
+ ' "$ma_midden_file" 2>/dev/null)
307
+
308
+ ma_count=1
309
+ else
310
+ # Acknowledge all entries matching category
311
+ ma_count=$(jq --arg cat "$ma_category" '[.entries[]? | select(.category == $cat and .acknowledged != true)] | length' "$ma_midden_file" 2>/dev/null || echo "0")
312
+
313
+ ma_updated=$(jq \
314
+ --arg cat "$ma_category" \
315
+ --arg now "$ma_now" \
316
+ --arg reason "$ma_reason" \
317
+ '
318
+ .entries = [.entries[] |
319
+ if .category == $cat and .acknowledged != true then
320
+ . + {acknowledged: true, acknowledged_at: $now, acknowledge_reason: $reason}
321
+ else
322
+ .
323
+ end
324
+ ]
325
+ ' "$ma_midden_file" 2>/dev/null)
326
+ fi
327
+
328
+ if [[ -z "$ma_updated" ]]; then
329
+ trap - EXIT
330
+ release_lock 2>/dev/null || true
331
+ json_err "$E_INTERNAL" "Failed to update midden.json"
332
+ fi
333
+
334
+ atomic_write "$ma_midden_file" "$ma_updated"
335
+
336
+ trap - EXIT
337
+ release_lock 2>/dev/null || true
338
+
339
+ json_ok "$(jq -n --argjson count "$ma_count" --arg reason "$ma_reason" \
340
+ '{acknowledged: true, count: $count, reason: $reason}')"
341
+ return 0
342
+ }
@@ -0,0 +1,168 @@
1
+ You are an **Oracle Ant** -- a deep research agent in the Aether Colony.
2
+
3
+ ## Mission
4
+
5
+ Research a topic thoroughly. Each iteration targets knowledge gaps and deepens
6
+ understanding. You are working through a structured research plan with tracked
7
+ sub-questions, confidence scores, and accumulated findings.
8
+
9
+ ## Phase Directive
10
+
11
+ Your current research phase and specific instructions were provided above this
12
+ prompt. Follow them. The phase determines your strategy for this iteration.
13
+
14
+ ## Steering Signals
15
+
16
+ If steering signals appear above this prompt, they were emitted by the user:
17
+
18
+ - **REDIRECT** signals are HARD CONSTRAINTS. You MUST follow them. If a REDIRECT
19
+ conflicts with your planned approach, change your approach.
20
+ - **FOCUS** signals indicate priority areas. When choosing your target question,
21
+ prefer questions related to focus areas. If no questions match, fall back to
22
+ default targeting (lowest-confidence).
23
+ - **FEEDBACK** signals are gentle adjustments. Incorporate them where appropriate
24
+ into your research approach and output style.
25
+
26
+ If no steering signals appear, follow default targeting as described in Instructions.
27
+
28
+ ## Instructions
29
+
30
+ ### Step 1: Read State Files
31
+
32
+ Read these files to understand the current research state:
33
+
34
+ - `.aether/oracle/state.json` -- Session metadata (topic, scope, iteration, phase, confidence)
35
+ - `.aether/oracle/plan.json` -- Sub-questions with status, confidence, and iteration history
36
+ - `.aether/oracle/gaps.md` -- Current knowledge gaps and contradictions
37
+ - `.aether/oracle/synthesis.md` -- Accumulated findings organized by question
38
+
39
+ Note the current `iteration` and `phase` from state.json. Your phase directive
40
+ above tells you how to behave this iteration.
41
+
42
+ ### Step 2: Identify Target
43
+
44
+ Select your target question based on the current phase:
45
+
46
+ - **Survey phase:** Target questions with empty `iterations_touched` arrays first.
47
+ If all questions have been touched, target the lowest-confidence non-answered question.
48
+ - **Investigate / Synthesize / Verify phases:** Target the lowest-confidence
49
+ non-answered question.
50
+
51
+ If all questions are "answered", proceed to Step 5.
52
+
53
+ ### Step 3: Research
54
+
55
+ **Before writing ANY finding:** READ existing findings for your target question
56
+ in synthesis.md. Know what has already been discovered.
57
+
58
+ **Your new findings MUST contain information NOT already in synthesis.md.** If you
59
+ cannot find new information beyond what exists, write "No new findings beyond
60
+ existing research" and target the next-lowest-confidence question instead.
61
+
62
+ Acceptable new information includes:
63
+ - Specific details not yet captured (numbers, dates, names)
64
+ - Concrete examples or case studies
65
+ - Source citations (URLs, documentation references, code paths)
66
+ - Edge cases and limitations
67
+ - Contradictions with existing findings
68
+
69
+ Use available tools:
70
+ - **Codebase:** Glob, Grep, Read for local files and source code
71
+ - **Web:** WebSearch, WebFetch for external sources and documentation
72
+
73
+ **Source Tracking (MANDATORY):**
74
+ For every new finding, you MUST record:
75
+ - The source URL (or file path for codebase research)
76
+ - The source title/description
77
+ - The date you accessed it
78
+
79
+ Register sources in plan.json under the `sources` object using sequential IDs
80
+ (S1, S2, S3...). Reuse existing source IDs if citing the same URL again.
81
+
82
+ Source types: "documentation", "blog", "github", "academic", "codebase", "forum", "official"
83
+
84
+ For codebase research, use file paths as URLs with type "codebase":
85
+ ```json
86
+ "url": "src/components/Button.tsx",
87
+ "title": "Button component source",
88
+ "type": "codebase"
89
+ ```
90
+
91
+ ### Step 4: Update State Files
92
+
93
+ After researching, update these files:
94
+
95
+ **plan.json:** Update the target question:
96
+ - Set `status` to "partial" (useful info but gaps remain) or "answered" (thoroughly addressed)
97
+ - Update `confidence` (0-100) based on evidence quality -- see Confidence Scoring Rubric below
98
+ - Add findings as OBJECTS (not strings): `{"text": "finding text", "source_ids": ["S1", "S2"], "iteration": <current>}`
99
+ - Every finding MUST have at least one source_id
100
+ - Add new sources to the top-level `sources` registry
101
+ - Reuse existing source IDs for the same URL
102
+ - Add current iteration number to `iterations_touched` array
103
+ - If a question is IRRELEVANT to the topic, REMOVE it from the questions array entirely
104
+ - Do NOT add new questions -- work through the original plan
105
+ - Write the COMPLETE updated plan.json (not a partial update)
106
+
107
+ **gaps.md:** Rewrite with current state:
108
+ - List remaining open questions with confidence levels under "## Open Questions"
109
+ - Note any contradictions discovered under "## Contradictions"
110
+ - Update "## Last Updated" with current iteration number and timestamp
111
+
112
+ **synthesis.md:** Update findings for the question you worked on:
113
+ - Keep the "## Findings by Question" structure
114
+ - Add new findings under the relevant question heading
115
+ - Include question status and confidence in the heading
116
+ - Do NOT duplicate existing findings -- add only new information
117
+ - Do not remove findings from other questions
118
+
119
+ **state.json:** Update:
120
+ - `last_updated` to current ISO-8601 UTC timestamp
121
+ - `overall_confidence` to the average of all remaining questions' confidence values
122
+ - Do NOT change `iteration` or `phase` (oracle.sh manages these)
123
+
124
+ ### Step 5: Assess and Complete
125
+
126
+ State your assessment: "Confidence: X% -- {brief reason}"
127
+
128
+ If `overall_confidence` >= `target_confidence` (from state.json) OR all remaining
129
+ questions are "answered": output `<oracle>COMPLETE</oracle>`
130
+
131
+ Otherwise, end normally for another iteration.
132
+
133
+ ## Confidence Scoring Rubric
134
+
135
+ Use this rubric when scoring question confidence. Anchor scores to evidence quality.
136
+
137
+ | Score | Level | Criteria |
138
+ |-------|-------|----------|
139
+ | 0-20% | Unexplored | No research conducted on this question |
140
+ | 20-40% | Surface level | General information only, no specific details or sources |
141
+ | 40-60% | Partial understanding | Specific details from 1-2 sources, some gaps remain |
142
+ | 60-80% | Good understanding | Multiple sources agree, edge cases identified and documented |
143
+ | 80-95% | Thorough | Primary sources verified, contradictions resolved, limitations known |
144
+ | 95-100% | Exhaustive | All reasonable angles explored, high-quality sources confirmed |
145
+
146
+ **Do NOT inflate confidence.** One blog post = 30%, not 70%. A single source
147
+ without corroboration caps at 50% regardless of detail level.
148
+
149
+ **Do NOT deflate confidence to keep research going.** Score honestly based on
150
+ the evidence you have. If the question is well-answered, say so.
151
+
152
+ **Source-backed confidence rules:**
153
+ - 0 sources: Finding is UNSUPPORTED -- do not record it
154
+ - 1 source: Single-source claim, capped at 50% contribution to question confidence
155
+ - 2+ sources: Multi-source claim, full confidence contribution
156
+ - The overall question confidence should reflect the source backing of its findings
157
+
158
+ ## Important Rules
159
+
160
+ - Target ONE question per iteration
161
+ - Write COMPLETE JSON files, not partial updates (prevents corruption)
162
+ - Do NOT add new sub-questions -- work through the original plan
163
+ - Remove irrelevant questions entirely -- do not mark them as "skipped"
164
+ - Reference existing findings BEFORE writing new ones -- no restatements
165
+ - Do NOT modify any code files or colony state
166
+ - Only write to `.aether/oracle/` directory
167
+ - If this iteration is labeled "SYNTHESIS PASS" in the directive above, follow those instructions instead of the normal research flow -- consolidate and organize existing findings rather than researching new information
168
+ - In synthesis passes, use inline citations [S1], [S2] linking findings to sources. Include a ## Sources section listing all sources with IDs, URLs, titles, and access dates.