total-recall-brain 3.43.3 → 3.45.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 (252) hide show
  1. package/bin/total-recall.mjs +6 -4
  2. package/docs/ARCHITECTURE.md +10 -7
  3. package/docs/reference/cli-reference.md +16 -9
  4. package/frontend/dist/assets/index-DACh1dhx.js +5613 -0
  5. package/frontend/dist/index.html +1 -1
  6. package/frontend/src/App.tsx +2 -2
  7. package/frontend/src/pages/PluginsPage.tsx +1 -1
  8. package/package.json +3 -3
  9. package/scaffold/.agent/skills/plugin/SKILL.md +7 -2
  10. package/scaffold/.agent/skills/plugin/evals/README.md +5 -0
  11. package/scaffold/.agent/skills/plugin/evals/cases/01-fabricated-seed.mjs +1 -0
  12. package/scaffold/.agent/skills/plugin/evals/cases/02-reassuring-default.mjs +1 -0
  13. package/scaffold/.agent/skills/plugin/evals/cases/03-declared-template.mjs +1 -0
  14. package/scaffold/.agent/skills/plugin/evals/cases/04-card-collects-credential.mjs +1 -0
  15. package/scaffold/.agent/skills/plugin/evals/cases/05-host-leak-in-scaffold.mjs +1 -0
  16. package/scaffold/.agent/skills/plugin/evals/cases/06-correct-plugin.mjs +1 -0
  17. package/scaffold/.agent/skills/plugin/evals/cases/07-missing-reuse.mjs +11 -0
  18. package/scaffold/.agent/skills/plugin/evals/cases/08-unresolved-owner-command.mjs +12 -0
  19. package/scaffold/.agent/skills/plugin/evals/cases/09-missing-brick.mjs +12 -0
  20. package/scaffold/.agent/skills/plugin/prompts/01-function.md +4 -3
  21. package/scaffold/.agent/skills/plugin/prompts/08-verify.md +1 -0
  22. package/scaffold/.agent/skills/plugin/references/surfaces.md +12 -2
  23. package/scaffold/.agent/skills/plugin/scripts/record.mjs +59 -2
  24. package/scaffold/.agent/skills/total-recall/plugins/auth/README.md +8 -0
  25. package/scaffold/.agent/skills/total-recall/plugins/auth/package-lock.json +15 -14
  26. package/scaffold/.agent/skills/total-recall/plugins/auth/package.json +3 -3
  27. package/scaffold/.agent/skills/total-recall/plugins/auth/plugin.json +1 -1
  28. package/scaffold/.agent/skills/total-recall/plugins/auth/src/cli-gh-login.mjs +102 -0
  29. package/scaffold/.agent/skills/total-recall/plugins/auth/src/cli-secret.mjs +38 -2
  30. package/scaffold/.agent/skills/total-recall/plugins/auth/src/login-projections.mjs +157 -13
  31. package/scaffold/.agent/skills/total-recall/plugins/auth/src/secrets-store.mjs +12 -1
  32. package/scaffold/.agent/skills/total-recall/plugins/auth/src/secrets-sync.mjs +161 -17
  33. package/scaffold/.agent/skills/total-recall/plugins/automations/BRICK.md +7 -0
  34. package/scaffold/.agent/skills/total-recall/plugins/automations/LICENSE +21 -0
  35. package/scaffold/.agent/skills/total-recall/plugins/automations/README.md +66 -0
  36. package/scaffold/.agent/skills/total-recall/plugins/automations/adapters.mjs +231 -0
  37. package/scaffold/.agent/skills/total-recall/plugins/automations/capability/index.mjs +16 -0
  38. package/scaffold/.agent/skills/total-recall/plugins/automations/cli.mjs +121 -0
  39. package/{src/core/plugin-cron.mjs → scaffold/.agent/skills/total-recall/plugins/automations/cron.mjs} +1 -3
  40. package/scaffold/.agent/skills/total-recall/plugins/automations/inventory.mjs +88 -0
  41. package/scaffold/.agent/skills/total-recall/plugins/automations/package-lock.json +7661 -0
  42. package/scaffold/.agent/skills/total-recall/plugins/automations/package.json +35 -0
  43. package/scaffold/.agent/skills/total-recall/plugins/automations/plugin.json +167 -0
  44. package/scaffold/.agent/skills/total-recall/plugins/automations/scheduler.mjs +246 -0
  45. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/DESIGN.md +42 -0
  46. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/automations.js +2 -0
  47. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/card.js +273 -0
  48. package/scaffold/.agent/skills/total-recall/plugins/code-quality/commands/run-core.mjs +1 -1
  49. package/scaffold/.agent/skills/total-recall/plugins/code-quality/core/check.mjs +57 -5
  50. package/scaffold/.agent/skills/total-recall/plugins/code-quality/core/report-data.mjs +40 -14
  51. package/scaffold/.agent/skills/total-recall/plugins/code-quality/core/report.mjs +15 -40
  52. package/scaffold/.agent/skills/total-recall/plugins/code-quality/package-lock.json +15 -14
  53. package/scaffold/.agent/skills/total-recall/plugins/code-quality/package.json +3 -3
  54. package/scaffold/.agent/skills/total-recall/plugins/code-quality/plugin.json +1 -1
  55. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package-lock.json +15 -14
  56. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package.json +3 -3
  57. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/plugin.json +1 -1
  58. package/scaffold/.agent/skills/total-recall/plugins/embeddings/package-lock.json +15 -14
  59. package/scaffold/.agent/skills/total-recall/plugins/embeddings/package.json +3 -3
  60. package/scaffold/.agent/skills/total-recall/plugins/embeddings/plugin.json +1 -1
  61. package/scaffold/.agent/skills/total-recall/plugins/git/README.md +112 -0
  62. package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/cli.mjs +135 -23
  63. package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/package-lock.json +17 -16
  64. package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/package.json +5 -4
  65. package/scaffold/.agent/skills/total-recall/plugins/git/plugin.json +161 -0
  66. package/scaffold/.agent/skills/total-recall/plugins/git/src/lib/context.mjs +94 -0
  67. package/scaffold/.agent/skills/total-recall/plugins/git/src/lib/phase3-spec-support.mjs +50 -0
  68. package/scaffold/.agent/skills/total-recall/plugins/git/src/lib/runtime.mjs +40 -0
  69. package/scaffold/.agent/skills/total-recall/plugins/git/src/lib/spec-support.mjs +51 -0
  70. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/_support.mjs +195 -0
  71. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/auth.mjs +201 -0
  72. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/bisect.mjs +40 -0
  73. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/cli-meta.mjs +159 -0
  74. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/commit-memory.mjs +30 -0
  75. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/commit.mjs +46 -0
  76. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/fleet.mjs +156 -0
  77. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/force-push.mjs +58 -0
  78. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/group.mjs +119 -0
  79. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/handoff.mjs +59 -0
  80. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/message.mjs +22 -0
  81. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/resolve.mjs +60 -0
  82. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/rules.mjs +81 -0
  83. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/secret-firewall.mjs +66 -0
  84. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/undo.mjs +132 -0
  85. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/why.mjs +16 -0
  86. package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/ui/card.js +2 -2
  87. package/scaffold/.agent/skills/total-recall/plugins/mesh/package-lock.json +15 -14
  88. package/scaffold/.agent/skills/total-recall/plugins/mesh/package.json +3 -3
  89. package/scaffold/.agent/skills/total-recall/plugins/mesh/plugin.json +1 -1
  90. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/README.md +59 -10
  91. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/capability/BRICK.md +1 -1
  92. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/capability/index.mjs +18 -6
  93. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/cli.mjs +160 -29
  94. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package-lock.json +15 -14
  95. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package.json +4 -4
  96. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/plugin.json +231 -16
  97. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/skills/meta-harness/SKILL.md +19 -4
  98. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/adoption.mjs +104 -0
  99. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/alerts.mjs +3 -3
  100. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/cascade.mjs +101 -16
  101. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/control.mjs +145 -0
  102. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/coordinator.mjs +54 -21
  103. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/dispatch-request.mjs +40 -0
  104. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/dispatch.mjs +68 -13
  105. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/documentation.mjs +55 -11
  106. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/executor.mjs +64 -15
  107. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/gate-adapters/hermes.mjs +29 -1
  108. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/gate-adapters/index.mjs +1 -1
  109. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/included-usage.mjs +249 -0
  110. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/jobs.mjs +84 -0
  111. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/learner.mjs +6 -12
  112. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/maintenance.mjs +17 -0
  113. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/mcp-server.mjs +228 -0
  114. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/pool.mjs +16 -8
  115. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/process-manager.mjs +26 -2
  116. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/reasoning.mjs +6 -1
  117. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/remote-operation.mjs +6 -2
  118. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/review.mjs +34 -3
  119. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/reviews.mjs +25 -0
  120. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/router.mjs +28 -12
  121. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/runtime.mjs +28 -6
  122. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/claude.mjs +319 -0
  123. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/codex.mjs +387 -0
  124. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/result.mjs +67 -0
  125. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/resume.mjs +373 -0
  126. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/run.mjs +223 -0
  127. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session-jobs.mjs +72 -0
  128. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/setup.mjs +6 -3
  129. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/termination.mjs +16 -12
  130. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/threads.mjs +32 -1
  131. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/usage-queue.mjs +110 -0
  132. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/verify-ssss.mjs +3 -3
  133. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/worker.mjs +597 -70
  134. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/worktree.mjs +76 -9
  135. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/DESIGN.md +5 -5
  136. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/card.js +3 -3
  137. package/scaffold/.agent/skills/total-recall/plugins/openwiki/cli.mjs +47 -18
  138. package/scaffold/.agent/skills/total-recall/plugins/openwiki/package-lock.json +15 -14
  139. package/scaffold/.agent/skills/total-recall/plugins/openwiki/package.json +3 -3
  140. package/scaffold/.agent/skills/total-recall/plugins/openwiki/plugin.json +1 -1
  141. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/refresh-diagnostics.mjs +44 -0
  142. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/refresh.mjs +120 -113
  143. package/scaffold/.agent/skills/total-recall/plugins/security/package-lock.json +15 -14
  144. package/scaffold/.agent/skills/total-recall/plugins/security/package.json +3 -3
  145. package/scaffold/.agent/skills/total-recall/plugins/security/plugin.json +1 -1
  146. package/scaffold/.agent/skills/total-recall/plugins/ssss/assets/scaffold.json +5 -5
  147. package/scaffold/.agent/skills/total-recall/plugins/ssss/package-lock.json +6 -6
  148. package/scaffold/.agent/skills/total-recall/plugins/ssss/package.json +2 -2
  149. package/scaffold/.agent/skills/total-recall/plugins/ssss/plugin.json +1 -1
  150. package/scaffold/.agent/skills/total-recall/references/operations.md +1 -1
  151. package/src/cli/agent.mjs +1 -1
  152. package/src/cli/command.mjs +41 -2
  153. package/src/cli/connect.mjs +2 -29
  154. package/src/cli/context.mjs +1 -0
  155. package/src/cli/dream.mjs +93 -69
  156. package/src/cli/harness.mjs +4 -4
  157. package/src/cli/help.mjs +1 -1
  158. package/src/cli/ingest-okf.mjs +4 -4
  159. package/src/cli/init.mjs +0 -25
  160. package/src/cli/lessons.mjs +51 -0
  161. package/src/cli/memory-plugin.mjs +1 -1
  162. package/src/cli/plugin/copies.mjs +64 -14
  163. package/src/cli/plugin/create.mjs +6 -7
  164. package/src/cli/plugin/index.mjs +11 -7
  165. package/src/cli/plugin/install.mjs +10 -15
  166. package/src/cli/plugin/remove.mjs +1 -1
  167. package/src/cli/plugin/search.mjs +2 -2
  168. package/src/cli/preflight.mjs +19 -6
  169. package/src/cli/proposals.mjs +1 -1
  170. package/src/cli/recall.mjs +66 -23
  171. package/src/cli/release.mjs +4 -1
  172. package/src/cli/remember.mjs +3 -14
  173. package/src/cli/server.mjs +18 -0
  174. package/src/cli/startup.mjs +1 -0
  175. package/src/cli/task.mjs +9 -2
  176. package/src/cli/update.mjs +10 -3
  177. package/src/core/access-ledger.mjs +78 -0
  178. package/src/core/agent-manager.mjs +2 -2
  179. package/src/core/automatic-brain-updates.mjs +11 -6
  180. package/src/core/brain-locate.mjs +15 -0
  181. package/src/core/brain-updates.mjs +42 -12
  182. package/src/core/claude-hooks.mjs +3 -1
  183. package/src/core/cleanup-task.mjs +15 -0
  184. package/src/core/cli-commands.mjs +2 -0
  185. package/src/core/cli-maintenance.mjs +4 -1
  186. package/src/core/cli-semantic-index.mjs +23 -3
  187. package/src/core/context-compactor.mjs +7 -2
  188. package/src/core/context-compiler.mjs +26 -1
  189. package/src/core/context-policy.mjs +7 -3
  190. package/src/core/daemon-control.mjs +22 -0
  191. package/src/core/daemon-loop.mjs +39 -62
  192. package/src/core/default-plugins.mjs +1 -1
  193. package/src/core/dream.mjs +33 -105
  194. package/src/core/ensure-dependencies.mjs +148 -0
  195. package/src/core/fast-recall.mjs +2 -2
  196. package/src/core/field-evaluation.mjs +23 -0
  197. package/src/core/gate-mode.mjs +1 -1
  198. package/src/core/global-brain-updates.mjs +1 -1
  199. package/src/core/harness-hooks.mjs +14 -2
  200. package/src/core/lesson-hooks.mjs +74 -0
  201. package/src/core/lesson-memory.mjs +24 -0
  202. package/src/core/lesson-sessions.mjs +52 -0
  203. package/src/core/lessons.mjs +96 -0
  204. package/src/core/mesh-brain-updates.mjs +2 -1
  205. package/src/core/meta-harness.mjs +2 -2
  206. package/src/core/optimizer.mjs +66 -165
  207. package/src/core/plugin-contracts/card.mjs +3 -0
  208. package/src/core/plugin-loader.mjs +12 -3
  209. package/src/core/plugin-runtime.mjs +40 -1
  210. package/src/core/plugin-store.mjs +35 -23
  211. package/src/core/post-mortem.mjs +52 -36
  212. package/src/core/preflight-gate.mjs +23 -2
  213. package/src/core/proposal-applier.mjs +31 -2
  214. package/src/core/repo-sync.mjs +4 -6
  215. package/src/core/required-plugins.mjs +26 -4
  216. package/src/core/rule-length.mjs +23 -0
  217. package/src/core/runtime.mjs +1 -1
  218. package/src/core/scheduler.mjs +35 -43
  219. package/src/core/schema.mjs +1 -2
  220. package/src/core/search.mjs +4 -3
  221. package/src/core/server-restart.mjs +128 -7
  222. package/src/core/server-service.mjs +148 -0
  223. package/src/core/session-watcher.mjs +19 -1
  224. package/src/core/skill-gap.mjs +16 -0
  225. package/src/core/ssss-kernel-bridge.mjs +33 -6
  226. package/src/core/startup-health.mjs +6 -1
  227. package/src/core/surface.mjs +68 -57
  228. package/src/core/task-context.mjs +9 -8
  229. package/src/core/task-executors.mjs +54 -106
  230. package/src/core/validated-write.mjs +5 -0
  231. package/src/core/vault-files.mjs +8 -2
  232. package/src/core/vault.mjs +1 -1
  233. package/src/core/vector-field.mjs +134 -192
  234. package/src/server/index.mjs +3 -1
  235. package/src/server/invoke-core-child.mjs +24 -0
  236. package/src/server/invoke-core-operations.mjs +102 -0
  237. package/src/server/route-manifest.json +0 -56
  238. package/src/server/routes/brains.mjs +0 -18
  239. package/src/server/routes/context.mjs +0 -41
  240. package/src/server/routes/invoke.mjs +26 -1
  241. package/src/server/routes/ssss.mjs +0 -169
  242. package/src/server/routes/system.mjs +0 -15
  243. package/src/server/routes/tasks.mjs +0 -26
  244. package/src/server/routes/vault.mjs +2 -23
  245. package/frontend/dist/assets/index-DD4qONvH.js +0 -5607
  246. package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/README.md +0 -53
  247. package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/plugin.json +0 -129
  248. package/src/core/append-log.mjs +0 -131
  249. package/src/core/plugin-tasks.mjs +0 -173
  250. package/templates/onboarding-interview.md +0 -82
  251. /package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/LICENSE +0 -0
  252. /package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/ui/DESIGN.md +0 -0
@@ -1,8 +1,10 @@
1
- # Meta Harness
1
+ # Metaharness
2
2
 
3
- Built-in and validated custom adapters share one plugin. `runtime <agent> ...`
4
- exposes native runtime commands; DSH observations and Hermes gateway management
5
- live here as well. `meta-harness` is the primary namespace; `cli-agents` is an alias.
3
+ Built-in and validated custom adapters share one plugin. Use `dispatch` or
4
+ `route --execute` for agent work. `runtime <agent> ...` accepts supported maintenance
5
+ commands such as `codex login status`, `hermes gateway status`, and `dsh models`.
6
+ Manage gateway services through their owning plugins. `cli-agents` is an alias
7
+ for `meta-harness`.
6
8
 
7
9
  `total-recall cli-agents setup` connects all nine native instruction surfaces.
8
10
  The declared setup operation also runs during daemon-owned plugin refresh.
@@ -15,10 +17,12 @@ is removed after execution. Setup failure or an unready context stops dispatch.
15
17
  `docs-refresh`, `docs-ensure`, `docs-status`, `docs-read` and `docs-search` manage
16
18
  downloaded official documentation rather than a list of links. Content is hashed,
17
19
  bounded and refreshed after 24 hours. Maintenance uses the existing Total Recall
18
- daemon's plugin task, refreshing one stale adapter per run. Failed pages remain
20
+ daemon's plugin task, attempting every stale adapter per run. Failed pages remain
19
21
  visible as failures and cannot certify complete coverage; successful cached
20
22
  content remains readable. `setup --node <recorded-node>` selects maintenance
21
- placement without creating a second scheduler.
23
+ placement for `maintenance`, `maintenance --models` and `alerts check` without
24
+ creating a second scheduler. Each maintenance step reports its failures. A failed
25
+ setup or gate install does not prevent documentation refresh for other harnesses.
22
26
 
23
27
  Standalone Total Recall owner for CLI-agent discovery and explicit mesh command execution. Install with `total-recall plugin install <path-or-private-git-url>`. Installation rebuilds the plugin inventory, CLI library and connected instruction surfaces. No model account is created or selected automatically.
24
28
 
@@ -29,6 +33,21 @@ total-recall cli-agents inspect --node <recorded-node> --json
29
33
  total-recall cli-agents run-command --stdin --json < request.json
30
34
  ```
31
35
 
36
+ Check adoption without launching a model:
37
+
38
+ ```sh
39
+ total-recall meta-harness adoption --json
40
+ total-recall meta-harness adoption --node <recorded-node> --json
41
+ total-recall meta-harness adoption --all --json
42
+ ```
43
+
44
+ The report separates native login and hook configuration from recent hook
45
+ decisions and completed managed runs. Its run evidence is historical; use the
46
+ timestamps and last attempt to see whether an agent has since stopped working.
47
+ Native hook activity alone does not prove that an agent was launched through
48
+ Metaharness. A fleet report lists offline nodes, missing CLI access, and
49
+ installed versions that cannot provide adoption evidence.
50
+
32
51
  `request.json` selects one installed plugin operation, its literal arguments, a node and an agent:
33
52
 
34
53
  ```json
@@ -44,13 +63,29 @@ total-recall cli-agents run-command --stdin --json < request.json
44
63
  }
45
64
  ```
46
65
 
47
- For remote nodes, supply `execution.cwd` as an explicit absolute workspace. `agent: "direct"` runs the actual installed Total Recall CLI without a model. Remote access comes from recorded mesh entities and verified SSH configuration; unavailable nodes or binaries produce errors. Secrets are never accepted in an agent prompt. Existing account metadata is inspected without printing credentials or substituting provider API keys.
66
+ For remote nodes, supply `execution.cwd` as an explicit absolute workspace. `agent: "direct"` runs the actual installed Total Recall CLI without a model. A remote agent task enters the destination's installed Metaharness and records its receipt there. Remote access comes from recorded mesh entities and verified SSH configuration; unavailable nodes or binaries produce errors. Secrets are never accepted in an agent prompt. Existing account metadata is inspected without printing credentials or substituting provider API keys.
48
67
 
49
68
  The four permissions are strict boolean **command-effect admission controls**. They allow or deny the selected plugin command before dispatch. They are not a network policy or an OS sandbox for every action a model might propose. Supported adapter write modes are scoped through the vendor CLI; vendor approval and sandbox defaults stay enabled. The host's authenticated authorization still applies.
50
69
 
51
70
  The foreground `dispatch --stdin` request accepts `timeoutMs` from 1 to 540000, defaulting to 300000. Use the managed process or background execution commands for longer jobs. A Claude write request can include explicit `allowedTools` rules such as `["Bash(git status *)"]`. Native permission denials surface as failed dispatch receipts. Agent turn completion and command verification are separate fields.
52
71
 
53
- A completed model turn is distinct from a completed plugin operation. Structured results return `commandExecutionVerified: false` for agent turns; only direct CLI execution returns a command exit receipt. Muse preserves its actual headless JSONL log and documented process exit status rather than treating session-protocol notifications as headless output. Do not infer working accounts, provider delivery or successful mutations from discovery or fixture tests.
72
+ A native login probe reads account metadata. A headless request can still fail if the provider rejects that login. Signed-out and expired Claude subscription sessions produce a failed receipt with `failureKind: "auth"`. Renew the subscription sign-in on the dispatch node and retry a scoped dispatch to verify execution. See [Claude Code authentication](https://code.claude.com/docs/en/iam#renew-an-expiring-login).
73
+
74
+ ### Included usage
75
+
76
+ Run `total-recall meta-harness included-enforce` to limit this node's managed dispatches to included usage. Use `included-status --probe --json` to see the Claude billing bindings and read current Codex allowance without an agent turn. Codex uses the built-in ChatGPT route and requires the signed-in plan to report no paid credit.
77
+
78
+ To approve OpenRouter on this node, run `total-recall meta-harness openrouter-bind <harness> <auth-key-name> --model <openrouter-model-id> --json`. Then select that harness by name when dispatching. Automatic routing continues to choose from the included subscription pool.
79
+
80
+ Run `total-recall harness dispatch codex "Run pwd and report the output" --json` to see the final reply and `toolResults`. Codex, Claude, DSH, Pi, Hermes and OpenClaw report native tool outcomes, available exit codes and bounded output. OpenClaw reports `toolEvidenceError` if its gateway cannot return the run's tool results. For background jobs, run `total-recall meta-harness process logs <job-id> --json` and read `toolResults` in the completion record. Adoption receipts retain the outcomes without the output text.
81
+
82
+ For Claude Max, sign in on the execution host with `claude auth login --claudeai`. Check that Usage credits are off in the account's Usage settings. Pass `{"organization":"<orgId from claude auth status>","usageCreditsEnabled":false}` to `included-bind-claude-plan --stdin`. Metaharness prefers the bound plan and checks the native login on every turn. Keep Usage credits off on that account. Claude manages that switch and enforces the plan limits. [Claude's subscription and SDK billing](https://support.claude.com/en/articles/15036540-use-the-claude-agent-sdk-with-your-claude-plan)
83
+
84
+ Before using `included-bind-claude --stdin`, verify the Max credit grant, key hint and organization in Claude Console. Supply `keyName` (the Total Recall Auth entry), `organization`, the masked `keyHint`, `expiresAt`, `creditSource: "claude-max"`, `paidBalanceCents: 0` and false values for `autoReload`, `paymentMethod` and `invoiced`. The binding expires with the observed grant. Reverify after a key or billing change.
85
+
86
+ `usage-queue --json` lists deferred jobs. Use `usage-retry <id>` after the reported reset to run a replayable job through the same policy, or `usage-cancel <id>` to cancel it. Review a job marked `needsReview` in the original workspace before resubmitting it. A queued result has `queued: true` and a `queueId` and has not succeeded.
87
+
88
+ A completed model turn is distinct from a completed plugin operation. `commandExecutionVerified` requires a successful native shell result. Direct CLI execution returns the CLI process's exit receipt. Muse preserves its actual headless JSONL log and documented process exit status. Verify accounts, provider delivery and mutations through the real runtime.
54
89
 
55
90
  ## Primary contracts checked 2026-10-14
56
91
 
@@ -93,6 +128,20 @@ SSSS execution receipts. Actual process exit and finish metadata are distinct fr
93
128
  verification results; unavailable model metadata remains null. Thread operations
94
129
  include list, show, create, update, close and delete, using native SSSS state.
95
130
 
131
+ Every review result is stored in an append-only SSSS ledger beside the thread
132
+ store. It retains the selected diff, commit, reviewer, verdict and disposition,
133
+ including failed reviews and `NO_DIFF`. `reviews --json` reads the ledger.
134
+ Deleting a thread does not remove its reviews. A failed ledger write returns
135
+ `ok: false` with `reviewStoreError` and the completed result.
136
+
137
+ `learn` reports scorecards, walls and proposals from run receipts. Routing reads
138
+ these receipts directly. The memory emit option has been removed.
139
+
140
+ `threads cleanup-fixtures --dry-run` previews the one-time cleanup of exact test
141
+ fixture titles. `threads cleanup-fixtures` applies it and stores the removed IDs,
142
+ titles, statuses, source test files and retained IDs in the same SSSS operation.
143
+ Real end-to-end job threads stay in place, including failed attempts.
144
+
96
145
  Custom adapter declarations preserve scoped credentials, optional authentication
97
146
  probes and HTTPS documentation URLs. IDs and paths reject traversal and symbolic
98
147
  links. Credentials reach only the declaring runner through the auth store. A
@@ -115,14 +164,14 @@ The active five-file suite and evidence live in
115
164
  owner/core suites, plugin/scaffold validation, real dashboard inspection and
116
165
  recorded acceptance evidence. Fixture tests do not certify live accounts, remote
117
166
  execution or recurring maintenance. The operator requires completing verification
118
- before Meta Harness runs task work.
167
+ before Metaharness runs task work.
119
168
 
120
169
  Cloudroom setup material remains under `cloudroom/`. Its plugin implementation
121
170
  follows this foundation and requires its own current audit and plan.
122
171
 
123
172
  ### Installed and standalone verification
124
173
 
125
- Use the installed plugin for CLI execution and maintenance. The repository has a pure planning capability under `capability/`. The current manifest does not declare it for vendoring. See the [Meta Harness tracker](docs/projects/in-progress/META_HARNESS_UNIFICATION/META_HARNESS_UNIFICATION_PROJECT_TRACKER.md) for current package, execution and hook acceptance.
174
+ Use the installed plugin for CLI execution and maintenance. The repository has a pure planning capability under `capability/`. The current manifest does not declare it for vendoring. See the [Metaharness tracker](docs/projects/in-progress/META_HARNESS_UNIFICATION/META_HARNESS_UNIFICATION_PROJECT_TRACKER.md) for current package, execution and hook acceptance.
126
175
 
127
176
  ## Using this from an agent
128
177
 
@@ -1,4 +1,4 @@
1
- # Meta Harness Capability Brick
1
+ # Metaharness Capability Brick
2
2
 
3
3
  A zero-dependency, host-free pure ES module providing universal agent harness discovery, two-stage complexity classification, cost-vs-frontier routing, gate cascade evaluation, and execution envelope construction.
4
4
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Meta Harness Capability Brick
2
+ * Metaharness Capability Brick
3
3
  * Zero-dependency, host-free pure ES module for agent routing,
4
4
  * complexity classification, adapter discovery, gate cascades, and SSSS receipts.
5
5
  * Works identically in any standalone app, edge device, workstation, or cloud environment.
@@ -34,7 +34,7 @@ export const ADAPTER_CATALOG = {
34
34
  contextLimit: 200000,
35
35
  modalities: ['text', 'code'],
36
36
  features: ['subagents', 'mcp', 'headless', 'compact', 'plan_mode'],
37
- flags: { prompt: '-p', nonInteractive: '--permission-mode acceptEdits', planMode: '--permission-mode plan', output: '--output-format json' }
37
+ flags: { prompt: '-p', nonInteractive: '--permission-mode bypassPermissions', planMode: '--permission-mode plan', output: '--output-format json' }
38
38
  },
39
39
  codex: {
40
40
  id: 'codex',
@@ -49,7 +49,7 @@ export const ADAPTER_CATALOG = {
49
49
  contextLimit: 128000,
50
50
  modalities: ['text', 'code'],
51
51
  features: ['mcp', 'headless', 'streaming'],
52
- flags: { prompt: 'exec', nonInteractive: '--sandbox workspace-write', planMode: '--sandbox read-only', output: '--json' }
52
+ flags: { prompt: 'exec', nonInteractive: '--sandbox danger-full-access', planMode: '--sandbox read-only', output: '--json' }
53
53
  },
54
54
  grok: {
55
55
  id: 'grok',
@@ -256,15 +256,27 @@ export function classifyTaskComplexity(taskDescription, options = {}) {
256
256
  score += 30;
257
257
  factors.push('security-sensitive');
258
258
  }
259
- if (/multi-file|across (all|every)|entire (repo|fleet)|worktree/.test(text)) {
259
+ if (/multi-file|across (all|every)|entire (repo|fleet)|worktree|every (mesh )?(node|machine|host|repo)|(all|several|multiple) (repos|repositories|nodes|machines)|\bmesh\b|\bfleet\b/.test(text)) {
260
260
  score += 25;
261
261
  factors.push('broad-blast-radius');
262
262
  }
263
+ if (/\bproduction\b|\bdeploy|roll ?out|\bdroplet\b|\bcore\b|\bmigration\b|\brelease\b/.test(text)) {
264
+ score += 15;
265
+ factors.push('production-or-core');
266
+ }
263
267
  if (/benchmark|telemetry|concurrency|race condition|memory leak/.test(text)) {
264
268
  score += 20;
265
269
  factors.push('complex-debugging');
266
270
  }
267
- if (/typo|rename|docstring|comment|formatting|readme|lint fix/.test(text)) {
271
+ // Several distinct pieces of work (comma or semicolon separated clauses, phases) are not one edit.
272
+ const clauses = text.split(/[,;]|\band then\b|\bthen\b|\bplus\b/).filter(part => part.trim().split(/\s+/).length >= 3).length;
273
+ if (clauses >= 4 || /phases? \d+ (and|&) \d+/.test(text)) {
274
+ score += 15;
275
+ factors.push('multi-part-work');
276
+ }
277
+ // An easy-sounding word ("rename", "readme") lowers the score only when nothing else carries risk:
278
+ // a rename across repositories or a credential change is not a typo fix.
279
+ if (/typo|rename|docstring|comment|formatting|readme|lint fix/.test(text) && factors.length === 0) {
268
280
  score -= 30;
269
281
  factors.push('low-complexity-edit');
270
282
  }
@@ -645,7 +657,7 @@ export function decomposeTask(taskDescription, options = {}) {
645
657
  }
646
658
 
647
659
  /**
648
- * Meta Harness Brick Factory
660
+ * Metaharness Brick Factory
649
661
  */
650
662
  export function createMetaHarness(customAdapters = {}) {
651
663
  const mergedAdapters = { ...ADAPTER_CATALOG, ...customAdapters };
@@ -5,9 +5,11 @@ import { pathToFileURL } from 'node:url';
5
5
  import { configDir } from './src/paths.mjs';
6
6
  import { inspectAgents, getActiveAdapters, getCustomAdaptersDirs, loadCustomAdapters, validateCustomAdapter, adapterPath } from './src/worker.mjs';
7
7
  import { inspectNode, listTargets, executeCommand, executeOnNode } from './src/executor.mjs';
8
- import { DOC_SOURCES, documentationStatus, refreshDocumentation, ensureDocumentation, maintainDocumentation, readDocumentation, searchDocumentation } from './src/documentation.mjs';
9
- import { manageRuntime } from './src/runtime.mjs';
8
+ import { DOC_SOURCES, documentationStatus, refreshDocumentation, ensureDocumentation, readDocumentation, searchDocumentation } from './src/documentation.mjs';
9
+ import { manageRuntime, validateRuntimeOperation } from './src/runtime.mjs';
10
+ import { validateDispatchRequest } from './src/dispatch-request.mjs';
10
11
  import { setupIntegrations } from './src/setup.mjs';
12
+ import { maintainIntegrations } from './src/maintenance.mjs';
11
13
  import { inspectUpstreamFleet, getAgentChangelog } from './src/tracker.mjs';
12
14
  import { inspectQuotas, getBenchmarks, routeTask } from './src/router.mjs';
13
15
  import { coordinateTask } from './src/coordinator.mjs';
@@ -17,11 +19,17 @@ import { resolvePool } from './src/pool.mjs';
17
19
  import { checkAlerts, notifyAlert } from './src/alerts.mjs';
18
20
  import { learnFromHistory, voidReceipts } from './src/learner.mjs';
19
21
  import { decomposeTask } from './capability/index.mjs';
20
- import { listThreads, getThread, createThread, updateThread, closeThread, deleteThread } from './src/threads.mjs';
22
+ import { listThreads, getThread, createThread, updateThread, closeThread, deleteThread, cleanupFixtureThreads } from './src/threads.mjs';
23
+ import { readReviews } from './src/reviews.mjs';
21
24
  import { executeCodeReview } from './src/review.mjs';
22
- import { stopOnTermination } from './src/termination.mjs';
25
+ import { stopOnTermination, finishCancellation } from './src/termination.mjs';
26
+ import { cancellationResult } from './src/worker.mjs';
27
+ import { startJob, newJobId, cancelJob, resolveJob } from './src/jobs.mjs';
28
+ import { appendCommand, waitingRequests } from './src/control.mjs';
29
+ import { sessionOptions } from './src/session/run.mjs';
30
+ import { continueJob } from './src/session-jobs.mjs';
23
31
 
24
- const VALUE_FLAGS = ['--node', '--mode', '--orchestrator', '--branch', '--reviewer', '--thread', '--status', '--platform', '--agent', '--url', '--query', '--tier', '--threshold', '--author', '--explorer', '--architect', '--implementer', '--verifier', '--title', '--summary', '--cwd', '--tools', '--setting-sources', '--model', '--name', '--tail', '--timeout-ms', '--void', '--reason'];
32
+ const VALUE_FLAGS = ['--result-schema-json', '--goal', '--max-turns', '--max-budget-usd', '--max-tokens', '--result-schema', '--at', '--node', '--mode', '--orchestrator', '--branch', '--reviewer', '--thread', '--status', '--platform', '--agent', '--url', '--query', '--tier', '--threshold', '--author', '--explorer', '--architect', '--implementer', '--verifier', '--title', '--summary', '--cwd', '--tools', '--setting-sources', '--model', '--name', '--tail', '--timeout-ms', '--void', '--reason', '--approvals', '--question-timeout-ms'];
25
33
  export function parseArguments(args) {
26
34
  const positional = [];
27
35
  for (let index = 1; index < args.length; index += 1) {
@@ -37,30 +45,68 @@ export function parseArguments(args) {
37
45
  return { positional, value, has: name => args.includes(name) };
38
46
  }
39
47
 
40
- export async function run(argv = []) {
48
+ export async function run(argv = [], { backgroundJobId } = {}) {
49
+ // MCP owns stdin/stdout for its whole lifetime. The CLI result wrapper must stay out of that stream.
50
+ if (argv[3] === 'mcp' && !argv.includes('--help') && !argv.includes('-h')) {
51
+ try { await runOperation(argv); }
52
+ catch (error) { console.error(`Metaharness MCP: ${error.message}`); process.exitCode = 1; }
53
+ return;
54
+ }
41
55
  stopOnTermination();
42
- try { await runOperation(argv); }
56
+ let job, result;
57
+ const previousJob = process.env.TR_METAHARNESS_JOB;
58
+ try {
59
+ const args = argv.slice(3), operation = args[0];
60
+ if (!args.includes('--help') && !args.includes('-h') && !args.includes('--background') &&
61
+ (['dispatch', 'fork', 'resume'].includes(operation) || (['route', 'coordinate', 'orchestrate'].includes(operation) && args.includes('--execute')))) {
62
+ job = startJob(operation, backgroundJobId ? { id: backgroundJobId } : {});
63
+ process.env.TR_METAHARNESS_JOB = job.job;
64
+ }
65
+ result = await runOperation(argv);
66
+ }
43
67
  catch (error) {
44
68
  const message = String(error?.message || error);
45
- if (argv.includes('--json')) console.log(JSON.stringify({ ok: false, error: message }));
46
- else console.error(`meta-harness: ${message}`);
69
+ result = { ok: false, error: message };
70
+ if (!argv.includes('--json')) console.error(`meta-harness: ${message}`);
47
71
  process.exitCode = 1;
48
72
  }
73
+ result = finishCancellation(result);
74
+ if (result !== undefined) {
75
+ if (job) {
76
+ if (result.execution?.remote && result.job) result.execution = { ...result.execution, remoteJob: result.job };
77
+ result = { ...result, job: job.job };
78
+ }
79
+ job?.finish(result);
80
+ if (!backgroundJobId) console.log(JSON.stringify(result));
81
+ }
82
+ if (previousJob === undefined) delete process.env.TR_METAHARNESS_JOB;
83
+ else process.env.TR_METAHARNESS_JOB = previousJob;
49
84
  }
50
85
 
51
86
  /** The host stops a plugin command after 10 minutes, so long runs detach and report through their thread and log. */
52
87
  async function detachRun(argv) {
53
88
  const directory = path.join(configDir(), 'jobs');
54
89
  fs.mkdirSync(directory, { recursive: true, mode: 0o700 });
55
- const log = path.join(directory, `${Date.now().toString(36)}.log`);
90
+ const id = newJobId();
91
+ const log = path.join(directory, `${id}.log`);
56
92
  const output = fs.openSync(log, 'a', 0o600);
57
93
  const entry = new URL('./cli.mjs', import.meta.url).href;
58
- const child = spawn(process.execPath, ['--input-type=module', '-e', `import(${JSON.stringify(entry)}).then(m=>m.run(${JSON.stringify(argv.filter(arg => arg !== '--background'))}))`], { cwd: process.cwd(), detached: true, stdio: ['ignore', output, output], env: process.env });
94
+ const input = argv[3] === 'dispatch' ? fs.readFileSync(0, 'utf8') : null;
95
+ const child = spawn(process.execPath, ['--input-type=module', '-e', `import(${JSON.stringify(entry)}).then(m=>m.run(${JSON.stringify(argv.filter(arg => arg !== '--background'))}, {backgroundJobId:${JSON.stringify(id)}}))`], { cwd: process.cwd(), detached: true, stdio: [input === null ? 'ignore' : 'pipe', output, output], env: process.env });
96
+ if (input !== null) { child.stdin.on('error', () => {}); child.stdin.end(input); }
59
97
  try {
60
98
  await new Promise((resolve, reject) => { child.once('spawn', resolve); child.once('error', reject); });
99
+ const deadline = Date.now() + 10_000;
100
+ while (!fs.statSync(log).size) {
101
+ if (child.exitCode !== null || Date.now() > deadline) {
102
+ child.kill('SIGTERM');
103
+ throw new Error(`The background job did not record its PID. Log: ${log}`);
104
+ }
105
+ await new Promise(resolve => setTimeout(resolve, 20));
106
+ }
61
107
  child.unref();
62
108
  } finally { fs.closeSync(output); }
63
- return { ok: true, background: true, pid: child.pid, log, follow: `The final JSON result is written to ${log}; a pipeline also records a thread.` };
109
+ return { ok: true, background: true, job: id, pid: child.pid, log, follow: `The final JSON result is written to ${log}; a pipeline also records a thread.` };
64
110
  }
65
111
 
66
112
  async function runOperation(argv) {
@@ -76,21 +122,57 @@ async function runOperation(argv) {
76
122
  // Help anywhere in the arguments prints usage; it must never run an operation.
77
123
  if (operation === 'help' || args.some(arg => arg === '--help' || arg === '-h')) {
78
124
  const manifest=JSON.parse(fs.readFileSync(new URL('./plugin.json',import.meta.url),'utf8'));
79
- console.log('Usage: total-recall meta-harness <operation> [options] (alias: cli-agents)\nEvery agent receives Total Recall bootstrap before dispatch. Runtime syntax: runtime <agent> <native-command...> [--node ID].\n');
125
+ console.log('Usage: total-recall meta-harness <operation> [options] (alias: cli-agents)\nEvery agent receives Total Recall bootstrap before dispatch. Runtime syntax: runtime <agent> <maintenance-command...> [--node ID].\n');
80
126
  for(const command of manifest.cli.subcommands)console.log(` ${command.name} ${(command.args || []).map(arg=>arg.flag?`${arg.flag} <${arg.name}>`:`<${arg.name}>`).join(' ')} — ${command.description}`);
81
127
  return;
82
128
  }
83
- if (has('--background') && ['route', 'coordinate', 'orchestrate'].includes(operation) && has('--execute')) { console.log(JSON.stringify(await detachRun(argv))); return; }
129
+ if (has('--background') && (['dispatch', 'fork', 'resume'].includes(operation) || (['route', 'coordinate', 'orchestrate'].includes(operation) && has('--execute')))) return detachRun(argv);
130
+ const controls = () => sessionOptions({ cwd: value('--cwd') || process.cwd(),
131
+ ...(value('--result-schema-json') !== undefined ? { resultSchema: JSON.parse(value('--result-schema-json')) } : {}),
132
+ ...Object.fromEntries([['goal', '--goal'], ['maxTurns', '--max-turns'], ['maxBudgetUsd', '--max-budget-usd'], ['maxTokens', '--max-tokens'],
133
+ ['resultSchema', '--result-schema'], ['approvalPolicy', '--approvals'], ['questionTimeoutMs', '--question-timeout-ms']]
134
+ .filter(([, flag]) => value(flag) !== undefined).map(([key, flag]) => [key, ['maxTurns', 'maxBudgetUsd', 'maxTokens', 'questionTimeoutMs'].includes(key) ? Number(value(flag)) : value(flag)])) });
84
135
  let result;
85
136
  if (operation === 'status') result = {...await inspectNode(value('--node') || 'local'),documentation:documentationStatus()};
86
137
  else if (operation === 'catalog') result = { adapters: getActiveAdapters(), permissions: ['read', 'write', 'send', 'destructive'] };
87
138
  else if (operation === 'nodes') result = await listTargets();
139
+ else if (operation === 'adoption') {
140
+ const node = value('--node');
141
+ if (node && has('--all')) throw new Error('Choose either --node or --all');
142
+ const { inspectLocalAdoption, inspectFleetAdoption } = await import('./src/adoption.mjs');
143
+ result = has('--all') || (node && node !== 'local') ? await inspectFleetAdoption({ node }) : await inspectLocalAdoption();
144
+ if (!result.ok) process.exitCode = 1;
145
+ }
88
146
  else if (operation === 'quota') result = await inspectQuotas({ node: value('--node') || 'local' });
147
+ else if (operation === 'openrouter-bind') {
148
+ const { bindOpenRouter } = await import('./src/included-usage.mjs');
149
+ result = await bindOpenRouter(positional[0], positional[1], value('--model'));
150
+ }
151
+ else if (['included-status', 'included-enforce', 'included-bind-claude', 'included-bind-claude-plan'].includes(operation)) {
152
+ const usage = await import('./src/included-usage.mjs');
153
+ if (operation === 'included-status') result = await usage.includedUsageStatus({ probe: has('--probe') });
154
+ else if (operation === 'included-enforce') result = await usage.enforceIncludedUsage();
155
+ else {
156
+ if (!has('--stdin')) throw new Error('Pass verified Claude billing evidence as JSON on stdin.');
157
+ const input = fs.readFileSync(0, 'utf8');
158
+ if (Buffer.byteLength(input) > 4096) throw new Error('Claude billing evidence is too large.');
159
+ const evidence = JSON.parse(input);
160
+ result = await (operation === 'included-bind-claude-plan' ? usage.bindClaudeMaxPlan : usage.bindClaudeIncludedKey)(evidence);
161
+ }
162
+ }
163
+ else if (['usage-queue', 'usage-retry', 'usage-cancel'].includes(operation)) {
164
+ const queue = await import('./src/usage-queue.mjs');
165
+ if (operation === 'usage-queue') result = { ok: true, jobs: await queue.listIncludedJobs() };
166
+ else if (!positional[0]) throw new Error('Choose a queued job ID.');
167
+ else if (operation === 'usage-cancel') result = { ok: true, job: await queue.cancelIncludedJob(positional[0]) };
168
+ else result = await queue.retryIncludedJob(positional[0]);
169
+ if (!result.ok) process.exitCode = 1;
170
+ }
89
171
  else if (operation === 'benchmarks') result = await getBenchmarks();
90
172
  else if (operation === 'route') {
91
173
  const task = positional.join(' ');
92
174
  if (!task) throw new Error('route requires a task description');
93
- const options = { jev: has('--jev'), preferLocal: has('--prefer-local'), preferFrontier: has('--prefer-frontier'), node: value('--node'), cwd: value('--cwd'), allowUnknownAuth: has('--allow-unknown-auth'), ...remoteTimeout() };
175
+ const options = { ...controls(), jev: has('--jev'), preferLocal: has('--prefer-local'), preferFrontier: has('--prefer-frontier'), node: value('--node'), cwd: value('--cwd'), allowUnknownAuth: has('--allow-unknown-auth'), ...remoteTimeout() };
94
176
  result = has('--execute') ? await executeRoutedTask(task, { ...options, gate: has('--gate'), gateOptions: { tier: value('--tier') || 'fast' } }) : await routeTask(task, options);
95
177
  if (!result.ok) process.exitCode = 1;
96
178
  }
@@ -104,7 +186,7 @@ async function runOperation(argv) {
104
186
  const task = positional.join(' ');
105
187
  if (!task) throw new Error(`${operation} requires a task description`);
106
188
  result = await coordinateTask(task, {
107
- mode: value('--mode') || 'pipeline', execute: has('--execute'), orchestrator: value('--orchestrator'), explorer: value('--explorer'), architect: value('--architect'), implementer: value('--implementer'), verifier: value('--verifier'),
189
+ ...controls(), mode: value('--mode') || 'pipeline', execute: has('--execute'), orchestrator: value('--orchestrator'), explorer: value('--explorer'), architect: value('--architect'), implementer: value('--implementer'), verifier: value('--verifier'),
108
190
  branch: value('--branch'), subagents: !has('--no-subagents'), autoReview: has('--auto-review'), gate: has('--gate'), gateOptions: { tier: value('--tier') || 'fast' }, allowSameFamily: has('--allow-same-family'), reviewer: value('--reviewer'),
109
191
  node: value('--node') || 'local', cwd: value('--cwd'), allowUnknownAuth: has('--allow-unknown-auth'), ...remoteTimeout(),
110
192
  });
@@ -119,6 +201,8 @@ async function runOperation(argv) {
119
201
  status: statusIdx >= 0 ? args[statusIdx + 1] : undefined,
120
202
  platform: platformIdx >= 0 ? args[platformIdx + 1] : undefined
121
203
  });
204
+ } else if (sub === 'cleanup-fixtures') {
205
+ result = cleanupFixtureThreads({ dryRun: has('--dry-run') });
122
206
  } else if (sub === 'show' || sub === 'get') {
123
207
  const id = args[2];
124
208
  if (!id) throw new Error('threads show requires a thread id');
@@ -149,14 +233,16 @@ async function runOperation(argv) {
149
233
  throw new Error(`Unsupported threads operation: ${sub}`);
150
234
  }
151
235
  }
236
+ else if (operation === 'reviews') result = { ok: true, reviews: readReviews() };
152
237
  else if (operation === 'review') {
153
238
  result = await executeCodeReview({ target: positional[0] || null, reviewer: value('--reviewer'), author: value('--author'), threadId: value('--thread'), staged: has('--staged'), node: value('--node') || 'local', cwd: value('--cwd'), allowUnknownAuth: has('--allow-unknown-auth'), ...remoteTimeout() });
154
239
  if (!result.ok) process.exitCode = 1;
155
240
  }
156
241
  else if (operation === 'learn') {
242
+ if (has('--emit')) throw new Error('learn --emit was removed. Routing reads run receipts directly.');
157
243
  result = value('--void') !== undefined
158
244
  ? await voidReceipts({ ids: String(value('--void')).split(',').map(id => id.trim()).filter(Boolean), reason: value('--reason') })
159
- : await learnFromHistory({ emit: has('--emit') });
245
+ : await learnFromHistory();
160
246
  if (!result.ok) process.exitCode = 1;
161
247
  }
162
248
  else if (operation === 'alerts') {
@@ -164,7 +250,7 @@ async function runOperation(argv) {
164
250
  if (sub === 'check') {
165
251
  const { quotas } = await inspectQuotas({});
166
252
  result = await checkAlerts({ quotas, threshold: Number(value('--threshold')) || 85, dryRun: has('--dry-run') });
167
- } else if (sub === 'test') result = await notifyAlert({ title: 'Meta Harness: test alert', message: 'Alert delivery check.', dryRun: has('--dry-run') });
253
+ } else if (sub === 'test') result = await notifyAlert({ title: 'Metaharness: test alert', message: 'Alert delivery check.', dryRun: has('--dry-run') });
168
254
  else throw new Error(`Unsupported alerts operation: ${sub}`);
169
255
  if (!result.ok) process.exitCode = 1;
170
256
  }
@@ -224,11 +310,7 @@ async function runOperation(argv) {
224
310
  const { syncModelCatalog } = await import('./src/model-catalog.mjs');
225
311
  result = await syncModelCatalog();
226
312
  } else {
227
- const setup=await setupIntegrations();
228
- const { installAll } = await import('./src/gate-adapters/index.mjs');
229
- const gates=await installAll();
230
- const docs=await maintainDocumentation(options);
231
- result={...docs,ok:docs.ok!==false&&gates.ok,setup,gates};
313
+ result=await maintainIntegrations(options);
232
314
  }
233
315
  } else result = operation==='docs-status' ? documentationStatus(options) : operation==='docs-ensure' ? await ensureDocumentation(options) : await refreshDocumentation(options);
234
316
  if(!result.ok)process.exitCode=1;
@@ -237,7 +319,8 @@ async function runOperation(argv) {
237
319
  const runtimeArgs=args.slice(1).filter(arg=>arg!=='--json'), agent=runtimeArgs.shift();
238
320
  const index=runtimeArgs.indexOf('--node'); let node='local';
239
321
  if(index>=0){node=runtimeArgs[index+1];if(!node || node.startsWith('-'))throw new Error('--node requires an identifier');runtimeArgs.splice(index,2);}
240
- result = node==='local' ? await manageRuntime(agent,runtimeArgs) : await executeOnNode(node,{operation:'direct',cwd:process.cwd(),argv:['total-recall','meta-harness','runtime',agent,...runtimeArgs,'--json']});
322
+ const command = validateRuntimeOperation(agent, runtimeArgs);
323
+ result = node==='local' ? await manageRuntime(agent,command) : await executeOnNode(node,{operation:'direct',useHome:true,argv:['total-recall','meta-harness','runtime',agent,...command,'--json']});
241
324
  if(!result.ok)process.exitCode=1;
242
325
  }
243
326
  else if (operation === 'process') {
@@ -263,13 +346,60 @@ async function runOperation(argv) {
263
346
  result = { ok: true, logs: await processes.getAgentLogs(target, Number(value('--tail') || 50)) };
264
347
  } else throw new Error(`Unsupported process operation: ${action}`);
265
348
  }
349
+ else if (operation === 'fork' || operation === 'resume') {
350
+ if (positional.length !== (operation === 'fork' ? 1 : 2)) throw new Error(`${operation} requires a job${operation === 'resume' ? ' and quoted text' : ''}.`);
351
+ result = await continueJob(positional[0], operation === 'fork' ? 'Continue from this session.' : positional[1], { fork: operation === 'fork', atTurn: value('--at') });
352
+ if (!result.ok) process.exitCode = 1;
353
+ }
354
+ else if (operation === 'cancel') {
355
+ result = await cancelJob(positional[0]);
356
+ }
357
+ else if (['reply', 'approve', 'interrupt', 'goal'].includes(operation)) {
358
+ if (!positional[0]) throw new Error(`${operation} requires a job ID.`);
359
+ if (positional.length !== (operation === 'approve' ? 3 : operation === 'interrupt' ? 1 : 2)) {
360
+ throw new Error(`${operation}: supply a job${operation === 'approve' ? ', request ID, and allow or deny' : operation === 'interrupt' ? '' : ' and quoted text'}.`);
361
+ }
362
+ result = await appendCommand(positional[0], { type: operation,
363
+ ...(operation === 'approve' ? { requestId: positional[1], value: positional[2] } : operation === 'interrupt' ? {} : { text: positional[1] }) },
364
+ { local: has('--local-delivery') });
365
+ }
366
+ else if (operation === 'mcp') {
367
+ const { runMcpServer, QUESTION_TIMEOUT_MS } = await import('./src/mcp-server.mjs');
368
+ await runMcpServer({ approvalPolicy: value('--approvals') || 'auto',
369
+ questionTimeoutMs: value('--question-timeout-ms') === undefined ? QUESTION_TIMEOUT_MS : Number(value('--question-timeout-ms')) });
370
+ return;
371
+ }
372
+ else if (operation === 'watch') {
373
+ // A-107: a dispatched agent's live status and latest events, by log path or job prefix.
374
+ const target = positional[0];
375
+ const jobs = path.join(configDir(), 'jobs');
376
+ let file = target && target.endsWith('.events.jsonl') ? path.resolve(target) : null;
377
+ if (target && !file) {
378
+ try {
379
+ const job = resolveJob(target);
380
+ const canonical = path.join(jobs, `${job.id}.events.jsonl`);
381
+ if (fs.existsSync(canonical)) file = canonical;
382
+ } catch (error) {
383
+ if (!error.message.startsWith('No job log matches')) throw error;
384
+ }
385
+ }
386
+ if (!file) {
387
+ const names = fs.existsSync(jobs) ? fs.readdirSync(jobs).filter(name => name.endsWith('.events.jsonl') && (!target || name.startsWith(target))) : [];
388
+ const newest = names.map(name => ({ name, at: fs.statSync(path.join(jobs, name)).mtimeMs })).sort((a, b) => b.at - a.at)[0];
389
+ if (!newest) throw new Error(target ? `No job log matches ${target}` : 'No dispatched job has a live log yet');
390
+ file = path.join(jobs, newest.name);
391
+ }
392
+ const { readProgress } = await import('./src/worker.mjs');
393
+ result = { ok: true, file, ...readProgress(file, Number(value('--tail') || 20)), waiting: waitingRequests(file) };
394
+ }
266
395
  else if(operation==='dispatch') {
267
396
  if(!args.includes('--stdin'))throw new Error('Task requests must arrive through stdin: pass --stdin with JSON {agent, cwd, prompt}');
268
397
  const input=fs.readFileSync(0,'utf8');if(Buffer.byteLength(input)>65536)throw new Error('Task request too large');
269
- const request=JSON.parse(input);
270
- const timeoutMs = request.timeoutMs ?? 300000;
271
- if (!Number.isInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 540000) throw new Error('Foreground dispatch timeout must be 1..540000 ms');
272
- result=await dispatchWithReceipt({...request,timeoutMs,allowUnknownAuth:request.allowUnknownAuth===true},{node:request.node || 'local',role:'Dispatch'});
398
+ const request=validateDispatchRequest({...JSON.parse(input),...controls()});
399
+ // A-107: a local dispatch streams its agent's events to a live log, announced before it starts.
400
+ const progressFile=(request.node||'local')==='local'?path.join(configDir(),'jobs',`${process.env.TR_METAHARNESS_JOB || `dispatch-${Date.now().toString(36)}-${request.agent}`}.events.jsonl`):undefined;
401
+ if(progressFile)console.error(JSON.stringify({progress:progressFile,agent:request.agent}));
402
+ result=await dispatchWithReceipt(progressFile?{...request,progressFile}:request,{node:request.node || 'local',role:'Dispatch',manageWrites:true});
273
403
  if(!result.ok)process.exitCode=1;
274
404
  }
275
405
  else if (operation === 'inspect') {
@@ -290,6 +420,7 @@ async function runOperation(argv) {
290
420
  result = await executeCommand({ ...request, plugin });
291
421
  if (!result.ok) process.exitCode = 1;
292
422
  } else throw new Error(`Unknown operation: ${operation}`);
293
- console.log(JSON.stringify(result));
423
+ if (cancellationResult()) process.exitCode = cancellationResult().exitCode;
424
+ return result;
294
425
  }
295
426
  export default run;
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "tr-plugin-meta-harness",
3
- "version": "0.3.4",
3
+ "version": "0.3.13",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "tr-plugin-meta-harness",
9
- "version": "0.3.4",
9
+ "version": "0.3.13",
10
10
  "dependencies": {
11
- "@gregiteen/ssss-cli": "0.14.4"
11
+ "@gregiteen/ssss-cli": "0.14.5"
12
12
  },
13
13
  "devDependencies": {
14
- "total-recall-brain": "3.42.1"
14
+ "total-recall-brain": "3.44.0"
15
15
  }
16
16
  },
17
17
  "node_modules/@alcalzone/ansi-tokenize": {
@@ -714,9 +714,9 @@
714
714
  "license": "MIT"
715
715
  },
716
716
  "node_modules/@gregiteen/ssss-cli": {
717
- "version": "0.14.4",
718
- "resolved": "https://registry.npmjs.org/@gregiteen/ssss-cli/-/ssss-cli-0.14.4.tgz",
719
- "integrity": "sha512-R6JIgPRvS9xXp0xb6BYO3rauv+72r35GIiDrJcvbjPdTSHFZXr8/jRxFOgoF8yTed/5xyGFF3ey3DI9bOjmHVA==",
717
+ "version": "0.14.5",
718
+ "resolved": "https://registry.npmjs.org/@gregiteen/ssss-cli/-/ssss-cli-0.14.5.tgz",
719
+ "integrity": "sha512-qVEYOocnwn97uJ0eDzmuwN06CYsYWr2t3+iKylpisBHX4wlLWk7P8EmFFdBlx7NyKVIZDDeYT164Gd7/T8UGgw==",
720
720
  "license": "ISC",
721
721
  "bin": {
722
722
  "ssss": "scripts/ssss.mjs"
@@ -1589,9 +1589,9 @@
1589
1589
  },
1590
1590
  "node_modules/@ssss/cli": {
1591
1591
  "name": "@gregiteen/ssss-cli",
1592
- "version": "0.14.4",
1593
- "resolved": "https://registry.npmjs.org/@gregiteen/ssss-cli/-/ssss-cli-0.14.4.tgz",
1594
- "integrity": "sha512-R6JIgPRvS9xXp0xb6BYO3rauv+72r35GIiDrJcvbjPdTSHFZXr8/jRxFOgoF8yTed/5xyGFF3ey3DI9bOjmHVA==",
1592
+ "version": "0.14.5",
1593
+ "resolved": "https://registry.npmjs.org/@gregiteen/ssss-cli/-/ssss-cli-0.14.5.tgz",
1594
+ "integrity": "sha512-qVEYOocnwn97uJ0eDzmuwN06CYsYWr2t3+iKylpisBHX4wlLWk7P8EmFFdBlx7NyKVIZDDeYT164Gd7/T8UGgw==",
1595
1595
  "dev": true,
1596
1596
  "license": "ISC",
1597
1597
  "bin": {
@@ -5546,9 +5546,9 @@
5546
5546
  }
5547
5547
  },
5548
5548
  "node_modules/total-recall-brain": {
5549
- "version": "3.42.1",
5550
- "resolved": "https://registry.npmjs.org/total-recall-brain/-/total-recall-brain-3.42.1.tgz",
5551
- "integrity": "sha512-woH7mdkGwPFYlKPZurhE8L3BPe+cSeIruNGaPOjGZJm/O8C92Bbr1gsdOY0tTLg5QHlgPHcXG1GMtsm9lPDz8w==",
5549
+ "version": "3.44.0",
5550
+ "resolved": "https://registry.npmjs.org/total-recall-brain/-/total-recall-brain-3.44.0.tgz",
5551
+ "integrity": "sha512-VNPaIO9zsSwoxAsJ5ByIQBP9zPpLq4RiQO7Vrex4rBOHFQJT50P7utcZiLMSZTyZJU4C/m5uB8qTCSBMp6+l6Q==",
5552
5552
  "dev": true,
5553
5553
  "license": "MIT",
5554
5554
  "workspaces": [
@@ -5556,7 +5556,7 @@
5556
5556
  ],
5557
5557
  "dependencies": {
5558
5558
  "@simplewebauthn/server": "^13.3.2",
5559
- "@ssss/cli": "npm:@gregiteen/ssss-cli@0.14.4",
5559
+ "@ssss/cli": "npm:@gregiteen/ssss-cli@0.14.5",
5560
5560
  "bcrypt": "^6.0.0",
5561
5561
  "better-sqlite3": "^12.11.1",
5562
5562
  "cookie-parser": "^1.4.7",
@@ -5579,6 +5579,7 @@
5579
5579
  "antigravity": "bin/antigravity.mjs",
5580
5580
  "total-recall": "bin/total-recall.mjs",
5581
5581
  "total-recall-memory": "bin/total-recall-memory.mjs",
5582
+ "total-recall-server-release": "bin/total-recall-server-release.mjs",
5582
5583
  "vibebrain": "bin/total-recall.mjs"
5583
5584
  },
5584
5585
  "optionalDependencies": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tr-plugin-meta-harness",
3
- "version": "0.3.4",
4
- "description": "Total Recall Meta Harness plugin",
3
+ "version": "0.3.13",
4
+ "description": "Total Recall Metaharness plugin",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "test": "node --import ./test/isolate.mjs --test test/*.test.mjs",
@@ -22,9 +22,9 @@
22
22
  "access": "public"
23
23
  },
24
24
  "dependencies": {
25
- "@gregiteen/ssss-cli": "0.14.4"
25
+ "@gregiteen/ssss-cli": "0.14.5"
26
26
  },
27
27
  "overrides": {
28
- "@ssss/cli": "npm:@gregiteen/ssss-cli@0.14.4"
28
+ "@ssss/cli": "npm:@gregiteen/ssss-cli@0.14.5"
29
29
  }
30
30
  }