aether-colony 5.3.2 → 5.4.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 (281) hide show
  1. package/.aether/aether-utils.sh +181 -5
  2. package/.aether/commands/archaeology.yaml +3 -3
  3. package/.aether/commands/build.yaml +80 -45
  4. package/.aether/commands/chaos.yaml +7 -7
  5. package/.aether/commands/colonize.yaml +17 -17
  6. package/.aether/commands/continue.yaml +40 -40
  7. package/.aether/commands/council.yaml +6 -6
  8. package/.aether/commands/data-clean.yaml +3 -3
  9. package/.aether/commands/dream.yaml +2 -2
  10. package/.aether/commands/entomb.yaml +12 -12
  11. package/.aether/commands/export-signals.yaml +2 -2
  12. package/.aether/commands/feedback.yaml +6 -6
  13. package/.aether/commands/flag.yaml +2 -2
  14. package/.aether/commands/flags.yaml +4 -4
  15. package/.aether/commands/focus.yaml +6 -6
  16. package/.aether/commands/help.yaml +1 -1
  17. package/.aether/commands/history.yaml +1 -1
  18. package/.aether/commands/import-signals.yaml +2 -2
  19. package/.aether/commands/init.yaml +44 -27
  20. package/.aether/commands/insert-phase.yaml +1 -1
  21. package/.aether/commands/interpret.yaml +2 -2
  22. package/.aether/commands/lay-eggs.yaml +3 -3
  23. package/.aether/commands/maturity.yaml +2 -2
  24. package/.aether/commands/memory-details.yaml +1 -1
  25. package/.aether/commands/migrate-state.yaml +1 -1
  26. package/.aether/commands/oracle.yaml +147 -82
  27. package/.aether/commands/organize.yaml +5 -5
  28. package/.aether/commands/patrol.yaml +8 -8
  29. package/.aether/commands/pause-colony.yaml +7 -7
  30. package/.aether/commands/phase.yaml +1 -1
  31. package/.aether/commands/pheromones.yaml +1 -1
  32. package/.aether/commands/plan.yaml +14 -14
  33. package/.aether/commands/quick.yaml +4 -4
  34. package/.aether/commands/redirect.yaml +6 -6
  35. package/.aether/commands/resume-colony.yaml +9 -9
  36. package/.aether/commands/resume.yaml +5 -38
  37. package/.aether/commands/run.yaml +10 -10
  38. package/.aether/commands/seal.yaml +33 -33
  39. package/.aether/commands/skill-create.yaml +4 -4
  40. package/.aether/commands/status.yaml +14 -14
  41. package/.aether/commands/swarm.yaml +14 -14
  42. package/.aether/commands/tunnels.yaml +7 -7
  43. package/.aether/commands/update.yaml +1 -1
  44. package/.aether/commands/verify-castes.yaml +3 -3
  45. package/.aether/commands/watch.yaml +15 -15
  46. package/.aether/docs/command-playbooks/build-complete.md +48 -15
  47. package/.aether/docs/command-playbooks/build-context.md +11 -11
  48. package/.aether/docs/command-playbooks/build-full.md +76 -76
  49. package/.aether/docs/command-playbooks/build-prep.md +10 -10
  50. package/.aether/docs/command-playbooks/build-verify.md +27 -27
  51. package/.aether/docs/command-playbooks/build-wave.md +38 -38
  52. package/.aether/docs/command-playbooks/continue-advance.md +60 -27
  53. package/.aether/docs/command-playbooks/continue-finalize.md +25 -11
  54. package/.aether/docs/command-playbooks/continue-full.md +60 -46
  55. package/.aether/docs/command-playbooks/continue-gates.md +18 -18
  56. package/.aether/docs/command-playbooks/continue-verify.md +10 -10
  57. package/.aether/docs/source-of-truth-map.md +10 -10
  58. package/.aether/docs/structural-learning-stack.md +283 -0
  59. package/.aether/templates/colony-state-template.json +1 -0
  60. package/.aether/utils/consolidation-seal.sh +196 -0
  61. package/.aether/utils/consolidation.sh +127 -0
  62. package/.aether/utils/curation-ants/archivist.sh +97 -0
  63. package/.aether/utils/curation-ants/critic.sh +214 -0
  64. package/.aether/utils/curation-ants/herald.sh +102 -0
  65. package/.aether/utils/curation-ants/janitor.sh +121 -0
  66. package/.aether/utils/curation-ants/librarian.sh +99 -0
  67. package/.aether/utils/curation-ants/nurse.sh +153 -0
  68. package/.aether/utils/curation-ants/orchestrator.sh +181 -0
  69. package/.aether/utils/curation-ants/scribe.sh +164 -0
  70. package/.aether/utils/curation-ants/sentinel.sh +119 -0
  71. package/.aether/utils/event-bus.sh +301 -0
  72. package/.aether/utils/graph.sh +559 -0
  73. package/.aether/utils/instinct-store.sh +401 -0
  74. package/.aether/utils/learning.sh +79 -7
  75. package/.aether/utils/oracle/oracle-stop-hook.sh +896 -0
  76. package/.aether/utils/session.sh +13 -0
  77. package/.aether/utils/state-api.sh +1 -1
  78. package/.aether/utils/trust-scoring.sh +347 -0
  79. package/.aether/utils/worktree.sh +97 -0
  80. package/.claude/commands/ant/archaeology.md +2 -2
  81. package/.claude/commands/ant/chaos.md +4 -4
  82. package/.claude/commands/ant/colonize.md +9 -9
  83. package/.claude/commands/ant/council.md +6 -6
  84. package/.claude/commands/ant/data-clean.md +3 -3
  85. package/.claude/commands/ant/dream.md +2 -2
  86. package/.claude/commands/ant/entomb.md +9 -9
  87. package/.claude/commands/ant/export-signals.md +2 -2
  88. package/.claude/commands/ant/feedback.md +4 -4
  89. package/.claude/commands/ant/flag.md +2 -2
  90. package/.claude/commands/ant/flags.md +4 -4
  91. package/.claude/commands/ant/focus.md +4 -4
  92. package/.claude/commands/ant/help.md +1 -1
  93. package/.claude/commands/ant/history.md +1 -1
  94. package/.claude/commands/ant/import-signals.md +2 -2
  95. package/.claude/commands/ant/init.md +44 -27
  96. package/.claude/commands/ant/insert-phase.md +1 -1
  97. package/.claude/commands/ant/interpret.md +2 -2
  98. package/.claude/commands/ant/lay-eggs.md +2 -2
  99. package/.claude/commands/ant/maturity.md +2 -2
  100. package/.claude/commands/ant/memory-details.md +1 -1
  101. package/.claude/commands/ant/migrate-state.md +1 -1
  102. package/.claude/commands/ant/oracle.md +78 -42
  103. package/.claude/commands/ant/organize.md +3 -3
  104. package/.claude/commands/ant/patrol.md +8 -8
  105. package/.claude/commands/ant/pause-colony.md +5 -5
  106. package/.claude/commands/ant/phase.md +1 -1
  107. package/.claude/commands/ant/pheromones.md +1 -1
  108. package/.claude/commands/ant/plan.md +8 -8
  109. package/.claude/commands/ant/quick.md +4 -4
  110. package/.claude/commands/ant/redirect.md +4 -4
  111. package/.claude/commands/ant/resume-colony.md +5 -5
  112. package/.claude/commands/ant/resume.md +17 -29
  113. package/.claude/commands/ant/run.md +10 -10
  114. package/.claude/commands/ant/seal.md +25 -25
  115. package/.claude/commands/ant/skill-create.md +2 -2
  116. package/.claude/commands/ant/status.md +14 -14
  117. package/.claude/commands/ant/swarm.md +14 -14
  118. package/.claude/commands/ant/tunnels.md +4 -4
  119. package/.claude/commands/ant/update.md +1 -1
  120. package/.claude/commands/ant/verify-castes.md +2 -2
  121. package/.claude/commands/ant/watch.md +8 -8
  122. package/.opencode/commands/ant/archaeology.md +1 -1
  123. package/.opencode/commands/ant/build.md +80 -45
  124. package/.opencode/commands/ant/chaos.md +3 -3
  125. package/.opencode/commands/ant/colonize.md +8 -8
  126. package/.opencode/commands/ant/continue.md +40 -40
  127. package/.opencode/commands/ant/council.md +5 -5
  128. package/.opencode/commands/ant/data-clean.md +2 -2
  129. package/.opencode/commands/ant/dream.md +1 -1
  130. package/.opencode/commands/ant/entomb.md +3 -3
  131. package/.opencode/commands/ant/export-signals.md +1 -1
  132. package/.opencode/commands/ant/feedback.md +2 -2
  133. package/.opencode/commands/ant/flag.md +1 -1
  134. package/.opencode/commands/ant/flags.md +3 -3
  135. package/.opencode/commands/ant/focus.md +2 -2
  136. package/.opencode/commands/ant/import-signals.md +1 -1
  137. package/.opencode/commands/ant/init.md +44 -27
  138. package/.opencode/commands/ant/insert-phase.md +1 -1
  139. package/.opencode/commands/ant/interpret.md +1 -1
  140. package/.opencode/commands/ant/lay-eggs.md +2 -2
  141. package/.opencode/commands/ant/maturity.md +1 -1
  142. package/.opencode/commands/ant/memory-details.md +1 -1
  143. package/.opencode/commands/ant/oracle.md +69 -40
  144. package/.opencode/commands/ant/organize.md +2 -2
  145. package/.opencode/commands/ant/patrol.md +8 -8
  146. package/.opencode/commands/ant/pause-colony.md +2 -2
  147. package/.opencode/commands/ant/pheromones.md +1 -1
  148. package/.opencode/commands/ant/plan.md +6 -6
  149. package/.opencode/commands/ant/quick.md +4 -4
  150. package/.opencode/commands/ant/redirect.md +2 -2
  151. package/.opencode/commands/ant/resume-colony.md +4 -4
  152. package/.opencode/commands/ant/resume.md +5 -17
  153. package/.opencode/commands/ant/run.md +10 -10
  154. package/.opencode/commands/ant/seal.md +8 -8
  155. package/.opencode/commands/ant/skill-create.md +2 -2
  156. package/.opencode/commands/ant/status.md +10 -10
  157. package/.opencode/commands/ant/tunnels.md +3 -3
  158. package/.opencode/commands/ant/verify-castes.md +1 -1
  159. package/.opencode/commands/ant/watch.md +7 -7
  160. package/CHANGELOG.md +83 -0
  161. package/README.md +22 -9
  162. package/bin/cli.js +118 -3
  163. package/bin/lib/binary-downloader.js +267 -0
  164. package/bin/lib/update-transaction.js +27 -3
  165. package/bin/lib/version-gate.js +179 -0
  166. package/bin/npx-entry.js +0 -0
  167. package/package.json +1 -1
  168. package/.aether/agents/aether-ambassador.md +0 -140
  169. package/.aether/agents/aether-archaeologist.md +0 -108
  170. package/.aether/agents/aether-architect.md +0 -133
  171. package/.aether/agents/aether-auditor.md +0 -144
  172. package/.aether/agents/aether-builder.md +0 -184
  173. package/.aether/agents/aether-chaos.md +0 -115
  174. package/.aether/agents/aether-chronicler.md +0 -122
  175. package/.aether/agents/aether-gatekeeper.md +0 -116
  176. package/.aether/agents/aether-includer.md +0 -117
  177. package/.aether/agents/aether-keeper.md +0 -177
  178. package/.aether/agents/aether-measurer.md +0 -128
  179. package/.aether/agents/aether-oracle.md +0 -137
  180. package/.aether/agents/aether-probe.md +0 -133
  181. package/.aether/agents/aether-queen.md +0 -286
  182. package/.aether/agents/aether-route-setter.md +0 -130
  183. package/.aether/agents/aether-sage.md +0 -106
  184. package/.aether/agents/aether-scout.md +0 -101
  185. package/.aether/agents/aether-surveyor-disciplines.md +0 -391
  186. package/.aether/agents/aether-surveyor-nest.md +0 -329
  187. package/.aether/agents/aether-surveyor-pathogens.md +0 -264
  188. package/.aether/agents/aether-surveyor-provisions.md +0 -334
  189. package/.aether/agents/aether-tracker.md +0 -137
  190. package/.aether/agents/aether-watcher.md +0 -174
  191. package/.aether/agents/aether-weaver.md +0 -130
  192. package/.aether/commands/claude/archaeology.md +0 -334
  193. package/.aether/commands/claude/build.md +0 -65
  194. package/.aether/commands/claude/chaos.md +0 -336
  195. package/.aether/commands/claude/colonize.md +0 -259
  196. package/.aether/commands/claude/continue.md +0 -60
  197. package/.aether/commands/claude/council.md +0 -507
  198. package/.aether/commands/claude/data-clean.md +0 -81
  199. package/.aether/commands/claude/dream.md +0 -268
  200. package/.aether/commands/claude/entomb.md +0 -498
  201. package/.aether/commands/claude/export-signals.md +0 -57
  202. package/.aether/commands/claude/feedback.md +0 -96
  203. package/.aether/commands/claude/flag.md +0 -151
  204. package/.aether/commands/claude/flags.md +0 -169
  205. package/.aether/commands/claude/focus.md +0 -76
  206. package/.aether/commands/claude/help.md +0 -154
  207. package/.aether/commands/claude/history.md +0 -140
  208. package/.aether/commands/claude/import-signals.md +0 -71
  209. package/.aether/commands/claude/init.md +0 -505
  210. package/.aether/commands/claude/insert-phase.md +0 -105
  211. package/.aether/commands/claude/interpret.md +0 -278
  212. package/.aether/commands/claude/lay-eggs.md +0 -210
  213. package/.aether/commands/claude/maturity.md +0 -113
  214. package/.aether/commands/claude/memory-details.md +0 -77
  215. package/.aether/commands/claude/migrate-state.md +0 -171
  216. package/.aether/commands/claude/oracle.md +0 -642
  217. package/.aether/commands/claude/organize.md +0 -232
  218. package/.aether/commands/claude/patrol.md +0 -620
  219. package/.aether/commands/claude/pause-colony.md +0 -233
  220. package/.aether/commands/claude/phase.md +0 -115
  221. package/.aether/commands/claude/pheromones.md +0 -156
  222. package/.aether/commands/claude/plan.md +0 -693
  223. package/.aether/commands/claude/preferences.md +0 -65
  224. package/.aether/commands/claude/quick.md +0 -100
  225. package/.aether/commands/claude/redirect.md +0 -76
  226. package/.aether/commands/claude/resume-colony.md +0 -197
  227. package/.aether/commands/claude/resume.md +0 -388
  228. package/.aether/commands/claude/run.md +0 -231
  229. package/.aether/commands/claude/seal.md +0 -774
  230. package/.aether/commands/claude/skill-create.md +0 -286
  231. package/.aether/commands/claude/status.md +0 -410
  232. package/.aether/commands/claude/swarm.md +0 -349
  233. package/.aether/commands/claude/tunnels.md +0 -426
  234. package/.aether/commands/claude/update.md +0 -132
  235. package/.aether/commands/claude/verify-castes.md +0 -143
  236. package/.aether/commands/claude/watch.md +0 -239
  237. package/.aether/commands/opencode/archaeology.md +0 -331
  238. package/.aether/commands/opencode/build.md +0 -1168
  239. package/.aether/commands/opencode/chaos.md +0 -329
  240. package/.aether/commands/opencode/colonize.md +0 -195
  241. package/.aether/commands/opencode/continue.md +0 -1436
  242. package/.aether/commands/opencode/council.md +0 -437
  243. package/.aether/commands/opencode/data-clean.md +0 -77
  244. package/.aether/commands/opencode/dream.md +0 -260
  245. package/.aether/commands/opencode/entomb.md +0 -377
  246. package/.aether/commands/opencode/export-signals.md +0 -54
  247. package/.aether/commands/opencode/feedback.md +0 -99
  248. package/.aether/commands/opencode/flag.md +0 -149
  249. package/.aether/commands/opencode/flags.md +0 -167
  250. package/.aether/commands/opencode/focus.md +0 -73
  251. package/.aether/commands/opencode/help.md +0 -157
  252. package/.aether/commands/opencode/history.md +0 -136
  253. package/.aether/commands/opencode/import-signals.md +0 -68
  254. package/.aether/commands/opencode/init.md +0 -518
  255. package/.aether/commands/opencode/insert-phase.md +0 -111
  256. package/.aether/commands/opencode/interpret.md +0 -272
  257. package/.aether/commands/opencode/lay-eggs.md +0 -213
  258. package/.aether/commands/opencode/maturity.md +0 -108
  259. package/.aether/commands/opencode/memory-details.md +0 -83
  260. package/.aether/commands/opencode/migrate-state.md +0 -165
  261. package/.aether/commands/opencode/oracle.md +0 -593
  262. package/.aether/commands/opencode/organize.md +0 -226
  263. package/.aether/commands/opencode/patrol.md +0 -626
  264. package/.aether/commands/opencode/pause-colony.md +0 -203
  265. package/.aether/commands/opencode/phase.md +0 -113
  266. package/.aether/commands/opencode/pheromones.md +0 -162
  267. package/.aether/commands/opencode/plan.md +0 -684
  268. package/.aether/commands/opencode/preferences.md +0 -71
  269. package/.aether/commands/opencode/quick.md +0 -91
  270. package/.aether/commands/opencode/redirect.md +0 -84
  271. package/.aether/commands/opencode/resume-colony.md +0 -190
  272. package/.aether/commands/opencode/resume.md +0 -394
  273. package/.aether/commands/opencode/run.md +0 -237
  274. package/.aether/commands/opencode/seal.md +0 -452
  275. package/.aether/commands/opencode/skill-create.md +0 -63
  276. package/.aether/commands/opencode/status.md +0 -307
  277. package/.aether/commands/opencode/swarm.md +0 -15
  278. package/.aether/commands/opencode/tunnels.md +0 -400
  279. package/.aether/commands/opencode/update.md +0 -127
  280. package/.aether/commands/opencode/verify-castes.md +0 -139
  281. package/.aether/commands/opencode/watch.md +0 -227
@@ -275,6 +275,13 @@ _session_init() {
275
275
  summary: "Session initialized"
276
276
  }' > "$session_file.tmp"
277
277
  mv "$session_file.tmp" "$session_file"
278
+
279
+ # Mirror to legacy path so session recovery (which checks .aether/data/session.json) works
280
+ local legacy_session="$DATA_DIR/session.json"
281
+ if [[ "$session_file" != "$legacy_session" ]]; then
282
+ cp "$session_file" "$legacy_session" 2>/dev/null || true
283
+ fi
284
+
278
285
  json_ok "$(jq -n --arg sid "$session_id" --arg goal "$goal" --arg file "$session_file" \
279
286
  '{session_id: $sid, goal: $goal, file: $file}')"
280
287
  }
@@ -361,6 +368,12 @@ _session_update() {
361
368
  json_err "$E_UNKNOWN" "Failed to rename temporary session file"
362
369
  }
363
370
 
371
+ # Mirror to legacy path so session recovery (which checks .aether/data/session.json) works
372
+ local legacy_session="$DATA_DIR/session.json"
373
+ if [[ "$session_file" != "$legacy_session" ]]; then
374
+ cp "$session_file" "$legacy_session" 2>/dev/null || true
375
+ fi
376
+
364
377
  json_ok "$(jq -n --arg cmd "$cmd_run" '{updated: true, command: $cmd}')"
365
378
  }
366
379
 
@@ -229,7 +229,7 @@ _state_migrate() {
229
229
  # Gracefully degrades: missing files produce zero/default values
230
230
  # ============================================================================
231
231
  _colony_vital_signs() {
232
- local cvs_state_file="$COLONY_DATA_DIR/COLONY_STATE.json"
232
+ local cvs_state_file="$DATA_DIR/COLONY_STATE.json"
233
233
  local cvs_midden_file="$COLONY_DATA_DIR/midden/midden.json"
234
234
  local cvs_phero_file="$COLONY_DATA_DIR/pheromones.json"
235
235
  local cvs_session_file="$COLONY_DATA_DIR/session.json"
@@ -0,0 +1,347 @@
1
+ #!/bin/bash
2
+ # Trust Scoring utility functions — Aether Structural Learning Stack
3
+ # Provides: _trust_calculate, _trust_decay, _trust_tier
4
+ #
5
+ # These functions are sourced by aether-utils.sh at startup.
6
+ # All shared infrastructure (json_ok, json_err, json_warn, atomic_write,
7
+ # DATA_DIR, COLONY_DATA_DIR, SCRIPT_DIR, error constants) is available.
8
+ #
9
+ # This is a pure calculation module — no state is read or written.
10
+ # All functions accept --flag <value> arguments and return JSON via json_ok.
11
+
12
+ # ============================================================================
13
+ # _trust_calculate
14
+ # Calculate a weighted trust score from source, evidence, and activity inputs.
15
+ #
16
+ # Weights: source 40%, evidence 35%, activity 25%
17
+ # Activity uses a 60-day half-life decay from days_since_last_use.
18
+ # Floor: score is never below 0.2.
19
+ #
20
+ # Usage: trust-calculate --source <type> --evidence <type> --days-since <N>
21
+ #
22
+ # Source types and weights:
23
+ # user_feedback 1.0
24
+ # error_resolution 0.9
25
+ # success_pattern 0.8
26
+ # observation 0.6
27
+ # heuristic 0.4
28
+ #
29
+ # Evidence types and weights:
30
+ # test_verified 1.0
31
+ # multi_phase 0.9
32
+ # single_phase 0.7
33
+ # anecdotal 0.4
34
+ #
35
+ # Output: {score, source_score, evidence_score, activity_score, tier}
36
+ # ============================================================================
37
+ _trust_calculate() {
38
+ local source_type=""
39
+ local evidence_type=""
40
+ local days_since=""
41
+
42
+ # Parse --flag value arguments
43
+ while [[ $# -gt 0 ]]; do
44
+ case "$1" in
45
+ --source)
46
+ source_type="${2:-}"
47
+ shift 2
48
+ ;;
49
+ --evidence)
50
+ evidence_type="${2:-}"
51
+ shift 2
52
+ ;;
53
+ --days-since)
54
+ days_since="${2:-}"
55
+ shift 2
56
+ ;;
57
+ *)
58
+ json_err "$E_VALIDATION_FAILED" "Usage: trust-calculate --source <type> --evidence <type> --days-since <N>"
59
+ return
60
+ ;;
61
+ esac
62
+ done
63
+
64
+ [[ -z "$source_type" || -z "$evidence_type" || -z "$days_since" ]] && \
65
+ json_err "$E_VALIDATION_FAILED" "Usage: trust-calculate --source <type> --evidence <type> --days-since <N>"
66
+
67
+ # Map source type to score
68
+ local source_score
69
+ case "$source_type" in
70
+ user_feedback) source_score="1.0" ;;
71
+ error_resolution) source_score="0.9" ;;
72
+ success_pattern) source_score="0.8" ;;
73
+ observation) source_score="0.6" ;;
74
+ heuristic) source_score="0.4" ;;
75
+ *)
76
+ json_err "$E_VALIDATION_FAILED" "Unknown source type: $source_type. Valid: user_feedback, error_resolution, success_pattern, observation, heuristic"
77
+ return
78
+ ;;
79
+ esac
80
+
81
+ # Map evidence type to score
82
+ local evidence_score
83
+ case "$evidence_type" in
84
+ test_verified) evidence_score="1.0" ;;
85
+ multi_phase) evidence_score="0.9" ;;
86
+ single_phase) evidence_score="0.7" ;;
87
+ anecdotal) evidence_score="0.4" ;;
88
+ *)
89
+ json_err "$E_VALIDATION_FAILED" "Unknown evidence type: $evidence_type. Valid: test_verified, multi_phase, single_phase, anecdotal"
90
+ return
91
+ ;;
92
+ esac
93
+
94
+ # Validate days_since is a non-negative integer
95
+ if ! [[ "$days_since" =~ ^[0-9]+$ ]]; then
96
+ json_err "$E_VALIDATION_FAILED" "--days-since must be a non-negative integer, got: $days_since"
97
+ return
98
+ fi
99
+
100
+ # Calculate activity score using 60-day half-life decay
101
+ # activity = 0.5 ^ (days / 60)
102
+ local activity_score
103
+ activity_score=$(_trust_halflife_decay "1.0" "$days_since" "60")
104
+
105
+ # Weighted formula: 0.4 * source + 0.35 * evidence + 0.25 * activity
106
+ local raw_score
107
+ if command -v bc &>/dev/null; then
108
+ raw_score=$(echo "scale=6; 0.4 * $source_score + 0.35 * $evidence_score + 0.25 * $activity_score" | bc)
109
+ else
110
+ raw_score=$(awk "BEGIN{printf \"%.6f\", 0.4 * $source_score + 0.35 * $evidence_score + 0.25 * $activity_score}")
111
+ fi
112
+
113
+ # Apply floor of 0.2
114
+ local score
115
+ score=$(_trust_apply_floor "$raw_score" "0.2")
116
+
117
+ # Derive tier from final score
118
+ local tier
119
+ tier=$(_trust_score_to_tier "$score")
120
+
121
+ json_ok "$(jq -n \
122
+ --argjson score "$score" \
123
+ --argjson source_score "$source_score" \
124
+ --argjson evidence_score "$evidence_score" \
125
+ --argjson activity_score "$activity_score" \
126
+ --arg tier "$tier" \
127
+ '{
128
+ score: $score,
129
+ source_score: $source_score,
130
+ evidence_score: $evidence_score,
131
+ activity_score: $activity_score,
132
+ tier: $tier
133
+ }')"
134
+ }
135
+
136
+ # ============================================================================
137
+ # _trust_decay
138
+ # Apply time-based half-life decay to an existing trust score.
139
+ # The score never drops below the floor of 0.2.
140
+ #
141
+ # Formula: decayed = max(0.2, score * (0.5 ^ (days / 60)))
142
+ #
143
+ # Usage: trust-decay --score <float> --days <N>
144
+ # Output: {original, decayed, days, half_life: 60}
145
+ # ============================================================================
146
+ _trust_decay() {
147
+ local score=""
148
+ local days=""
149
+
150
+ while [[ $# -gt 0 ]]; do
151
+ case "$1" in
152
+ --score)
153
+ score="${2:-}"
154
+ shift 2
155
+ ;;
156
+ --days)
157
+ days="${2:-}"
158
+ shift 2
159
+ ;;
160
+ *)
161
+ json_err "$E_VALIDATION_FAILED" "Usage: trust-decay --score <float> --days <N>"
162
+ return
163
+ ;;
164
+ esac
165
+ done
166
+
167
+ [[ -z "$score" || -z "$days" ]] && \
168
+ json_err "$E_VALIDATION_FAILED" "Usage: trust-decay --score <float> --days <N>"
169
+
170
+ # Validate score is a positive number
171
+ if ! [[ "$score" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
172
+ json_err "$E_VALIDATION_FAILED" "--score must be a non-negative number, got: $score"
173
+ return
174
+ fi
175
+
176
+ # Validate days is a non-negative integer
177
+ if ! [[ "$days" =~ ^[0-9]+$ ]]; then
178
+ json_err "$E_VALIDATION_FAILED" "--days must be a non-negative integer, got: $days"
179
+ return
180
+ fi
181
+
182
+ local decayed
183
+ decayed=$(_trust_halflife_decay "$score" "$days" "60")
184
+ local final
185
+ final=$(_trust_apply_floor "$decayed" "0.2")
186
+
187
+ json_ok "$(jq -n \
188
+ --argjson original "$score" \
189
+ --argjson decayed "$final" \
190
+ --argjson days "$days" \
191
+ --argjson half_life 60 \
192
+ '{
193
+ original: $original,
194
+ decayed: $decayed,
195
+ days: $days,
196
+ half_life: $half_life
197
+ }')"
198
+ }
199
+
200
+ # ============================================================================
201
+ # _trust_tier
202
+ # Map a trust score to a named tier.
203
+ #
204
+ # Tier table:
205
+ # 0.90–1.00 canonical (index 0) — proven across multiple contexts
206
+ # 0.80–0.89 trusted (index 1) — reliable with strong evidence
207
+ # 0.70–0.79 established (index 2) — consistent but limited evidence
208
+ # 0.60–0.69 emerging (index 3) — promising, needs more validation
209
+ # 0.45–0.59 provisional (index 4) — early stage, minimal evidence
210
+ # 0.30–0.44 suspect (index 5) — weak evidence or conflicting signals
211
+ # 0.20–0.29 dormant (index 6) — inactive, near floor
212
+ #
213
+ # Usage: trust-tier --score <float>
214
+ # Output: {score, tier, tier_index}
215
+ # ============================================================================
216
+ _trust_tier() {
217
+ local score=""
218
+
219
+ while [[ $# -gt 0 ]]; do
220
+ case "$1" in
221
+ --score)
222
+ score="${2:-}"
223
+ shift 2
224
+ ;;
225
+ *)
226
+ json_err "$E_VALIDATION_FAILED" "Usage: trust-tier --score <float>"
227
+ return
228
+ ;;
229
+ esac
230
+ done
231
+
232
+ [[ -z "$score" ]] && \
233
+ json_err "$E_VALIDATION_FAILED" "Usage: trust-tier --score <float>"
234
+
235
+ # Validate score is a non-negative number
236
+ if ! [[ "$score" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
237
+ json_err "$E_VALIDATION_FAILED" "--score must be a non-negative number, got: $score"
238
+ return
239
+ fi
240
+
241
+ local tier
242
+ local tier_index
243
+ tier=$(_trust_score_to_tier "$score")
244
+ tier_index=$(_trust_tier_to_index "$tier")
245
+
246
+ json_ok "$(jq -n \
247
+ --argjson score "$score" \
248
+ --arg tier "$tier" \
249
+ --argjson tier_index "$tier_index" \
250
+ '{
251
+ score: $score,
252
+ tier: $tier,
253
+ tier_index: $tier_index
254
+ }')"
255
+ }
256
+
257
+ # ============================================================================
258
+ # Internal helpers — not exposed as subcommands
259
+ # ============================================================================
260
+
261
+ # _trust_halflife_decay: compute score * (0.5 ^ (days / half_life))
262
+ # Usage: _trust_halflife_decay <score> <days> <half_life>
263
+ # Outputs the decayed value as a float string
264
+ _trust_halflife_decay() {
265
+ local score="$1"
266
+ local days="$2"
267
+ local half_life="$3"
268
+
269
+ if command -v bc &>/dev/null; then
270
+ echo "scale=6; $score * e(l(0.5) * ($days / $half_life))" | bc -l
271
+ else
272
+ awk "BEGIN{printf \"%.6f\", $score * (0.5 ^ ($days / $half_life))}"
273
+ fi
274
+ }
275
+
276
+ # _trust_apply_floor: return max(floor, value)
277
+ # Usage: _trust_apply_floor <value> <floor>
278
+ # Outputs the floored value as a float string
279
+ _trust_apply_floor() {
280
+ local value="$1"
281
+ local floor="$2"
282
+
283
+ if command -v bc &>/dev/null; then
284
+ local cmp
285
+ cmp=$(echo "$value < $floor" | bc -l)
286
+ if [[ "$cmp" == "1" ]]; then
287
+ echo "$floor"
288
+ else
289
+ echo "$value"
290
+ fi
291
+ else
292
+ awk "BEGIN{v=$value; f=$floor; printf \"%.6f\", (v < f ? f : v)}"
293
+ fi
294
+ }
295
+
296
+ # _trust_score_to_tier: map a numeric score to a tier name
297
+ # Usage: _trust_score_to_tier <score>
298
+ # Outputs the tier name string
299
+ _trust_score_to_tier() {
300
+ local score="$1"
301
+
302
+ if command -v bc &>/dev/null; then
303
+ if [[ $(echo "$score >= 0.90" | bc -l) == "1" ]]; then
304
+ echo "canonical"
305
+ elif [[ $(echo "$score >= 0.80" | bc -l) == "1" ]]; then
306
+ echo "trusted"
307
+ elif [[ $(echo "$score >= 0.70" | bc -l) == "1" ]]; then
308
+ echo "established"
309
+ elif [[ $(echo "$score >= 0.60" | bc -l) == "1" ]]; then
310
+ echo "emerging"
311
+ elif [[ $(echo "$score >= 0.45" | bc -l) == "1" ]]; then
312
+ echo "provisional"
313
+ elif [[ $(echo "$score >= 0.30" | bc -l) == "1" ]]; then
314
+ echo "suspect"
315
+ else
316
+ echo "dormant"
317
+ fi
318
+ else
319
+ awk "BEGIN{
320
+ s = $score
321
+ if (s >= 0.90) print \"canonical\"
322
+ else if (s >= 0.80) print \"trusted\"
323
+ else if (s >= 0.70) print \"established\"
324
+ else if (s >= 0.60) print \"emerging\"
325
+ else if (s >= 0.45) print \"provisional\"
326
+ else if (s >= 0.30) print \"suspect\"
327
+ else print \"dormant\"
328
+ }"
329
+ fi
330
+ }
331
+
332
+ # _trust_tier_to_index: map tier name to integer index
333
+ # Usage: _trust_tier_to_index <tier_name>
334
+ # Outputs the index as an integer string
335
+ _trust_tier_to_index() {
336
+ local tier="$1"
337
+ case "$tier" in
338
+ canonical) echo "0" ;;
339
+ trusted) echo "1" ;;
340
+ established) echo "2" ;;
341
+ emerging) echo "3" ;;
342
+ provisional) echo "4" ;;
343
+ suspect) echo "5" ;;
344
+ dormant) echo "6" ;;
345
+ *) echo "-1" ;;
346
+ esac
347
+ }
@@ -187,3 +187,100 @@ _worktree_cleanup() {
187
187
 
188
188
  json_ok "$result"
189
189
  }
190
+
191
+ # _worktree_merge
192
+ # Merges a worktree branch back to the target branch with safety checks.
193
+ #
194
+ # Usage: _worktree_merge --branch <branch-name> [--target <target-branch>] [--force]
195
+ # Returns JSON: {ok:true, result:{merged, branch, target, sha, commits_merged}}
196
+ _worktree_merge() {
197
+ local branch=""
198
+ local target=""
199
+ local force=false
200
+
201
+ while [[ $# -gt 0 ]]; do
202
+ case "$1" in
203
+ --branch) branch="${2:-}"; shift 2 ;;
204
+ --target) target="${2:-}"; shift 2 ;;
205
+ --force) force=true; shift ;;
206
+ *) shift ;;
207
+ esac
208
+ done
209
+
210
+ if [[ -z "$branch" ]]; then
211
+ json_err "$E_VALIDATION_FAILED" "Usage: worktree-merge --branch <branch-name> [--target <target-branch>]"
212
+ fi
213
+
214
+ # Sanitize branch name
215
+ if [[ "$branch" == *..* ]] || [[ "$branch" == */* ]] || [[ "$branch" == *\\* ]]; then
216
+ json_err "$E_VALIDATION_FAILED" "Branch name must not contain '..', '/', or backslashes"
217
+ fi
218
+
219
+ local worktree_dir="$WORKTREE_BASE_DIR/$branch"
220
+
221
+ # Default target to current branch
222
+ if [[ -z "$target" ]]; then
223
+ target=$(git -C "$AETHER_ROOT" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "main")
224
+ fi
225
+
226
+ # Safety check 1: worktree must exist
227
+ if [[ ! -d "$worktree_dir" ]]; then
228
+ json_err "$E_RESOURCE_NOT_FOUND" "No worktree found for branch '$branch'"
229
+ fi
230
+
231
+ # Safety check 2: worktree must have committed changes (unless --force)
232
+ if [[ "$force" == "false" ]]; then
233
+ local dirty_count
234
+ dirty_count=$(git -C "$worktree_dir" status --porcelain 2>/dev/null \
235
+ | grep -v '\.aether/' \
236
+ | wc -l | tr -d ' ') || dirty_count=0
237
+ if [[ "$dirty_count" -gt 0 ]]; then
238
+ json_err "$E_VALIDATION_FAILED" "Worktree '$branch' has $dirty_count uncommitted changes. Commit or stash before merging."
239
+ fi
240
+ fi
241
+
242
+ # Safety check 3: worktree must have commits ahead of target
243
+ local ahead_count
244
+ ahead_count=$(git -C "$AETHER_ROOT" rev-list --count "${target}..${branch}" 2>/dev/null || echo "0")
245
+ if [[ "$ahead_count" -eq 0 ]]; then
246
+ # Nothing to merge — just clean up
247
+ _worktree_cleanup --branch "$branch" --force
248
+ return $?
249
+ fi
250
+
251
+ # Safety check 4: check for merge conflicts (dry run)
252
+ local conflict_check
253
+ conflict_check=$(git -C "$AETHER_ROOT" merge-tree $(git -C "$AETHER_ROOT" merge-base "$target" "$branch") "$target" "$branch" 2>/dev/null | grep -c "changed in both" || echo "0")
254
+ if [[ "$conflict_check" -gt 0 ]] && [[ "$force" == "false" ]]; then
255
+ json_err "$E_VALIDATION_FAILED" "Merge would produce $conflict_check conflict(s). Resolve manually or use --force."
256
+ fi
257
+
258
+ # Perform the merge
259
+ local merge_sha
260
+ if ! git -C "$AETHER_ROOT" merge "$branch" --no-edit --no-ff -m "merge: worktree branch $branch into $target" >/dev/null 2>&1; then
261
+ # Merge failed — abort
262
+ git -C "$AETHER_ROOT" merge --abort 2>/dev/null || true
263
+ json_err "$E_GIT_ERROR" "Merge of '$branch' into '$target' failed. Aborted."
264
+ fi
265
+
266
+ merge_sha=$(git -C "$AETHER_ROOT" rev-parse HEAD 2>/dev/null || echo "unknown")
267
+
268
+ # Export pheromones from the worktree branch before cleanup
269
+ if [[ -f "$worktree_dir/.aether/data/pheromones.json" ]]; then
270
+ mkdir -p "$AETHER_ROOT/.aether/exchange"
271
+ cp "$worktree_dir/.aether/data/pheromones.json" \
272
+ "$AETHER_ROOT/.aether/exchange/pheromone-branch-export.json" 2>/dev/null || true
273
+ fi
274
+
275
+ # Cleanup the worktree
276
+ _worktree_cleanup --branch "$branch" --force 2>/dev/null || true
277
+
278
+ local result
279
+ result=$(jq -n \
280
+ --arg branch "$branch" \
281
+ --arg target "$target" \
282
+ --arg sha "$merge_sha" \
283
+ --argjson ahead "$ahead_count" \
284
+ '{merged: true, branch: $branch, target: $target, sha: $sha, commits_merged: $ahead}')
285
+ json_ok "$result"
286
+ }
@@ -309,7 +309,7 @@ Excavation date: {YYYY-MM-DD}
309
309
 
310
310
  Run using the Bash tool with description "Logging excavation activity...":
311
311
  ```bash
312
- bash .aether/aether-utils.sh activity-log "ARCHAEOLOGY" "Archaeologist" "Excavated {target}: {total_commits} commits, {author_count} authors, {findings_count} findings, {tech_debt_count} debt markers"
312
+ aether activity-log "ARCHAEOLOGY" "Archaeologist" "Excavated {target}: {total_commits} commits, {author_count} authors, {findings_count} findings, {tech_debt_count} debt markers"
313
313
  ```
314
314
 
315
315
  Generate the state-based Next Up block by running using the Bash tool with description "Generating Next Up suggestions...":
@@ -317,7 +317,7 @@ Generate the state-based Next Up block by running using the Bash tool with descr
317
317
  state=$(jq -r '.state // "IDLE"' .aether/data/COLONY_STATE.json)
318
318
  current_phase=$(jq -r '.current_phase // 0' .aether/data/COLONY_STATE.json)
319
319
  total_phases=$(jq -r '.plan.phases | length' .aether/data/COLONY_STATE.json)
320
- bash .aether/aether-utils.sh print-next-up "$state" "$current_phase" "$total_phases"
320
+ aether print-next-up
321
321
  ```
322
322
 
323
323
  ## Investigation Guidelines
@@ -295,12 +295,12 @@ After outputting the JSON report, iterate through the chaos report scenarios. Fo
295
295
 
296
296
  ```bash
297
297
  # For each scenario where status == "finding" AND severity is "CRITICAL" or "HIGH":
298
- bash .aether/aether-utils.sh flag-add "blocker" "{scenario.title}" "{scenario.description}" "chaos-standalone" {current_phase_number}
298
+ aether flag-add --severity "blocker" --title "{scenario.title}" --description "{scenario.description}" --source "chaos-standalone" --phase {current_phase_number}
299
299
  ```
300
300
 
301
301
  Log each flag creation by running using the Bash tool with description "Logging chaos flag...":
302
302
  ```bash
303
- bash .aether/aether-utils.sh activity-log "FLAG" "Chaos Ant" "Created blocker: {scenario.title}"
303
+ aether activity-log "FLAG" "Chaos Ant" "Created blocker: {scenario.title}"
304
304
  ```
305
305
 
306
306
  The `{current_phase_number}` comes from the colony state loaded in Step 1 (`.aether/data/COLONY_STATE.json` field `current_phase`).
@@ -311,7 +311,7 @@ The `{current_phase_number}` comes from the colony state loaded in Step 1 (`.aet
311
311
 
312
312
  Run using the Bash tool with description "Logging chaos activity...":
313
313
  ```bash
314
- bash .aether/aether-utils.sh activity-log "CHAOS" "Chaos Ant" "Resilience test on {target}: {findings_count} finding(s) ({critical} critical, {high} high, {medium} medium, {low} low), {resilient_count} resilient"
314
+ aether activity-log "CHAOS" "Chaos Ant" "Resilience test on {target}: {findings_count} finding(s) ({critical} critical, {high} high, {medium} medium, {low} low), {resilient_count} resilient"
315
315
  ```
316
316
 
317
317
  Generate the state-based Next Up block by running using the Bash tool with description "Generating Next Up suggestions...":
@@ -319,7 +319,7 @@ Generate the state-based Next Up block by running using the Bash tool with descr
319
319
  state=$(jq -r '.state // "IDLE"' .aether/data/COLONY_STATE.json)
320
320
  current_phase=$(jq -r '.current_phase // 0' .aether/data/COLONY_STATE.json)
321
321
  total_phases=$(jq -r '.plan.phases | length' .aether/data/COLONY_STATE.json)
322
- bash .aether/aether-utils.sh print-next-up "$state" "$current_phase" "$total_phases"
322
+ aether print-next-up
323
323
  ```
324
324
 
325
325
  ## Investigation Guidelines
@@ -109,14 +109,14 @@ Before dispatching surveyors, check for existing survey files and capture sessio
109
109
  SURVEY_START=$(date +%s)
110
110
 
111
111
  # Check for stale survey files
112
- stale_check=$(bash .aether/aether-utils.sh session-verify-fresh --command survey "" "$SURVEY_START")
112
+ stale_check=$(aether session-verify-fresh --command survey "" "$SURVEY_START")
113
113
  has_stale=$(echo "$stale_check" | jq -r '.stale | length')
114
114
  has_fresh=$(echo "$stale_check" | jq -r '.fresh | length')
115
115
 
116
116
  if [[ "$has_stale" -gt 0 ]] || [[ "$has_fresh" -gt 0 ]]; then
117
117
  # Found existing survey files
118
118
  if [[ "$force_resurvey" == "true" ]]; then
119
- bash .aether/aether-utils.sh session-clear --command survey
119
+ aether session-clear --command survey
120
120
  echo "Cleared existing survey files for fresh territory mapping"
121
121
  else
122
122
  echo "Found existing territory survey. Use --force-resurvey to remap."
@@ -127,15 +127,15 @@ fi
127
127
 
128
128
  Generate unique names for the 4 Surveyor Ants (each name must be captured separately):
129
129
  ```bash
130
- bash .aether/aether-utils.sh generate-ant-name "surveyor"
131
- bash .aether/aether-utils.sh generate-ant-name "surveyor"
132
- bash .aether/aether-utils.sh generate-ant-name "surveyor"
133
- bash .aether/aether-utils.sh generate-ant-name "surveyor"
130
+ aether generate-ant-name --caste "surveyor"
131
+ aether generate-ant-name --caste "surveyor"
132
+ aether generate-ant-name --caste "surveyor"
133
+ aether generate-ant-name --caste "surveyor"
134
134
  ```
135
135
 
136
136
  Log the dispatches (consolidated - fire-and-forget logging):
137
137
  ```bash
138
- bash .aether/aether-utils.sh spawn-log "Queen" "surveyor" "{provisions_name}" "Mapping provisions and trails" && bash .aether/aether-utils.sh spawn-log "Queen" "surveyor" "{nest_name}" "Mapping nest structure" && bash .aether/aether-utils.sh spawn-log "Queen" "surveyor" "{disciplines_name}" "Mapping disciplines and sentinels" && bash .aether/aether-utils.sh spawn-log "Queen" "surveyor" "{pathogens_name}" "Identifying pathogens"
138
+ aether spawn-log --name "Queen" --caste "surveyor" --id "{provisions_name}" --description "Mapping provisions and trails" && aether spawn-log --name "Queen" --caste "surveyor" --id "{nest_name}" --description "Mapping nest structure" && aether spawn-log --name "Queen" --caste "surveyor" --id "{disciplines_name}" --description "Mapping disciplines and sentinels" && aether spawn-log --name "Queen" --caste "surveyor" --id "{pathogens_name}" --description "Identifying pathogens"
139
139
  ```
140
140
 
141
141
  **Spawn 4 Surveyor Ants in parallel using the Task tool:**
@@ -179,7 +179,7 @@ If any documents are missing, note which ones in the output.
179
179
 
180
180
  Verify that all survey files were created after the session start:
181
181
  ```bash
182
- verify_result=$(bash .aether/aether-utils.sh session-verify-fresh --command survey "" "$SURVEY_START")
182
+ verify_result=$(aether session-verify-fresh --command survey "" "$SURVEY_START")
183
183
  fresh_count=$(echo "$verify_result" | jq -r '.fresh | length')
184
184
 
185
185
  if [[ "$fresh_count" -lt 7 ]]; then
@@ -255,5 +255,5 @@ Generate the state-based Next Up block:
255
255
  state=$(jq -r '.state // "IDLE"' .aether/data/COLONY_STATE.json)
256
256
  current_phase=$(jq -r '.current_phase // 0' .aether/data/COLONY_STATE.json)
257
257
  total_phases=$(jq -r '.plan.phases | length' .aether/data/COLONY_STATE.json)
258
- bash .aether/aether-utils.sh print-next-up "$state" "$current_phase" "$total_phases"
258
+ aether print-next-up
259
259
  ```
@@ -25,7 +25,7 @@ When `--deliberate "<proposal>"` is passed, run a structured Advocate/Challenger
25
25
 
26
26
  Run using the Bash tool with description "Checking deliberation budget...":
27
27
  ```bash
28
- bash .aether/aether-utils.sh council-budget-check
28
+ aether council-budget-check
29
29
  ```
30
30
 
31
31
  Parse result. If `allowed` is `false`:
@@ -41,7 +41,7 @@ Stop here.
41
41
 
42
42
  Run using the Bash tool with description "Opening deliberation...":
43
43
  ```bash
44
- bash .aether/aether-utils.sh council-deliberate --proposal "<proposal>"
44
+ aether council-deliberate --proposal "<proposal>"
45
45
  ```
46
46
 
47
47
  Capture `deliberation_id` from `result.id`.
@@ -84,7 +84,7 @@ Capture the advocate's argument as `advocate_argument`.
84
84
 
85
85
  Record the argument:
86
86
  ```bash
87
- bash .aether/aether-utils.sh council-advocate \
87
+ aether council-advocate \
88
88
  --deliberation-id "<deliberation_id>" \
89
89
  --argument "<advocate_argument>"
90
90
  ```
@@ -122,7 +122,7 @@ Capture the challenger's argument as `challenger_argument`.
122
122
 
123
123
  Record the argument:
124
124
  ```bash
125
- bash .aether/aether-utils.sh council-challenger \
125
+ aether council-challenger \
126
126
  --deliberation-id "<deliberation_id>" \
127
127
  --argument "<challenger_argument>"
128
128
  ```
@@ -165,7 +165,7 @@ Parse the JSON response. Capture `synthesis` and `recommendation`.
165
165
 
166
166
  Record the sage synthesis:
167
167
  ```bash
168
- bash .aether/aether-utils.sh council-sage \
168
+ aether council-sage \
169
169
  --deliberation-id "<deliberation_id>" \
170
170
  --synthesis "<synthesis>" \
171
171
  --recommendation "<recommendation>"
@@ -502,6 +502,6 @@ Generate the state-based Next Up block by running using the Bash tool with descr
502
502
  state=$(jq -r '.state // "IDLE"' .aether/data/COLONY_STATE.json)
503
503
  current_phase=$(jq -r '.current_phase // 0' .aether/data/COLONY_STATE.json)
504
504
  total_phases=$(jq -r '.plan.phases | length' .aether/data/COLONY_STATE.json)
505
- bash .aether/aether-utils.sh print-next-up "$state" "$current_phase" "$total_phases"
505
+ aether print-next-up
506
506
  ```
507
507
 
@@ -17,7 +17,7 @@ You are the **Queen Ant Colony**. Run the data cleaner to scan for and remove te
17
17
 
18
18
  Run using the Bash tool with description "Scanning colony data for test artifacts...":
19
19
  ```bash
20
- bash .aether/aether-utils.sh data-clean --dry-run
20
+ aether data-clean --dry-run
21
21
  ```
22
22
 
23
23
  Display the output to the user. This shows artifact counts per data file without modifying anything.
@@ -46,7 +46,7 @@ If user says no, display "No changes made." and skip to Step 5.
46
46
 
47
47
  If user confirmed, run using the Bash tool with description "Removing test artifacts...":
48
48
  ```bash
49
- bash .aether/aether-utils.sh data-clean --confirm
49
+ aether data-clean --confirm
50
50
  ```
51
51
 
52
52
  ### Step 4: Summary
@@ -76,6 +76,6 @@ Generate the state-based Next Up block by running using the Bash tool with descr
76
76
  state=$(jq -r '.state // "IDLE"' .aether/data/COLONY_STATE.json)
77
77
  current_phase=$(jq -r '.current_phase // 0' .aether/data/COLONY_STATE.json)
78
78
  total_phases=$(jq -r '.plan.phases | length' .aether/data/COLONY_STATE.json)
79
- bash .aether/aether-utils.sh print-next-up "$state" "$current_phase" "$total_phases"
79
+ aether print-next-up
80
80
  ```
81
81