aether-colony 5.3.2 → 5.3.3

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 (165) hide show
  1. package/.aether/aether-utils.sh +181 -5
  2. package/.aether/commands/build.yaml +35 -0
  3. package/.aether/commands/entomb.yaml +1 -1
  4. package/.aether/commands/init.yaml +29 -12
  5. package/.aether/commands/oracle.yaml +70 -0
  6. package/.aether/commands/patrol.yaml +2 -2
  7. package/.aether/commands/run.yaml +3 -3
  8. package/.aether/commands/swarm.yaml +1 -1
  9. package/.aether/docs/command-playbooks/build-complete.md +41 -8
  10. package/.aether/docs/command-playbooks/build-full.md +7 -7
  11. package/.aether/docs/command-playbooks/build-prep.md +1 -1
  12. package/.aether/docs/command-playbooks/continue-advance.md +33 -0
  13. package/.aether/docs/command-playbooks/continue-finalize.md +15 -1
  14. package/.aether/docs/command-playbooks/continue-full.md +15 -1
  15. package/.aether/docs/source-of-truth-map.md +10 -10
  16. package/.aether/docs/structural-learning-stack.md +283 -0
  17. package/.aether/utils/consolidation-seal.sh +196 -0
  18. package/.aether/utils/consolidation.sh +127 -0
  19. package/.aether/utils/curation-ants/archivist.sh +97 -0
  20. package/.aether/utils/curation-ants/critic.sh +214 -0
  21. package/.aether/utils/curation-ants/herald.sh +102 -0
  22. package/.aether/utils/curation-ants/janitor.sh +121 -0
  23. package/.aether/utils/curation-ants/librarian.sh +99 -0
  24. package/.aether/utils/curation-ants/nurse.sh +153 -0
  25. package/.aether/utils/curation-ants/orchestrator.sh +181 -0
  26. package/.aether/utils/curation-ants/scribe.sh +164 -0
  27. package/.aether/utils/curation-ants/sentinel.sh +119 -0
  28. package/.aether/utils/event-bus.sh +301 -0
  29. package/.aether/utils/graph.sh +559 -0
  30. package/.aether/utils/instinct-store.sh +401 -0
  31. package/.aether/utils/learning.sh +79 -7
  32. package/.aether/utils/session.sh +13 -0
  33. package/.aether/utils/state-api.sh +1 -1
  34. package/.aether/utils/trust-scoring.sh +347 -0
  35. package/.aether/utils/worktree.sh +97 -0
  36. package/.claude/commands/ant/entomb.md +1 -1
  37. package/.claude/commands/ant/init.md +29 -12
  38. package/.claude/commands/ant/oracle.md +35 -0
  39. package/.claude/commands/ant/patrol.md +2 -2
  40. package/.claude/commands/ant/run.md +3 -3
  41. package/.claude/commands/ant/swarm.md +1 -1
  42. package/.opencode/commands/ant/build.md +35 -0
  43. package/.opencode/commands/ant/init.md +29 -12
  44. package/.opencode/commands/ant/oracle.md +35 -0
  45. package/.opencode/commands/ant/patrol.md +2 -2
  46. package/.opencode/commands/ant/run.md +3 -3
  47. package/CHANGELOG.md +83 -0
  48. package/README.md +22 -9
  49. package/bin/lib/update-transaction.js +8 -3
  50. package/bin/npx-entry.js +0 -0
  51. package/package.json +1 -1
  52. package/.aether/agents/aether-ambassador.md +0 -140
  53. package/.aether/agents/aether-archaeologist.md +0 -108
  54. package/.aether/agents/aether-architect.md +0 -133
  55. package/.aether/agents/aether-auditor.md +0 -144
  56. package/.aether/agents/aether-builder.md +0 -184
  57. package/.aether/agents/aether-chaos.md +0 -115
  58. package/.aether/agents/aether-chronicler.md +0 -122
  59. package/.aether/agents/aether-gatekeeper.md +0 -116
  60. package/.aether/agents/aether-includer.md +0 -117
  61. package/.aether/agents/aether-keeper.md +0 -177
  62. package/.aether/agents/aether-measurer.md +0 -128
  63. package/.aether/agents/aether-oracle.md +0 -137
  64. package/.aether/agents/aether-probe.md +0 -133
  65. package/.aether/agents/aether-queen.md +0 -286
  66. package/.aether/agents/aether-route-setter.md +0 -130
  67. package/.aether/agents/aether-sage.md +0 -106
  68. package/.aether/agents/aether-scout.md +0 -101
  69. package/.aether/agents/aether-surveyor-disciplines.md +0 -391
  70. package/.aether/agents/aether-surveyor-nest.md +0 -329
  71. package/.aether/agents/aether-surveyor-pathogens.md +0 -264
  72. package/.aether/agents/aether-surveyor-provisions.md +0 -334
  73. package/.aether/agents/aether-tracker.md +0 -137
  74. package/.aether/agents/aether-watcher.md +0 -174
  75. package/.aether/agents/aether-weaver.md +0 -130
  76. package/.aether/commands/claude/archaeology.md +0 -334
  77. package/.aether/commands/claude/build.md +0 -65
  78. package/.aether/commands/claude/chaos.md +0 -336
  79. package/.aether/commands/claude/colonize.md +0 -259
  80. package/.aether/commands/claude/continue.md +0 -60
  81. package/.aether/commands/claude/council.md +0 -507
  82. package/.aether/commands/claude/data-clean.md +0 -81
  83. package/.aether/commands/claude/dream.md +0 -268
  84. package/.aether/commands/claude/entomb.md +0 -498
  85. package/.aether/commands/claude/export-signals.md +0 -57
  86. package/.aether/commands/claude/feedback.md +0 -96
  87. package/.aether/commands/claude/flag.md +0 -151
  88. package/.aether/commands/claude/flags.md +0 -169
  89. package/.aether/commands/claude/focus.md +0 -76
  90. package/.aether/commands/claude/help.md +0 -154
  91. package/.aether/commands/claude/history.md +0 -140
  92. package/.aether/commands/claude/import-signals.md +0 -71
  93. package/.aether/commands/claude/init.md +0 -505
  94. package/.aether/commands/claude/insert-phase.md +0 -105
  95. package/.aether/commands/claude/interpret.md +0 -278
  96. package/.aether/commands/claude/lay-eggs.md +0 -210
  97. package/.aether/commands/claude/maturity.md +0 -113
  98. package/.aether/commands/claude/memory-details.md +0 -77
  99. package/.aether/commands/claude/migrate-state.md +0 -171
  100. package/.aether/commands/claude/oracle.md +0 -642
  101. package/.aether/commands/claude/organize.md +0 -232
  102. package/.aether/commands/claude/patrol.md +0 -620
  103. package/.aether/commands/claude/pause-colony.md +0 -233
  104. package/.aether/commands/claude/phase.md +0 -115
  105. package/.aether/commands/claude/pheromones.md +0 -156
  106. package/.aether/commands/claude/plan.md +0 -693
  107. package/.aether/commands/claude/preferences.md +0 -65
  108. package/.aether/commands/claude/quick.md +0 -100
  109. package/.aether/commands/claude/redirect.md +0 -76
  110. package/.aether/commands/claude/resume-colony.md +0 -197
  111. package/.aether/commands/claude/resume.md +0 -388
  112. package/.aether/commands/claude/run.md +0 -231
  113. package/.aether/commands/claude/seal.md +0 -774
  114. package/.aether/commands/claude/skill-create.md +0 -286
  115. package/.aether/commands/claude/status.md +0 -410
  116. package/.aether/commands/claude/swarm.md +0 -349
  117. package/.aether/commands/claude/tunnels.md +0 -426
  118. package/.aether/commands/claude/update.md +0 -132
  119. package/.aether/commands/claude/verify-castes.md +0 -143
  120. package/.aether/commands/claude/watch.md +0 -239
  121. package/.aether/commands/opencode/archaeology.md +0 -331
  122. package/.aether/commands/opencode/build.md +0 -1168
  123. package/.aether/commands/opencode/chaos.md +0 -329
  124. package/.aether/commands/opencode/colonize.md +0 -195
  125. package/.aether/commands/opencode/continue.md +0 -1436
  126. package/.aether/commands/opencode/council.md +0 -437
  127. package/.aether/commands/opencode/data-clean.md +0 -77
  128. package/.aether/commands/opencode/dream.md +0 -260
  129. package/.aether/commands/opencode/entomb.md +0 -377
  130. package/.aether/commands/opencode/export-signals.md +0 -54
  131. package/.aether/commands/opencode/feedback.md +0 -99
  132. package/.aether/commands/opencode/flag.md +0 -149
  133. package/.aether/commands/opencode/flags.md +0 -167
  134. package/.aether/commands/opencode/focus.md +0 -73
  135. package/.aether/commands/opencode/help.md +0 -157
  136. package/.aether/commands/opencode/history.md +0 -136
  137. package/.aether/commands/opencode/import-signals.md +0 -68
  138. package/.aether/commands/opencode/init.md +0 -518
  139. package/.aether/commands/opencode/insert-phase.md +0 -111
  140. package/.aether/commands/opencode/interpret.md +0 -272
  141. package/.aether/commands/opencode/lay-eggs.md +0 -213
  142. package/.aether/commands/opencode/maturity.md +0 -108
  143. package/.aether/commands/opencode/memory-details.md +0 -83
  144. package/.aether/commands/opencode/migrate-state.md +0 -165
  145. package/.aether/commands/opencode/oracle.md +0 -593
  146. package/.aether/commands/opencode/organize.md +0 -226
  147. package/.aether/commands/opencode/patrol.md +0 -626
  148. package/.aether/commands/opencode/pause-colony.md +0 -203
  149. package/.aether/commands/opencode/phase.md +0 -113
  150. package/.aether/commands/opencode/pheromones.md +0 -162
  151. package/.aether/commands/opencode/plan.md +0 -684
  152. package/.aether/commands/opencode/preferences.md +0 -71
  153. package/.aether/commands/opencode/quick.md +0 -91
  154. package/.aether/commands/opencode/redirect.md +0 -84
  155. package/.aether/commands/opencode/resume-colony.md +0 -190
  156. package/.aether/commands/opencode/resume.md +0 -394
  157. package/.aether/commands/opencode/run.md +0 -237
  158. package/.aether/commands/opencode/seal.md +0 -452
  159. package/.aether/commands/opencode/skill-create.md +0 -63
  160. package/.aether/commands/opencode/status.md +0 -307
  161. package/.aether/commands/opencode/swarm.md +0 -15
  162. package/.aether/commands/opencode/tunnels.md +0 -400
  163. package/.aether/commands/opencode/update.md +0 -127
  164. package/.aether/commands/opencode/verify-castes.md +0 -139
  165. package/.aether/commands/opencode/watch.md +0 -227
@@ -328,6 +328,39 @@ bash .aether/aether-utils.sh state-mutate \
328
328
  Validate the state file:
329
329
  Run using the Bash tool with description "Validating colony state...": `bash .aether/aether-utils.sh validate-state colony`
330
330
 
331
+ ### Step 2.0.4: Worktree Merge-Back (NON-BLOCKING)
332
+
333
+ After state update, check for any completed worktree branches from the build wave and merge them back to the target branch.
334
+
335
+ Run using the Bash tool with description "Checking for worktree branches to merge...":
336
+ ```bash
337
+ # List worktree branches created during this build
338
+ branches=$(git -C "$AETHER_ROOT" worktree list --porcelain 2>/dev/null \
339
+ | grep "worktree-agent-\|worktree-" \
340
+ | awk '{print $NF}' || echo "")
341
+
342
+ last_merged_branch=""
343
+ last_merge_sha=""
344
+ merged_count=0
345
+
346
+ for branch in $branches; do
347
+ [[ -z "$branch" ]] && continue
348
+ result=$(bash "$AETHER_UTILS" worktree-merge --branch "$branch" 2>/dev/null || echo '{"ok":false}')
349
+ ok=$(echo "$result" | jq -r '.ok // false')
350
+ if [[ "$ok" == "true" ]]; then
351
+ last_merged_branch="$branch"
352
+ last_merge_sha=$(echo "$result" | jq -r '.result.sha // ""')
353
+ merged_count=$((merged_count + 1))
354
+ fi
355
+ done
356
+
357
+ if [[ "$merged_count" -gt 0 ]]; then
358
+ echo "Merged $merged_count worktree branch(es). Last: $last_merged_branch ($last_merge_sha)"
359
+ fi
360
+ ```
361
+
362
+ This step sets `$last_merged_branch` and `$last_merge_sha` which activates the existing dead code paths in Steps 2.0.5 and 2.0.6.
363
+
331
364
  ### Step 2.0.5: Pheromone Merge-Back (SILENT, NON-BLOCKING)
332
365
 
333
366
  If a `pheromone-branch-export.json` exists in `.aether/exchange/` (written by seal ceremony on a PR branch and merged to main), run merge-back to collect branch-discovered signals into main's pheromone store. This entire step is silent and non-blocking -- continue proceeds even if merge-back fails.
@@ -394,7 +394,7 @@ Output:
394
394
 
395
395
  ```
396
396
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
397
- P H A S E A D V A N C E M E N T
397
+ ➡️ P H A S E A D V A N C E M E N T
398
398
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
399
399
 
400
400
  ✅ Phase {prev_id}: {prev_name} -- COMPLETED
@@ -445,3 +445,17 @@ bash .aether/aether-utils.sh session-update "/ant:continue" "/ant:build {next_id
445
445
  ```
446
446
 
447
447
  Run using the Bash tool with description "Saving session state...": `bash .aether/aether-utils.sh session-update "/ant:continue" "/ant:build {next_id}" "Phase {prev_id} completed, advanced to Phase {next_id}"`
448
+
449
+ ### Step 4.5: Housekeeping (Non-Blocking)
450
+
451
+ Prune stale backups and temp files. This runs automatically — failures never affect phase advancement.
452
+
453
+ Run using the Bash tool with description "Pruning stale backups...":
454
+ ```bash
455
+ bash .aether/aether-utils.sh backup-prune-global 2>/dev/null || true
456
+ ```
457
+
458
+ Run using the Bash tool with description "Cleaning temp files...":
459
+ ```bash
460
+ bash .aether/aether-utils.sh temp-clean 2>/dev/null || true
461
+ ```
@@ -1676,7 +1676,7 @@ Output:
1676
1676
 
1677
1677
  ```
1678
1678
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1679
- P H A S E A D V A N C E M E N T
1679
+ ➡️ P H A S E A D V A N C E M E N T
1680
1680
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1681
1681
 
1682
1682
  ✅ Phase {prev_id}: {prev_name} -- COMPLETED
@@ -1723,3 +1723,17 @@ bash .aether/aether-utils.sh session-update "/ant:continue" "/ant:build {next_id
1723
1723
  ```
1724
1724
 
1725
1725
  Run using the Bash tool with description "Saving session state...": `bash .aether/aether-utils.sh session-update "/ant:continue" "/ant:build {next_id}" "Phase {prev_id} completed, advanced to Phase {next_id}"`
1726
+
1727
+ ### Step 4.5: Housekeeping (Non-Blocking)
1728
+
1729
+ Prune stale backups and temp files. This runs automatically — failures never affect phase advancement.
1730
+
1731
+ Run using the Bash tool with description "Pruning stale backups...":
1732
+ ```bash
1733
+ bash .aether/aether-utils.sh backup-prune-global 2>/dev/null || true
1734
+ ```
1735
+
1736
+ Run using the Bash tool with description "Cleaning temp files...":
1737
+ ```bash
1738
+ bash .aether/aether-utils.sh temp-clean 2>/dev/null || true
1739
+ ```
@@ -36,10 +36,10 @@ Define which files are authoritative for system behavior, which files are derive
36
36
  |---|---|---|
37
37
  | Core deterministic operations | `.aether/aether-utils.sh` | Dispatcher that loads domain modules on demand (~5,200 lines) |
38
38
  | Slash command orchestration | `.claude/commands/ant/*.md` | Includes build/continue orchestrators |
39
- | Worker behavior specs | `.claude/agents/ant/*.md` | 22 Claude agent definitions (Builder, Watcher, etc.) |
39
+ | Worker behavior specs | `.claude/agents/ant/*.md` | 24 Claude agent definitions (Builder, Watcher, etc.) |
40
40
  | Packaged Claude agent mirror | `.aether/agents-claude/*.md` | Distribution mirror; must stay byte-identical with `.claude/agents/ant/*.md` |
41
- | OpenCode command surface | `.opencode/commands/ant/*.md` | 44 OpenCode command files; structure parity with Claude commands |
42
- | OpenCode worker behavior specs | `.opencode/agents/*.md` | 22 OpenCode agent definitions |
41
+ | OpenCode command surface | `.opencode/commands/ant/*.md` | 45 OpenCode command files; structure parity with Claude commands |
42
+ | OpenCode worker behavior specs | `.opencode/agents/*.md` | 24 OpenCode agent definitions |
43
43
  | Domain modules | `.aether/utils/{flag,spawn,session,suggest,queen,swarm,learning,pheromone,state-api}.sh` | Extracted from aether-utils.sh in Phase 13; sourced on demand |
44
44
  | Build/continue split stages | `.aether/docs/command-playbooks/*.md` | Loaded by orchestrators; executable instruction docs |
45
45
  | Output templates | `.aether/templates/*` | Templates for generated state/handoff/wisdom/session artifacts |
@@ -66,8 +66,8 @@ Define which files are authoritative for system behavior, which files are derive
66
66
  - `build.md` and `continue.md` are now orchestrators that load split playbooks under `.aether/docs/command-playbooks/`.
67
67
  - Orchestrators run playbooks as staged instruction sets (Read-tool execution model), not as bash subcommand wrappers.
68
68
  - Cross-platform surfaces are present:
69
- - 44 Claude commands and 44 OpenCode commands
70
- - 22 Claude agents and 22 OpenCode agents
69
+ - 45 Claude commands and 45 OpenCode commands
70
+ - 24 Claude agents and 24 OpenCode agents
71
71
  - Autopilot subcommands (`autopilot-init`, `autopilot-update`, `autopilot-status`, `autopilot-stop`, `autopilot-check-replan`) manage autonomous build/continue cycles via `/ant:run`.
72
72
  - `registry-list` lists all registered repos with metadata including domain tags.
73
73
  - `.aether/agents-claude/*.md` mirrors `.claude/agents/ant/*.md` for packaging/distribution.
@@ -84,11 +84,11 @@ Define which files are authoritative for system behavior, which files are derive
84
84
  | Core utility entrypoint | `.aether/aether-utils.sh` | 1 | Active |
85
85
  | Sourced shell utilities | `.aether/utils/*.sh` | ~29 | Active (9 domain modules + infrastructure + XML) |
86
86
  | XML utility scripts | `.aether/utils/xml-*.sh` | 5 | Active (see drift note) |
87
- | Slash commands (Claude) | `.claude/commands/ant/*.md` | 44 | Active |
88
- | Slash commands (OpenCode) | `.opencode/commands/ant/*.md` | 44 | Active (content differs from Claude variants) |
89
- | Agent definitions (Claude) | `.claude/agents/ant/*.md` | 22 | Active |
90
- | Agent mirror (packaging) | `.aether/agents-claude/*.md` | 22 | Active mirror (must match Claude agent files exactly) |
91
- | Agent definitions (OpenCode) | `.opencode/agents/*.md` | 22 | Active (content differs from Claude variants) |
87
+ | Slash commands (Claude) | `.claude/commands/ant/*.md` | 45 | Active |
88
+ | Slash commands (OpenCode) | `.opencode/commands/ant/*.md` | 45 | Active (content differs from Claude variants) |
89
+ | Agent definitions (Claude) | `.claude/agents/ant/*.md` | 24 | Active |
90
+ | Agent mirror (packaging) | `.aether/agents-claude/*.md` | 24 | Active mirror (must match Claude agent files exactly) |
91
+ | Agent definitions (OpenCode) | `.opencode/agents/*.md` | 24 | Active (content differs from Claude variants) |
92
92
  | Command playbooks | `.aether/docs/command-playbooks/*.md` | 9 | Active (5 build + 4 continue; excludes full/README) |
93
93
  | Templates (all types) | `.aether/templates/*` | 12 | Active |
94
94
  | Disciplines | `.aether/docs/disciplines/*.md` | 7 | Active |
@@ -0,0 +1,283 @@
1
+ # Structural Learning Stack
2
+
3
+ > Memory consolidation pipeline: from raw observations to trusted wisdom.
4
+
5
+ ---
6
+
7
+ ## Overview
8
+
9
+ The Structural Learning Stack is how Aether converts raw, repeated observations into
10
+ colony wisdom that workers can act on. Each stage adds structure: trust scores quantify
11
+ reliability, the graph records relationships between instincts, curation ants clean and
12
+ promote, and the event bus connects everything loosely.
13
+
14
+ The stack runs automatically at phase-end and seal — workers never call it directly.
15
+
16
+ ---
17
+
18
+ ## Architecture Diagram
19
+
20
+ ```
21
+ learning-observe
22
+
23
+ [learning-observations.json]
24
+
25
+ trust-calculate
26
+
27
+
28
+ [instinct-store] ──────────► [instinct-graph.json]
29
+ │ (graph-link edges)
30
+
31
+ ┌──────────▼──────────┐
32
+ │ Curation Ants │
33
+ │ (phase-end / seal) │
34
+ └──────────┬──────────┘
35
+
36
+ ┌───────────────┼───────────────┐
37
+ ▼ ▼ ▼
38
+ [QUEEN.md] [event-bus.jsonl] [archived]
39
+ (via herald) (consolidation (low-trust
40
+ events) instincts)
41
+ ```
42
+
43
+ ---
44
+
45
+ ## Pipeline Stages
46
+
47
+ ### 1. Observation (learning.sh — `_learning_observe`)
48
+
49
+ Records an observation of a learning pattern into `.aether/data/learning-observations.json`.
50
+
51
+ - **Deduplication:** A SHA-256 hash of the content is used as the key. If an identical observation already exists, `observation_count` is incremented and `last_seen` is updated rather than creating a duplicate entry.
52
+ - **Trust score on write:** For new observations, `trust-calculate` is called immediately using the provided `source_type` and `evidence_type` (defaults: `observation` / `anecdotal`). The computed score is stored as `trust_score`.
53
+ - **Backup rotation:** A 3-file rotating backup (`*.bak.1`, `*.bak.2`, `*.bak.3`) is maintained on every write. On read, if the file is corrupt, the most recent valid backup is restored automatically.
54
+ - **Valid wisdom types:** `philosophy`, `pattern`, `redirect`, `stack`, `decree`, `failure`
55
+
56
+ Observation schema fields: `content_hash`, `content`, `wisdom_type`, `observation_count`, `first_seen`, `last_seen`, `colonies`, `trust_score`, `source_type`, `evidence_type`, `compression_level`.
57
+
58
+ ---
59
+
60
+ ### 2. Trust Scoring Engine (trust-scoring.sh)
61
+
62
+ A pure calculation module. No state is read or written. All functions accept `--flag value` arguments and return JSON.
63
+
64
+ **Weighted formula:**
65
+ ```
66
+ score = 0.40 × source_score + 0.35 × evidence_score + 0.25 × activity_score
67
+ ```
68
+
69
+ **Source types (40% weight):**
70
+
71
+ | Type | Score |
72
+ |------|-------|
73
+ | user_feedback | 1.0 |
74
+ | error_resolution | 0.9 |
75
+ | success_pattern | 0.8 |
76
+ | observation | 0.6 |
77
+ | heuristic | 0.4 |
78
+
79
+ **Evidence types (35% weight):**
80
+
81
+ | Type | Score |
82
+ |------|-------|
83
+ | test_verified | 1.0 |
84
+ | multi_phase | 0.9 |
85
+ | single_phase | 0.7 |
86
+ | anecdotal | 0.4 |
87
+
88
+ **Activity score (25% weight):** `0.5 ^ (days_since_last_use / 60)` — a 60-day half-life decay from the last observed use.
89
+
90
+ **Floor:** Score is never below `0.2`.
91
+
92
+ **Trust tiers:**
93
+
94
+ | Score range | Tier | Index |
95
+ |-------------|------|-------|
96
+ | 0.90 – 1.00 | canonical | 0 |
97
+ | 0.80 – 0.89 | trusted | 1 |
98
+ | 0.70 – 0.79 | established | 2 |
99
+ | 0.60 – 0.69 | emerging | 3 |
100
+ | 0.45 – 0.59 | provisional | 4 |
101
+ | 0.30 – 0.44 | suspect | 5 |
102
+ | 0.20 – 0.29 | dormant | 6 |
103
+
104
+ ---
105
+
106
+ ### 3. Event Bus (event-bus.sh)
107
+
108
+ A JSONL append-log at `.aether/data/event-bus.jsonl`. Each line is one JSON event object.
109
+
110
+ **Event fields:** `id`, `topic`, `payload`, `source`, `timestamp`, `ttl_days`, `expires_at`
111
+
112
+ - **Pub/sub pattern:** Publish to a topic with `event-publish`; subscribe by topic pattern with `event-subscribe`. Patterns support exact match or prefix wildcard (e.g., `"consolidation.*"`).
113
+ - **TTL:** Default 30 days per event. Events with `expires_at` in the past are excluded from subscriptions and removed by cleanup.
114
+ - **Concurrency:** File locking via `acquire_lock`/`release_lock` on every append and cleanup rewrite.
115
+ - **Replay:** `event-replay` returns events for a topic from a given ISO-8601 timestamp, sorted chronologically.
116
+ - **Cleanup:** `event-cleanup` atomically rewrites the JSONL file, keeping only non-expired events. Supports `--dry-run`.
117
+
118
+ ---
119
+
120
+ ### 4. Instinct Storage (instinct-store.sh)
121
+
122
+ Persistent trust-scored instincts at `.aether/data/instincts.json` (schema version 1.0).
123
+
124
+ **Instinct schema:**
125
+ ```json
126
+ {
127
+ "id": "inst_<timestamp>_<hex>",
128
+ "trigger": "...",
129
+ "action": "...",
130
+ "domain": "...",
131
+ "trust_score": 0.75,
132
+ "trust_tier": "established",
133
+ "confidence": 0.8,
134
+ "provenance": {
135
+ "source": "...",
136
+ "source_type": "observation",
137
+ "evidence": "...",
138
+ "created_at": "<ISO8601>",
139
+ "last_applied": null,
140
+ "application_count": 0
141
+ },
142
+ "application_history": [],
143
+ "related_instincts": [],
144
+ "archived": false
145
+ }
146
+ ```
147
+
148
+ - **Deduplication:** First 50 characters of `trigger` are matched against existing active entries. On match, confidence is boosted to `max(existing, new)` and the trust score is recomputed.
149
+ - **50-instinct cap:** When active count exceeds 50 after insert, the entry with the lowest `trust_score` is soft-deleted (`archived: true`).
150
+ - **Decay:** `instinct-decay-all` applies the same 60-day half-life decay to all active entries. Entries whose decayed score falls below `0.25` are automatically archived.
151
+ - **Read:** `instinct-read-trusted` returns active entries filtered by `min-score` (default 0.5), optionally by domain, sorted by `trust_score` descending.
152
+
153
+ ---
154
+
155
+ ### 5. Graph Layer (graph.sh)
156
+
157
+ Tracks directed relationships between instincts at `.aether/data/instinct-graph.json`.
158
+
159
+ **Edge schema:** `edge_id`, `source`, `target`, `relationship`, `weight`, `created_at`
160
+
161
+ **Relationship types:** `reinforces`, `contradicts`, `extends`, `supersedes`, `related`
162
+
163
+ **Operations:**
164
+
165
+ | Function | Description |
166
+ |----------|-------------|
167
+ | `graph-link` | Create or update a directed edge. Duplicate `source+target+relationship` updates the weight. Default weight: 0.5. |
168
+ | `graph-neighbors` | 1-hop lookup. Direction: `out`, `in`, or `both`. Optional relationship filter. |
169
+ | `graph-reach` | BFS traversal up to N hops (max 3). Returns `{id, hop, path}` for each reachable node. Optional `--min-weight` filter. Early exit when no new nodes are found. |
170
+ | `graph-cluster` | Finds clusters of strongly connected instincts using greedy union-find over qualifying edges. Defaults: `min-edges=2`, `min-weight=0.3`. Returns `{nodes, edge_count, avg_weight}` per cluster. |
171
+
172
+ ---
173
+
174
+ ### 6. Curation Ants
175
+
176
+ Eight specialized ants that maintain memory quality. The orchestrator (`curation-run`) runs all eight in sequence. Sentinel can abort the run early if critical corruption is detected.
177
+
178
+ **Execution order:**
179
+
180
+ ```
181
+ sentinel → nurse → critic → herald → janitor → archivist → librarian → scribe
182
+ ```
183
+
184
+ **Ant responsibilities:**
185
+
186
+ | Ant | Responsibility |
187
+ |-----|---------------|
188
+ | sentinel | Health check on all memory stores. Aborts subsequent steps if critical corruption is found. |
189
+ | nurse | Recalculates trust scores for observations and instincts using current elapsed days. |
190
+ | critic | Detects contradictions between instincts (overlapping triggers with conflicting actions). |
191
+ | herald | Promotes high-trust instincts to QUEEN.md Patterns/Philosophies section. |
192
+ | janitor | Removes expired events from the event bus; prunes old archived instincts. |
193
+ | archivist | Archives active instincts whose trust score has fallen below a configurable threshold (default: 0.3 at seal). |
194
+ | librarian | Collects inventory statistics across all memory stores. |
195
+ | scribe | Generates a markdown consolidation report. |
196
+
197
+ All steps are non-blocking — a failure in one step is logged and execution continues.
198
+
199
+ ---
200
+
201
+ ### 7. Consolidation Pipeline
202
+
203
+ Two consolidation modes, each calling into the curation ants.
204
+
205
+ **Phase-end (lightweight) — `consolidation-phase-end`:**
206
+
207
+ Runs at the end of every phase (`/ant:continue`). Executes three ants only: `nurse → herald → janitor`. Publishes a `consolidation.phase_end` event on the event bus. All three steps are non-blocking.
208
+
209
+ **Seal (full) — `consolidation-seal`:**
210
+
211
+ Runs once during `/ant:seal`. Executes five steps:
212
+
213
+ 1. `curation-run` — full 8-ant orchestration
214
+ 2. `instinct-decay-all` — final trust decay pass across all active instincts
215
+ 3. `curation-archivist --threshold 0.3` — archive borderline instincts
216
+ 4. `event-publish` — publish `consolidation.seal` event
217
+ 5. `curation-scribe` — generate final consolidation report
218
+
219
+ All steps are non-blocking. The seal report path is returned in the output.
220
+
221
+ ---
222
+
223
+ ## Integration Points
224
+
225
+ | Trigger | Stack call | Effect |
226
+ |---------|-----------|--------|
227
+ | `/ant:continue` | `consolidation-phase-end` | nurse + herald + janitor; phase_end event |
228
+ | `/ant:seal` | `consolidation-seal` | full 8-ant curation + decay + archive + seal event + report |
229
+ | `/ant:build` (pattern capture) | `learning-observe` | Records observation with trust score |
230
+ | `colony-prime` | `instinct-read-trusted` | Injects trusted instincts into worker prompts |
231
+
232
+ ---
233
+
234
+ ## Subcommand Reference
235
+
236
+ | Subcommand | Module | Usage |
237
+ |-----------|--------|-------|
238
+ | `trust-calculate` | trust-scoring.sh | `--source <type> --evidence <type> --days-since <N>` |
239
+ | `trust-decay` | trust-scoring.sh | `--score <float> --days <N>` |
240
+ | `trust-tier` | trust-scoring.sh | `--score <float>` |
241
+ | `event-publish` | event-bus.sh | `--topic <topic> --payload <json> [--source <src>] [--ttl <days>]` |
242
+ | `event-subscribe` | event-bus.sh | `--topic <pattern> [--since <ISO>] [--limit <N>]` |
243
+ | `event-cleanup` | event-bus.sh | `[--dry-run]` |
244
+ | `event-replay` | event-bus.sh | `--topic <topic> --since <ISO> [--limit <N>]` |
245
+ | `instinct-store` | instinct-store.sh | `--trigger <t> --action <a> --domain <d> --confidence <f> --source <s> --evidence <e> [--source-type <type>]` |
246
+ | `instinct-read-trusted` | instinct-store.sh | `[--min-score <f>] [--domain <d>] [--limit <N>]` |
247
+ | `instinct-decay-all` | instinct-store.sh | `[--days <N>] [--dry-run]` |
248
+ | `instinct-archive` | instinct-store.sh | `--id <id>` |
249
+ | `graph-link` | graph.sh | `--source <id> --target <id> --relationship <type> [--weight <float>]` |
250
+ | `graph-neighbors` | graph.sh | `--id <id> [--direction out\|in\|both] [--relationship <type>]` |
251
+ | `graph-reach` | graph.sh | `--id <id> --hops <N> [--min-weight <float>]` |
252
+ | `graph-cluster` | graph.sh | `[--min-edges <N>] [--min-weight <float>]` |
253
+ | `curation-sentinel` | curation-ants/sentinel.sh | `[--dry-run]` |
254
+ | `curation-nurse` | curation-ants/nurse.sh | `[--dry-run]` |
255
+ | `curation-critic` | curation-ants/critic.sh | `[--dry-run]` |
256
+ | `curation-herald` | curation-ants/herald.sh | `[--dry-run]` |
257
+ | `curation-janitor` | curation-ants/janitor.sh | `[--dry-run]` |
258
+ | `curation-archivist` | curation-ants/archivist.sh | `[--threshold <f>] [--dry-run]` |
259
+ | `curation-librarian` | curation-ants/librarian.sh | `[--dry-run]` |
260
+ | `curation-scribe` | curation-ants/scribe.sh | `[--dry-run]` |
261
+ | `curation-run` | curation-ants/orchestrator.sh | `[--dry-run] [--verbose]` |
262
+ | `consolidation-phase-end` | consolidation.sh | `[--dry-run]` |
263
+ | `consolidation-seal` | consolidation-seal.sh | `[--dry-run]` |
264
+
265
+ ---
266
+
267
+ ## Test Coverage
268
+
269
+ | Test file | What it covers |
270
+ |-----------|---------------|
271
+ | `tests/bash/test-trust-scoring.sh` | `trust-calculate`, `trust-decay`, `trust-tier`; formula weights, floor, tiers |
272
+ | `tests/bash/test-event-bus.sh` | `event-publish`, `event-subscribe`, `event-cleanup`, `event-replay`; TTL, locking, wildcard patterns |
273
+ | `tests/bash/test-instinct-store.sh` | `instinct-store`, `instinct-read-trusted`, `instinct-decay-all`, `instinct-archive`; 50-cap, dedup, decay archival |
274
+ | `tests/bash/test-instinct-apply.sh` | Instinct application and provenance tracking |
275
+ | `tests/bash/test-graph.sh` | `graph-link`, `graph-neighbors`, `graph-reach`, `graph-cluster`; BFS traversal, cluster detection |
276
+ | `tests/bash/test-curation-core.sh` | Core curation ant behavior (sentinel, nurse, critic) |
277
+ | `tests/bash/test-curation-ops.sh` | Operational curation ants (herald, janitor, archivist, librarian, scribe) |
278
+ | `tests/bash/test-curation-orchestrator.sh` | `curation-run` full sequence, sentinel abort path |
279
+ | `tests/bash/test-consolidation.sh` | `consolidation-phase-end`; phase-end step sequence, event publishing |
280
+ | `tests/bash/test-consolidation-seal.sh` | `consolidation-seal`; full seal sequence, dry-run mode |
281
+ | `tests/bash/test-learning-module.sh` | `learning-observe`; trust score on write, deduplication, observation_count increment |
282
+ | `tests/bash/test-learning-recovery.sh` | Backup rotation and corrupt-file recovery logic |
283
+ | `tests/bash/test-oracle-trust.sh` | Trust scoring integration with oracle/research paths |
@@ -0,0 +1,196 @@
1
+ #!/bin/bash
2
+ # Consolidation Seal — Full seal-ceremony consolidation
3
+ # Provides: _consolidation_seal
4
+ #
5
+ # Runs once during /ant:seal. Orchestrates curation-run, instinct-decay-all,
6
+ # curation-archivist, event publish, and curation-scribe in sequence.
7
+ # Each step is non-blocking: failures are logged but do not stop the seal.
8
+ #
9
+ # These functions are sourced by aether-utils.sh at startup.
10
+ # All shared infrastructure (json_ok, json_err, COLONY_DATA_DIR, DATA_DIR,
11
+ # error constants) is available when sourced.
12
+
13
+ # ============================================================================
14
+ # _consolidation_seal
15
+ # Full consolidation for the seal ceremony.
16
+ #
17
+ # Usage: consolidation-seal [--dry-run]
18
+ #
19
+ # Steps:
20
+ # 1. curation-run — full 8-ant orchestration
21
+ # 2. instinct-decay-all — final trust decay pass
22
+ # 3. curation-archivist — archive borderline instincts (threshold 0.3)
23
+ # 4. event-publish — publish consolidation.seal event
24
+ # 5. curation-scribe — generate final report
25
+ #
26
+ # Output: json_ok with {type, steps, event_published, dry_run}
27
+ # ============================================================================
28
+ _consolidation_seal() {
29
+ local dry_run="false"
30
+
31
+ while [[ $# -gt 0 ]]; do
32
+ case "$1" in
33
+ --dry-run) dry_run="true"; shift ;;
34
+ *) shift ;;
35
+ esac
36
+ done
37
+
38
+ local steps_json="[]"
39
+ local event_published="false"
40
+
41
+ # _cs_step <name> <subcommand> [extra_args...]
42
+ # Runs the subcommand non-blocking (failures logged, not fatal).
43
+ # Appends a step entry to steps_json.
44
+ _cs_step() {
45
+ local step_name="$1"
46
+ shift
47
+ local subcmd="$1"
48
+ shift
49
+ # Remaining positional args are passed to the subcommand
50
+
51
+ local step_result step_status step_summary step_report_path="null"
52
+
53
+ # Build argument array respecting dry_run
54
+ local -a args=("$subcmd")
55
+ if [[ "$dry_run" == "true" ]]; then
56
+ args+=("--dry-run")
57
+ fi
58
+ # Append any extra args
59
+ while [[ $# -gt 0 ]]; do
60
+ args+=("$1")
61
+ shift
62
+ done
63
+
64
+ step_result=$(bash "$0" "${args[@]}" 2>/dev/null) || true
65
+
66
+ if echo "$step_result" | jq -e '.ok == true' >/dev/null 2>&1; then
67
+ step_status="ok"
68
+ step_summary=$(echo "$step_result" | jq -r '
69
+ .result |
70
+ if type == "object" then
71
+ [ to_entries[] | "\(.key) \(.value)" ] | join(", ")
72
+ else
73
+ tostring
74
+ end
75
+ ' 2>/dev/null | head -c 120 || echo "ok")
76
+ [[ -z "$step_summary" ]] && step_summary="ok"
77
+
78
+ # Extract report_path if present (scribe step)
79
+ step_report_path=$(echo "$step_result" | jq -r '.result.report_path // "null"' 2>/dev/null || echo "null")
80
+ else
81
+ step_status="failed"
82
+ local err_msg
83
+ err_msg=$(echo "$step_result" | jq -r '.error // "unknown error"' 2>/dev/null || echo "unknown error")
84
+ step_summary="$err_msg"
85
+ fi
86
+
87
+ steps_json=$(echo "$steps_json" | jq \
88
+ --arg name "$step_name" \
89
+ --arg status "$step_status" \
90
+ --arg summary "$step_summary" \
91
+ --arg rp "$step_report_path" \
92
+ '. += [{
93
+ "name": $name,
94
+ "status": $status,
95
+ "summary": $summary,
96
+ "report_path": (if $rp == "null" then null else $rp end)
97
+ }]')
98
+ }
99
+
100
+ # ── Step 1: Full 8-ant curation run ────────────────────────────────────────
101
+ _cs_step "curation-run" "curation-run"
102
+
103
+ # ── Step 2: Final trust decay pass ─────────────────────────────────────────
104
+ _cs_step "instinct-decay-all" "instinct-decay-all"
105
+
106
+ # ── Step 3: Archive borderline instincts (threshold 0.3) ───────────────────
107
+ # Note: --dry-run is injected by _cs_step; but archivist also takes --threshold
108
+ # We cannot let _cs_step inject --dry-run before --threshold so we handle manually
109
+ local arch_result arch_status arch_summary
110
+ local -a arch_args=("curation-archivist" "--threshold" "0.3")
111
+ if [[ "$dry_run" == "true" ]]; then
112
+ arch_args+=("--dry-run")
113
+ fi
114
+ arch_result=$(bash "$0" "${arch_args[@]}" 2>/dev/null) || true
115
+ if echo "$arch_result" | jq -e '.ok == true' >/dev/null 2>&1; then
116
+ arch_status="ok"
117
+ arch_summary=$(echo "$arch_result" | jq -r '
118
+ .result |
119
+ if type == "object" then
120
+ [ to_entries[] | "\(.key) \(.value)" ] | join(", ")
121
+ else tostring end
122
+ ' 2>/dev/null | head -c 120 || echo "ok")
123
+ [[ -z "$arch_summary" ]] && arch_summary="ok"
124
+ else
125
+ arch_status="failed"
126
+ arch_summary=$(echo "$arch_result" | jq -r '.error // "unknown error"' 2>/dev/null || echo "unknown error")
127
+ fi
128
+ steps_json=$(echo "$steps_json" | jq \
129
+ --arg status "$arch_status" \
130
+ --arg summary "$arch_summary" \
131
+ '. += [{"name":"archivist","status":$status,"summary":$summary,"report_path":null}]')
132
+
133
+ # ── Step 4: Publish consolidation.seal event ───────────────────────────────
134
+ if [[ "$dry_run" != "true" ]]; then
135
+ local payload
136
+ payload=$(jq -nc \
137
+ --arg ts "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" \
138
+ --argjson steps "$steps_json" \
139
+ '{"timestamp":$ts,"steps":$steps}')
140
+ local ep_result
141
+ ep_result=$(bash "$0" event-publish \
142
+ --topic "consolidation.seal" \
143
+ --payload "$payload" \
144
+ --source "consolidation-seal" 2>/dev/null) || true
145
+ if echo "$ep_result" | jq -e '.ok == true' >/dev/null 2>&1; then
146
+ event_published="true"
147
+ fi
148
+ else
149
+ # In dry-run mode, report event as published (no side effects)
150
+ event_published="true"
151
+ fi
152
+
153
+ # ── Step 5: Generate final scribe report ───────────────────────────────────
154
+ local scribe_result scribe_status scribe_summary scribe_report_path="null"
155
+ local -a scribe_args=("curation-scribe")
156
+ if [[ "$dry_run" == "true" ]]; then
157
+ scribe_args+=("--dry-run")
158
+ fi
159
+ scribe_result=$(bash "$0" "${scribe_args[@]}" 2>/dev/null) || true
160
+ if echo "$scribe_result" | jq -e '.ok == true' >/dev/null 2>&1; then
161
+ scribe_status="ok"
162
+ scribe_summary=$(echo "$scribe_result" | jq -r '
163
+ .result |
164
+ if type == "object" then
165
+ [ to_entries[] | "\(.key) \(.value)" ] | join(", ")
166
+ else tostring end
167
+ ' 2>/dev/null | head -c 120 || echo "ok")
168
+ [[ -z "$scribe_summary" ]] && scribe_summary="ok"
169
+ scribe_report_path=$(echo "$scribe_result" | jq -r '.result.report_path // "null"' 2>/dev/null || echo "null")
170
+ else
171
+ scribe_status="failed"
172
+ scribe_summary=$(echo "$scribe_result" | jq -r '.error // "unknown error"' 2>/dev/null || echo "unknown error")
173
+ fi
174
+ steps_json=$(echo "$steps_json" | jq \
175
+ --arg status "$scribe_status" \
176
+ --arg summary "$scribe_summary" \
177
+ --arg rp "$scribe_report_path" \
178
+ '. += [{
179
+ "name": "scribe",
180
+ "status": $status,
181
+ "summary": $summary,
182
+ "report_path": (if $rp == "null" then null else $rp end)
183
+ }]')
184
+
185
+ # ── Output ─────────────────────────────────────────────────────────────────
186
+ json_ok "$(jq -n \
187
+ --argjson steps "$steps_json" \
188
+ --argjson event_published "$([ "$event_published" == "true" ] && echo true || echo false)" \
189
+ --argjson dry "$([ "$dry_run" == "true" ] && echo true || echo false)" \
190
+ '{
191
+ "type": "seal",
192
+ "steps": $steps,
193
+ "event_published": $event_published,
194
+ "dry_run": $dry
195
+ }')"
196
+ }