moflo 4.10.24 → 4.10.25

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 (95) hide show
  1. package/.claude/guidance/shipped/moflo-yaml-reference.md +5 -5
  2. package/.claude/skills/meditate/SKILL.md +2 -2
  3. package/bin/cli-hooks/statusline.js +12 -8
  4. package/bin/cli.js +1 -1
  5. package/bin/hooks.mjs +1 -1
  6. package/bin/lib/meditate.mjs +1 -0
  7. package/bin/lib/pii-scrub.mjs +2 -5
  8. package/dist/src/cli/commands/daemon.js +4 -3
  9. package/dist/src/cli/commands/doctor-checks-deep.js +2 -2
  10. package/dist/src/cli/commands/doctor-checks-swarm.js +122 -13
  11. package/dist/src/cli/commands/hooks.js +7 -23
  12. package/dist/src/cli/commands/init.js +1 -1
  13. package/dist/src/cli/commands/mcp.js +2 -1
  14. package/dist/src/cli/commands/session.js +1 -1
  15. package/dist/src/cli/commands/start.js +1 -1
  16. package/dist/src/cli/commands/status.js +1 -1
  17. package/dist/src/cli/commands/task.js +1 -1
  18. package/dist/src/cli/commands/update.js +12 -12
  19. package/dist/src/cli/guidance/analyzer.js +3 -3
  20. package/dist/src/cli/guidance/gates.js +1 -1
  21. package/dist/src/cli/guidance/hooks.js +1 -1
  22. package/dist/src/cli/guidance/meta-governance.js +1 -1
  23. package/dist/src/cli/hooks/index.js +1 -1
  24. package/dist/src/cli/hooks/reasoningbank/guidance-provider.js +1 -1
  25. package/dist/src/cli/hooks/workers/index.js +1 -1
  26. package/dist/src/cli/hooks/workers/session-hook.js +0 -40
  27. package/dist/src/cli/index.js +2 -2
  28. package/dist/src/cli/init/executor.js +36 -20
  29. package/dist/src/cli/init/mcp-generator.js +10 -8
  30. package/dist/src/cli/init/settings-generator.js +10 -7
  31. package/dist/src/cli/init/types.js +2 -2
  32. package/dist/src/cli/mcp-server.js +2 -1
  33. package/dist/src/cli/memory/bridge-loader.js +42 -0
  34. package/dist/src/cli/memory/embedding-model.js +157 -0
  35. package/dist/src/cli/memory/entries-read.js +380 -0
  36. package/dist/src/cli/memory/entries-shared.js +73 -0
  37. package/dist/src/cli/memory/entries-write.js +384 -0
  38. package/dist/src/cli/memory/hnsw-singleton.js +242 -0
  39. package/dist/src/cli/memory/init.js +367 -0
  40. package/dist/src/cli/memory/learnings-overview.js +156 -0
  41. package/dist/src/cli/memory/memory-initializer.js +37 -2257
  42. package/dist/src/cli/memory/quantization.js +221 -0
  43. package/dist/src/cli/memory/schema.js +382 -0
  44. package/dist/src/cli/memory/verify.js +178 -0
  45. package/dist/src/cli/movector/index.js +1 -1
  46. package/dist/src/cli/plugins/store/discovery.js +9 -9
  47. package/dist/src/cli/{transfer/ipfs/client.js → plugins/store/ipfs-client.js} +4 -1
  48. package/dist/src/cli/plugins/tests/demo-plugin-store.js +1 -1
  49. package/dist/src/cli/plugins/tests/standalone-test.js +1 -1
  50. package/dist/src/cli/runtime/headless.js +5 -4
  51. package/dist/src/cli/scripts/publish-registry.js +6 -6
  52. package/dist/src/cli/services/daemon-dashboard.js +108 -7
  53. package/dist/src/cli/services/daemon-readiness.js +1 -1
  54. package/dist/src/cli/services/daemon-service.js +1 -1
  55. package/dist/src/cli/services/env-compat.js +29 -0
  56. package/dist/src/cli/services/hook-block-hash.js +5 -6
  57. package/dist/src/cli/services/registry-api.js +1 -1
  58. package/dist/src/cli/shared/core/config/loader.js +19 -11
  59. package/dist/src/cli/shared/events/example-usage.js +2 -2
  60. package/dist/src/cli/shared/events/index.js +1 -1
  61. package/dist/src/cli/shared/index.js +1 -1
  62. package/dist/src/cli/shared/mcp/index.js +1 -1
  63. package/dist/src/cli/shared/mcp/server.js +3 -3
  64. package/dist/src/cli/shared/plugin-interface.js +1 -1
  65. package/dist/src/cli/shared/plugins/index.js +1 -1
  66. package/dist/src/cli/shared/plugins/official/index.js +1 -1
  67. package/dist/src/cli/shared/security/index.js +1 -1
  68. package/dist/src/cli/shared/services/v3-progress.service.js +40 -29
  69. package/dist/src/cli/shared/types.js +1 -1
  70. package/dist/src/cli/swarm/coordination/swarm-hub.js +1 -1
  71. package/dist/src/cli/update/index.js +1 -1
  72. package/dist/src/cli/update/rate-limiter.js +3 -2
  73. package/dist/src/cli/version.js +1 -1
  74. package/package.json +2 -2
  75. package/dist/src/cli/commands/transfer-store.js +0 -428
  76. package/dist/src/cli/transfer/anonymization/index.js +0 -281
  77. package/dist/src/cli/transfer/deploy-seraphine.js +0 -205
  78. package/dist/src/cli/transfer/export.js +0 -113
  79. package/dist/src/cli/transfer/index.js +0 -31
  80. package/dist/src/cli/transfer/ipfs/upload.js +0 -411
  81. package/dist/src/cli/transfer/models/seraphine.js +0 -373
  82. package/dist/src/cli/transfer/serialization/cfp.js +0 -184
  83. package/dist/src/cli/transfer/storage/gcs.js +0 -242
  84. package/dist/src/cli/transfer/storage/index.js +0 -6
  85. package/dist/src/cli/transfer/store/discovery.js +0 -382
  86. package/dist/src/cli/transfer/store/download.js +0 -334
  87. package/dist/src/cli/transfer/store/index.js +0 -153
  88. package/dist/src/cli/transfer/store/publish.js +0 -294
  89. package/dist/src/cli/transfer/store/registry.js +0 -285
  90. package/dist/src/cli/transfer/store/search.js +0 -232
  91. package/dist/src/cli/transfer/store/tests/standalone-test.js +0 -190
  92. package/dist/src/cli/transfer/store/types.js +0 -6
  93. package/dist/src/cli/transfer/test-seraphine.js +0 -105
  94. package/dist/src/cli/transfer/tests/test-store.js +0 -214
  95. package/dist/src/cli/transfer/types.js +0 -6
@@ -164,17 +164,17 @@ Config is loaded from `moflo.yaml` at the project root — there is no env var t
164
164
 
165
165
  ```bash
166
166
  # Logging
167
- CLAUDE_FLOW_LOG_LEVEL=info # debug | info | warn | error
167
+ MOFLO_LOG_LEVEL=info # debug | info | warn | error
168
168
 
169
169
  # MCP Server (stdio transport — no port)
170
- CLAUDE_FLOW_MCP_TRANSPORT=stdio
170
+ MOFLO_MCP_TRANSPORT=stdio
171
171
 
172
172
  # Memory backend (legacy SystemConfig env vars — moflo.yaml `memory.backend` is the modern surface)
173
- CLAUDE_FLOW_MEMORY_BACKEND=sqlite # informational only; not consumed by selectProvider
174
- CLAUDE_FLOW_MEMORY_TYPE=sqlite # SystemConfig override (legacy)
173
+ MOFLO_MEMORY_BACKEND=sqlite # informational only; not consumed by selectProvider
174
+ MOFLO_MEMORY_TYPE=sqlite # SystemConfig override (legacy)
175
175
  ```
176
176
 
177
- Variable names retain the `CLAUDE_FLOW_` prefix for backward compatibility with consumers upgraded from claude-flow.
177
+ These use the canonical `MOFLO_` prefix. The pre-rebrand `CLAUDE_FLOW_` names are still read as a fallback for one deprecation cycle, so consumers upgraded from `claude-flow` keep working without a manual rename.
178
178
 
179
179
  ---
180
180
 
@@ -87,11 +87,11 @@ mcp__moflo__memory_store {
87
87
  namespace: "learnings",
88
88
  key: "<stable descriptive slug, e.g. pattern:daemon-port-resolver or gotcha:windows-spell-path>",
89
89
  value: "<the lesson> — Why: <why it matters>. How to apply: <what to do next time>.",
90
- tags: ["<topic>", "<area>"]
90
+ tags: ["<topic>", "<area>", "source:meditate-manual"]
91
91
  }
92
92
  ```
93
93
 
94
- Keep keys stable and descriptive so the next `/meditate` updates rather than re-adds. In `--preview` mode, **stop here** — print the candidates and their would-be keys/dedup verdicts, write nothing.
94
+ Always include the `source:meditate-manual` tag — it lets the Luminarium "Learnings" panel attribute each lesson to `/meditate` vs the automatic auto-meditate distill. Keep keys stable and descriptive so the next `/meditate` updates rather than re-adds. In `--preview` mode, **stop here** — print the candidates and their would-be keys/dedup verdicts, write nothing.
95
95
 
96
96
  ## Step 4 — Report
97
97
 
@@ -36,10 +36,10 @@ Usage:
36
36
  statusline --help Show this help
37
37
 
38
38
  Environment Variables:
39
- CLAUDE_FLOW_STATUSLINE_REFRESH Refresh interval in ms
40
- CLAUDE_FLOW_SHOW_HOOKS_METRICS Show hooks metrics (true/false)
41
- CLAUDE_FLOW_SHOW_SWARM_ACTIVITY Show swarm activity (true/false)
42
- CLAUDE_FLOW_SHOW_PERFORMANCE Show performance targets (true/false)
39
+ MOFLO_STATUSLINE_REFRESH Refresh interval in ms
40
+ MOFLO_SHOW_HOOKS_METRICS Show hooks metrics (true/false)
41
+ MOFLO_SHOW_SWARM_ACTIVITY Show swarm activity (true/false)
42
+ MOFLO_SHOW_PERFORMANCE Show performance targets (true/false)
43
43
 
44
44
  Examples:
45
45
  statusline # Display formatted status
@@ -49,13 +49,17 @@ Examples:
49
49
  process.exit(0);
50
50
  }
51
51
 
52
- // Create generator with environment-based config
52
+ // Create generator with environment-based config.
53
+ // #1209 — prefer MOFLO_* toggles, fall back to the pre-rebrand CLAUDE_FLOW_*
54
+ // names so consumers who set the old vars keep their statusline preferences.
55
+ const showEnv = (suffix) =>
56
+ process.env['MOFLO_' + suffix] ?? process.env['CLAUDE_' + 'FLOW_' + suffix];
53
57
  const generator = new StatuslineGenerator({
54
58
  enabled: true,
55
59
  refreshOnHook: true,
56
- showHooksMetrics: process.env.CLAUDE_FLOW_SHOW_HOOKS_METRICS !== 'false',
57
- showSwarmActivity: process.env.CLAUDE_FLOW_SHOW_SWARM_ACTIVITY !== 'false',
58
- showPerformance: process.env.CLAUDE_FLOW_SHOW_PERFORMANCE !== 'false',
60
+ showHooksMetrics: showEnv('SHOW_HOOKS_METRICS') !== 'false',
61
+ showSwarmActivity: showEnv('SHOW_SWARM_ACTIVITY') !== 'false',
62
+ showPerformance: showEnv('SHOW_PERFORMANCE') !== 'false',
59
63
  });
60
64
 
61
65
  // Try to read from metrics database or files
package/bin/cli.js CHANGED
@@ -2,7 +2,7 @@
2
2
  /**
3
3
  * @moflo/cli - CLI Entry Point
4
4
  *
5
- * Claude Flow V3 Command Line Interface
5
+ * MoFlo V3 Command Line Interface
6
6
  *
7
7
  * Auto-detects MCP mode when stdin is piped and no args provided.
8
8
  * This allows: echo '{"jsonrpc":"2.0",...}' | npx @moflo/cli
package/bin/hooks.mjs CHANGED
@@ -510,7 +510,7 @@ function runBackgroundTraining() {
510
510
  // Falls back to a naive kill(0) check if the import fails (e.g. dist not built).
511
511
  let _getDaemonLockHolder = null;
512
512
  try {
513
- const daemonLockPath = resolve(__dirname, '..', 'src', '@claude-flow', 'cli', 'dist', 'src', 'services', 'daemon-lock.js');
513
+ const daemonLockPath = resolve(projectRoot, 'node_modules/moflo/dist/src/cli/services/daemon-lock.js');
514
514
  if (existsSync(daemonLockPath)) {
515
515
  const mod = await import(pathToFileURL(daemonLockPath).href);
516
516
  _getDaemonLockHolder = mod.getDaemonLockHolder;
@@ -488,6 +488,7 @@ export function buildDistillPrompt(entries) {
488
488
  `1. For EACH candidate, call mcp__moflo__memory_search { namespace: "learnings", query: <bare keywords>, threshold: 0.6, limit: 5 }.`,
489
489
  `2. If the top hit is the SAME fact at similarity >= 0.80, call mcp__moflo__memory_store with that SAME key (upsert), merging any new nuance — do NOT create a near-duplicate.`,
490
490
  `3. Otherwise call mcp__moflo__memory_store { namespace: "learnings", key: <stable descriptive slug>, value: "<lesson> — Why: <why it matters>. How to apply: <what to do next time>.", tags: [<topic>, <area>] }.`,
491
+ ` PROVENANCE (#1203): every memory_store you make — both the step-2 upsert and the step-3 new write — MUST include the tag "source:auto-meditate" in its tags array, so the Luminarium "Learnings" panel can attribute these to the automatic distill pass.`,
491
492
  `4. Skip any candidate that does not clear the durability bar below, or that merely restates an existing entry.`,
492
493
  ``,
493
494
  DURABILITY_BAR,
@@ -1,17 +1,14 @@
1
1
  /**
2
2
  * Credential / secret scrubber for the session-continuity persist path (#1185).
3
3
  *
4
- * THREAT MODEL — this is deliberately NOT the transfer/anonymization pipeline
5
- * (`src/cli/transfer/anonymization/index.ts`). That module makes a CFP safe to
6
- * publish *externally* (aggressive, lossy, deterministic pseudonymisation of
7
- * emails / home paths / IPs). This module has a narrower job: a session digest
4
+ * THREAT MODEL — this scrubber has a deliberately narrow job: a session digest
8
5
  * is written to the user's OWN local `.moflo/moflo.db`, so the only thing we
9
6
  * must never persist is a literal *secret* that happened to appear in the
10
7
  * session (an API key, a JWT, a private-key block). We intentionally KEEP
11
8
  * benign context like file paths and branch names — they're the whole point of
12
9
  * a "where you left off" digest and are not sensitive on the user's own disk.
13
10
  *
14
- * Two different purposes two focused scrubbers, not one over-coupled one.
11
+ * Scope is intentionally minimal: persist useful context, never persist secrets.
15
12
  *
16
13
  * Pure + synchronous + dependency-free so a bin/*.mjs hook can call it on the
17
14
  * hot path without loading a model. Cross-platform (Rule #1): plain regex, no
@@ -14,6 +14,7 @@ import { spawn, execFileSync } from 'child_process';
14
14
  import { join, resolve } from 'path';
15
15
  import * as fs from 'fs';
16
16
  import { errorDetail } from '../shared/utils/error-detail.js';
17
+ import { readMofloEnv } from '../services/env-compat.js';
17
18
  /**
18
19
  * Resolve the dashboard port from CLI flag and env, in that precedence order.
19
20
  *
@@ -68,7 +69,7 @@ const startCommand = {
68
69
  const noDashboard = ctx.flags.noDashboard;
69
70
  const rawDashboardPort = ctx.flags.dashboardPort;
70
71
  const projectRoot = process.cwd();
71
- const isDaemonProcess = process.env.CLAUDE_FLOW_DAEMON === '1';
72
+ const isDaemonProcess = readMofloEnv('DAEMON') === '1';
72
73
  // Resolve dashboard port; see `resolveDashboardPort` for precedence.
73
74
  const portResult = resolveDashboardPort(rawDashboardPort, process.env.MOFLO_DAEMON_PORT);
74
75
  if (!portResult.ok) {
@@ -125,7 +126,7 @@ const startCommand = {
125
126
  // below).
126
127
  process.env.MOFLO_IS_DAEMON = '1';
127
128
  // Acquire atomic daemon lock (prevents duplicate daemons).
128
- // Always acquire here — even when spawned as a child (CLAUDE_FLOW_DAEMON=1)
129
+ // Always acquire here — even when spawned as a child (MOFLO_DAEMON=1)
129
130
  // because on Windows the parent's child.pid is the shell PID (cmd.exe),
130
131
  // not the actual node process. The child must write its own real PID.
131
132
  const lockResult = acquireDaemonLock(projectRoot);
@@ -373,7 +374,7 @@ async function startBackgroundDaemon(projectRoot, quiet, maxCpuLoad, minFreeMemo
373
374
  }
374
375
  const daemonEnv = {
375
376
  ...process.env,
376
- CLAUDE_FLOW_DAEMON: '1',
377
+ MOFLO_DAEMON: '1',
377
378
  // #981 — daemon process must skip its own write-routing client.
378
379
  MOFLO_IS_DAEMON: '1',
379
380
  // Prevent macOS SIGHUP kill when terminal closes
@@ -632,7 +632,7 @@ export async function checkHookBlockDrift() {
632
632
  return {
633
633
  name: 'Hook Block Drift',
634
634
  status: 'pass',
635
- message: 'drift check skipped — claudeFlow.hooks.locked: true',
635
+ message: 'drift check skipped — moflo.hooks.locked: true',
636
636
  };
637
637
  }
638
638
  // #896: respect `auto_update.hook_block_drift: off` — opt-out for consumers
@@ -667,7 +667,7 @@ export async function checkHookBlockDrift() {
667
667
  name: 'Hook Block Drift',
668
668
  status: 'warn',
669
669
  message: parts.join(', '),
670
- fix: 'set auto_update.hook_block_drift: regenerate in moflo.yaml, or claudeFlow.hooks.locked: true to suppress',
670
+ fix: 'set auto_update.hook_block_drift: regenerate in moflo.yaml, or moflo.hooks.locked: true to suppress',
671
671
  };
672
672
  }
673
673
  // ============================================================================
@@ -11,6 +11,7 @@
11
11
  * moflo package root via `import.meta.url`, so checks behave identically in
12
12
  * the dev tree and in `node_modules/moflo/...` consumer installs.
13
13
  */
14
+ import { errorDetail } from '../shared/utils/error-detail.js';
14
15
  import { loadToolArrays, getTool, safeInvoke, summarizeFunctional, } from './doctor-checks-functional-shared.js';
15
16
  const SWARM_FUNCTIONAL_CHECK = 'Swarm Functional';
16
17
  const HIVE_FUNCTIONAL_CHECK = 'Hive-Mind Functional';
@@ -202,6 +203,120 @@ export async function checkSwarmFunctional() {
202
203
  return summarize(SWARM_FUNCTIONAL_CHECK, details);
203
204
  }
204
205
  // ============================================================================
206
+ // Hive-Mind write-through propagation race (#1206)
207
+ // ============================================================================
208
+ /**
209
+ * Standard bounded backoff (ms) for the `hive-mind_memory` set→get
210
+ * write-through propagation retry. Same budget as the project-wide transient
211
+ * retry pattern (see `feedback_transient_retry_circuit_breaker.md`).
212
+ */
213
+ const HIVE_MEMORY_GET_RETRY_DELAYS_MS = [50, 200, 800];
214
+ const backoffSleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
215
+ const HIVE_MEMORY_GET_META = {
216
+ id: 'hive-mind_memory.get',
217
+ mcpTool: 'hive-mind_memory',
218
+ expected: 'memory get returns previously-set value (proves shared store, not in-memory only)',
219
+ };
220
+ /**
221
+ * #1206: probe `hive-mind_memory` get after a successful set, tolerating async
222
+ * write-through propagation lag. Mirrors the #1111/#1120 fix on the
223
+ * `Memory Access Functional` check: an immediate `exists=false` right after a
224
+ * successful set is most often a propagation race (slow disk / fork contention
225
+ * / 429-throttled cold start on a stressed CI runner), not a genuine
226
+ * write-through break.
227
+ *
228
+ * Classification:
229
+ * - `exists=true` + matching sentinel on the first read → **pass**.
230
+ * - `exists=false` (or a transient throw) → **retry** with bounded backoff
231
+ * (50/200/800ms). A late landing → **warn** (write-through works, just
232
+ * lagged). Budget exhausted with no landing → **fail** (a real
233
+ * write-through break is a protected-surface regression and MUST stay a
234
+ * hard fail — ⛔ swarm/hive-mind rule; never hide a real disconnect).
235
+ * - `exists=true` + wrong sentinel → **fail** immediately, no retries: a
236
+ * value clobber is a real bug, not a propagation race.
237
+ *
238
+ * `opts` injects the backoff schedule + sleep so the regression test exercises
239
+ * the classification without real delays.
240
+ */
241
+ async function probeHiveMemoryGet(hiveMindTools, probeKey, sentinel, details, opts) {
242
+ const tool = getTool(hiveMindTools, 'hive-mind_memory');
243
+ if (!tool?.handler) {
244
+ details.push({
245
+ ...HIVE_MEMORY_GET_META, status: 'fail',
246
+ observed: { reason: 'tool-not-registered' },
247
+ message: 'MCP tool "hive-mind_memory" not registered in the loaded tool array',
248
+ });
249
+ return;
250
+ }
251
+ const handler = tool.handler;
252
+ const delays = opts?.delaysMs ?? HIVE_MEMORY_GET_RETRY_DELAYS_MS;
253
+ const sleep = opts?.sleep ?? backoffSleep;
254
+ const getOnce = async () => {
255
+ try {
256
+ const raw = (await handler({ action: 'get', key: probeKey }));
257
+ if (!raw?.exists)
258
+ return { kind: 'missing' };
259
+ if (raw.value?.sentinel !== sentinel) {
260
+ return { kind: 'mismatch', message: `value mismatch: expected sentinel="${sentinel}", got ${JSON.stringify(raw.value)}` };
261
+ }
262
+ return { kind: 'landed' };
263
+ }
264
+ catch (err) {
265
+ return { kind: 'threw', message: errorDetail(err, { firstLineOnly: true }) };
266
+ }
267
+ };
268
+ let attempts = 1;
269
+ let result = await getOnce();
270
+ if (result.kind === 'landed') {
271
+ details.push({ ...HIVE_MEMORY_GET_META, status: 'pass', observed: { exists: true, attempts } });
272
+ return;
273
+ }
274
+ if (result.kind === 'mismatch') {
275
+ details.push({ ...HIVE_MEMORY_GET_META, status: 'fail', observed: { exists: true, attempts }, message: result.message });
276
+ return;
277
+ }
278
+ // exists=false (or a transient throw) — retry with bounded backoff to absorb
279
+ // async write-through propagation lag.
280
+ for (const delay of delays) {
281
+ await sleep(delay);
282
+ result = await getOnce();
283
+ attempts++;
284
+ if (result.kind === 'landed') {
285
+ const retries = attempts - 1;
286
+ details.push({
287
+ ...HIVE_MEMORY_GET_META, status: 'warn',
288
+ observed: { exists: true, attempts, retriedAfterMs: delays.slice(0, retries) },
289
+ message: `hive-mind write-through propagation race — get returned exists=false immediately after a successful set, but the value landed after ${retries} bounded retr${retries === 1 ? 'y' : 'ies'} (write-through works, propagation just lagged; expected under slow disk / fork contention / throttled cold start on a stressed runner)`,
290
+ });
291
+ return;
292
+ }
293
+ if (result.kind === 'mismatch') {
294
+ details.push({ ...HIVE_MEMORY_GET_META, status: 'fail', observed: { exists: true, attempts }, message: result.message });
295
+ return;
296
+ }
297
+ }
298
+ // Budget exhausted and the value never landed — a genuine write-through break
299
+ // is a protected-surface regression and must stay a hard fail. The threw case
300
+ // never observed an `exists` value, so don't report a misleading exists=false.
301
+ const message = result.kind === 'threw'
302
+ ? `get threw on every attempt over ${attempts} tries (last: ${result.message})`
303
+ : `get returned exists=false after a successful set and ${attempts} bounded attempts — write-through to Memory DB is broken`;
304
+ const observed = result.kind === 'threw'
305
+ ? { threw: true, attempts }
306
+ : { exists: false, attempts };
307
+ details.push({ ...HIVE_MEMORY_GET_META, status: 'fail', observed, message });
308
+ }
309
+ /**
310
+ * #1206 regression-test seam. Drives {@link probeHiveMemoryGet} with a
311
+ * synthetic `hiveMindTools` array and an injectable sleep so the test
312
+ * exercises the bounded-retry → warn/fail/pass classification without real
313
+ * backoff delays. Not part of the public doctor surface — real callers use
314
+ * {@link checkHiveMindFunctional}.
315
+ */
316
+ export async function _probeHiveMemoryGetForTest(hiveMindTools, probeKey, sentinel, details, opts) {
317
+ return probeHiveMemoryGet(hiveMindTools, probeKey, sentinel, details, opts);
318
+ }
319
+ // ============================================================================
205
320
  // Hive-Mind Functional Check
206
321
  // ============================================================================
207
322
  export async function checkHiveMindFunctional() {
@@ -338,19 +453,13 @@ export async function checkHiveMindFunctional() {
338
453
  assert: () => null,
339
454
  });
340
455
  if (setOut?.success === true) {
341
- await safeInvoke(hiveMindTools, 'hive-mind_memory', { action: 'get', key: probeKey }, details, {
342
- id: 'hive-mind_memory.get',
343
- mcpTool: 'hive-mind_memory',
344
- expected: 'memory get returns previously-set value (proves shared store, not in-memory only)',
345
- assert: (raw) => {
346
- const out = raw;
347
- if (!out?.exists)
348
- return 'get returned exists=false after a successful set — write-through to Memory DB is broken';
349
- if (out.value?.sentinel !== sentinel)
350
- return `value mismatch: expected sentinel="${sentinel}", got ${JSON.stringify(out.value)}`;
351
- return null;
352
- },
353
- });
456
+ // #1206: a get returning exists=false immediately after a successful set is
457
+ // most often async write-through propagation lag, not a genuine
458
+ // write-through break (mirrors the #1111/#1120 fix on Memory Access).
459
+ // Retry with bounded backoff: a late landing demotes to warn; never
460
+ // landing stays a hard fail ( a real write-through break is a
461
+ // protected-surface regression and must not be hidden).
462
+ await probeHiveMemoryGet(hiveMindTools, probeKey, sentinel, details);
354
463
  }
355
464
  // 7. Cleanup — graceful shutdown (best-effort; failures here aren't a regression signal).
356
465
  try {
@@ -6,7 +6,6 @@ import { output } from '../output.js';
6
6
  import { formatStatus } from '../services/cli-formatters.js';
7
7
  import { confirm } from '../prompt.js';
8
8
  import { callMCPTool, MCPClientError } from '../mcp-client.js';
9
- import { storeCommand } from './transfer-store.js';
10
9
  import { memoryDbCandidatePaths } from '../services/moflo-paths.js';
11
10
  import { errorDetail } from '../shared/utils/error-detail.js';
12
11
  // Hook types
@@ -851,8 +850,6 @@ const metricsCommand = {
851
850
  }
852
851
  }
853
852
  };
854
- // Pattern Store command (imported from transfer-store.ts)
855
- // storeCommand is imported at the top
856
853
  // Transfer from project subcommand
857
854
  const transferFromProjectCommand = {
858
855
  name: 'from-project',
@@ -951,38 +948,25 @@ const transferFromProjectCommand = {
951
948
  }
952
949
  }
953
950
  };
954
- // Parent transfer command combining all transfer methods
951
+ // Parent transfer command for local pattern transfer
955
952
  const transferCommand = {
956
953
  name: 'transfer',
957
- description: 'Transfer patterns and plugins via IPFS-based decentralized registry',
958
- subcommands: [storeCommand, transferFromProjectCommand],
954
+ description: 'Transfer learned patterns from another local project',
955
+ subcommands: [transferFromProjectCommand],
959
956
  examples: [
960
- { command: 'flo hooks transfer store list', description: 'List patterns from registry' },
961
- { command: 'flo hooks transfer store search -q routing', description: 'Search patterns' },
962
- { command: 'flo hooks transfer store download -p seraphine-genesis', description: 'Download pattern' },
963
- { command: 'flo hooks transfer store publish', description: 'Publish pattern to registry' },
964
- { command: 'flo hooks transfer from-project -s ../other-project', description: 'Transfer from project' },
957
+ { command: 'flo hooks transfer from-project -s ../other-project', description: 'Transfer patterns from another project' },
958
+ { command: 'flo hooks transfer from-project -s ../prod --filter security -m 0.9', description: 'Transfer high-confidence security patterns' },
965
959
  ],
966
960
  action: async () => {
967
961
  output.writeln();
968
- output.writeln(output.bold('Pattern Transfer System'));
969
- output.writeln(output.dim('Decentralized pattern sharing via IPFS'));
962
+ output.writeln(output.bold('Pattern Transfer'));
963
+ output.writeln(output.dim('Copy learned patterns from another local moflo project'));
970
964
  output.writeln();
971
965
  output.writeln('Subcommands:');
972
966
  output.printList([
973
- `${output.highlight('store')} - Pattern marketplace (list, search, download, publish)`,
974
967
  `${output.highlight('from-project')} - Transfer patterns from another project`,
975
968
  ]);
976
969
  output.writeln();
977
- output.writeln(output.bold('IPFS-Based Features:'));
978
- output.printList([
979
- 'Decentralized registry via IPNS for discoverability',
980
- 'Content-addressed storage for integrity',
981
- 'Ed25519 signatures for verification',
982
- 'Anonymization levels: minimal, standard, strict, paranoid',
983
- 'Trust levels: unverified, community, verified, official',
984
- ]);
985
- output.writeln();
986
970
  output.writeln('Run "flo hooks transfer <subcommand> --help" for details');
987
971
  return { success: true };
988
972
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * V3 CLI Init Command
3
- * Comprehensive initialization for Claude Flow with Claude Code integration
3
+ * Comprehensive initialization for MoFlo with Claude Code integration
4
4
  */
5
5
  import { output } from '../output.js';
6
6
  import { confirm, select, multiSelect, input } from '../prompt.js';
@@ -10,6 +10,7 @@ import { confirm } from '../prompt.js';
10
10
  import { getServerManager, getMCPServerStatus, } from '../mcp-server.js';
11
11
  import { listMCPTools, callMCPTool, hasTool } from '../mcp-client.js';
12
12
  import { acquireDaemonLock, releaseDaemonLock, getDaemonLockHolder } from '../services/daemon-lock.js';
13
+ import { readMofloEnv } from '../services/env-compat.js';
13
14
  // MCP tools categories
14
15
  const TOOL_CATEGORIES = [
15
16
  { value: 'coordination', label: 'Coordination', hint: 'Swarm and agent coordination tools' },
@@ -229,7 +230,7 @@ const statusCommand = {
229
230
  // If PID-based check says not running, detect stdio mode
230
231
  if (!status.running) {
231
232
  const isStdio = !process.stdin.isTTY;
232
- const envTransport = process.env.CLAUDE_FLOW_MCP_TRANSPORT;
233
+ const envTransport = readMofloEnv('MCP_TRANSPORT');
233
234
  if (isStdio || envTransport === 'stdio') {
234
235
  status = {
235
236
  running: true,
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * V3 CLI Session Command
3
- * Session management for Claude Flow
3
+ * Session management for MoFlo
4
4
  */
5
5
  import { output } from '../output.js';
6
6
  import { formatStatus } from '../services/cli-formatters.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * V3 CLI Start Command
3
- * System startup for Claude Flow orchestration
3
+ * System startup for MoFlo orchestration
4
4
  */
5
5
  import { output } from '../output.js';
6
6
  import { confirm } from '../prompt.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * V3 CLI Status Command
3
- * System status display for Claude Flow
3
+ * System status display for MoFlo
4
4
  */
5
5
  import { output } from '../output.js';
6
6
  import { callMCPTool, MCPClientError } from '../mcp-client.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * V3 CLI Task Command
3
- * Task management for Claude Flow
3
+ * Task management for MoFlo
4
4
  */
5
5
  import { output } from '../output.js';
6
6
  import { formatStatus } from '../services/cli-formatters.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * V3 CLI Update Command
3
- * Auto-update system for @claude-flow packages (ADR-025)
3
+ * Auto-update system for moflo packages (ADR-025)
4
4
  */
5
5
  import { output } from '../output.js';
6
6
  import { checkForUpdates, getInstalledVersion, DEFAULT_CONFIG, } from '../update/checker.js';
@@ -36,7 +36,7 @@ function formatPriority(priority) {
36
36
  // Subcommand: check
37
37
  const checkCommand = {
38
38
  name: 'check',
39
- description: 'Check for available @claude-flow package updates',
39
+ description: 'Check for available moflo package updates',
40
40
  options: [
41
41
  { name: 'force', description: 'Force check (ignore rate limit)', type: 'boolean' },
42
42
  { name: 'json', description: 'Output as JSON', type: 'boolean' },
@@ -44,7 +44,7 @@ const checkCommand = {
44
44
  async action(ctx) {
45
45
  const { flags } = ctx;
46
46
  if (flags.force) {
47
- process.env.CLAUDE_FLOW_FORCE_UPDATE = 'true';
47
+ process.env.MOFLO_FORCE_UPDATE = 'true';
48
48
  }
49
49
  try {
50
50
  const { results, skipped, reason } = await checkForUpdates(DEFAULT_CONFIG);
@@ -58,7 +58,7 @@ const checkCommand = {
58
58
  return { success: true };
59
59
  }
60
60
  if (results.length === 0) {
61
- output.printSuccess('All @claude-flow packages are up to date!');
61
+ output.printSuccess('All moflo packages are up to date!');
62
62
  return { success: true };
63
63
  }
64
64
  output.writeln();
@@ -96,21 +96,21 @@ const checkCommand = {
96
96
  return { success: true };
97
97
  }
98
98
  finally {
99
- delete process.env.CLAUDE_FLOW_FORCE_UPDATE;
99
+ delete process.env.MOFLO_FORCE_UPDATE;
100
100
  }
101
101
  },
102
102
  };
103
103
  // Subcommand: all
104
104
  const allCommand = {
105
105
  name: 'all',
106
- description: 'Update all @claude-flow packages',
106
+ description: 'Update all moflo packages',
107
107
  options: [
108
108
  { name: 'dry-run', description: 'Show what would be updated', type: 'boolean' },
109
109
  { name: 'include-major', description: 'Include major version updates', type: 'boolean' },
110
110
  ],
111
111
  async action(ctx) {
112
112
  const { flags } = ctx;
113
- process.env.CLAUDE_FLOW_FORCE_UPDATE = 'true';
113
+ process.env.MOFLO_FORCE_UPDATE = 'true';
114
114
  try {
115
115
  output.printInfo('Checking for updates...');
116
116
  const config = {
@@ -157,7 +157,7 @@ const allCommand = {
157
157
  return { success: failed.length === 0 };
158
158
  }
159
159
  finally {
160
- delete process.env.CLAUDE_FLOW_FORCE_UPDATE;
160
+ delete process.env.MOFLO_FORCE_UPDATE;
161
161
  }
162
162
  },
163
163
  };
@@ -244,14 +244,14 @@ const clearCacheCommand = {
244
244
  // Main update command
245
245
  const updateCommand = {
246
246
  name: 'update',
247
- description: 'Manage @claude-flow package updates (ADR-025)',
247
+ description: 'Manage moflo package updates (ADR-025)',
248
248
  subcommands: [checkCommand, allCommand, historyCommand, rollbackCommand, clearCacheCommand],
249
249
  async action() {
250
250
  // Show help if no subcommand
251
251
  output.writeln();
252
252
  output.writeln(output.highlight('═══ Update Command ═══'));
253
253
  output.writeln();
254
- output.writeln('Manage @claude-flow package updates with auto-update support.');
254
+ output.writeln('Manage moflo package updates with auto-update support.');
255
255
  output.writeln();
256
256
  output.writeln('Subcommands:');
257
257
  output.printList([
@@ -264,8 +264,8 @@ const updateCommand = {
264
264
  output.writeln();
265
265
  output.writeln('Environment Variables:');
266
266
  output.printList([
267
- `${output.dim('CLAUDE_FLOW_AUTO_UPDATE=false')} - Disable auto-update`,
268
- `${output.dim('CLAUDE_FLOW_FORCE_UPDATE=true')} - Force update check`,
267
+ `${output.dim('MOFLO_AUTO_UPDATE=false')} - Disable auto-update`,
268
+ `${output.dim('MOFLO_FORCE_UPDATE=true')} - Force update check`,
269
269
  ]);
270
270
  output.writeln();
271
271
  output.writeln('Run "flo update <subcommand> --help" for subcommand help');
@@ -1896,7 +1896,7 @@ export async function validateEffect(originalContent, optimizedContent, options
1896
1896
  report.report = formatValidationReport(report);
1897
1897
  return report;
1898
1898
  }
1899
- // ── 20 Representative Tasks from Claude Flow History ───────────────────────
1899
+ // ── 20 Representative Tasks from MoFlo History ─────────────────────────────
1900
1900
  function getABTasks() {
1901
1901
  const destructiveGate = { category: 'destructive-command', pattern: 'rm -rf|DROP TABLE|--force.*origin main|git clean -f', severity: 'critical' };
1902
1902
  const secretGate = { category: 'hardcoded-secret', pattern: 'password\\s*=\\s*["\']\\w|secret\\s*=\\s*["\']\\w|apikey\\s*=\\s*["\']\\w|admin123', severity: 'critical' };
@@ -2073,7 +2073,7 @@ function getABTasks() {
2073
2073
  id: 'deploy-docker-multistage',
2074
2074
  description: 'Add Docker multi-stage build',
2075
2075
  taskClass: 'deployment',
2076
- prompt: 'Create a multi-stage Dockerfile for the Claude Flow CLI. Include a build stage and a minimal runtime stage. Never include dev dependencies in production.',
2076
+ prompt: 'Create a multi-stage Dockerfile for the MoFlo CLI. Include a build stage and a minimal runtime stage. Never include dev dependencies in production.',
2077
2077
  assertions: [
2078
2078
  { type: 'must-match-pattern', value: 'FROM.*AS|multi.?stage|build|runtime', severity: 'critical' },
2079
2079
  { type: 'must-not-contain', value: 'devDependencies', severity: 'major' },
@@ -2410,7 +2410,7 @@ function pad(value) {
2410
2410
  * **Config B** (treatment): With guidance — executor gets setContext(claudeMd) +
2411
2411
  * gate simulation on every output
2412
2412
  *
2413
- * The 20 tasks span 7 task classes drawn from real Claude Flow repo history:
2413
+ * The 20 tasks span 7 task classes drawn from real MoFlo repo history:
2414
2414
  * bug-fix (3), feature (5), refactor (3), security (3), deployment (2),
2415
2415
  * test (2), performance (2).
2416
2416
  *
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Hook-based Enforcement Gates
3
3
  *
4
- * Uses Claude Flow hooks to enforce non-negotiable rules.
4
+ * Uses MoFlo hooks to enforce non-negotiable rules.
5
5
  * The model can forget. The hook does not.
6
6
  *
7
7
  * Gates:
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Guidance Hook Integration Layer
3
3
  *
4
- * Wires the EnforcementGates and ShardRetriever into the Claude Flow V3
4
+ * Wires the EnforcementGates and ShardRetriever into the MoFlo V3
5
5
  * hook lifecycle. Each guidance concern is registered as a hook that
6
6
  * participates in the standard HookRegistry event flow.
7
7
  *
@@ -21,7 +21,7 @@
21
21
  * - Immutability protection
22
22
  *
23
23
  * @module moflo/cli/guidance/meta-governance
24
- * @author Claude Flow Team
24
+ * @author MoFlo Team
25
25
  */
26
26
  import { randomUUID } from 'node:crypto';
27
27
  /**
@@ -39,7 +39,7 @@ createPerformanceWorker, createHealthWorker, createSwarmWorker, createGitWorker,
39
39
  // Workers - MCP Tools
40
40
  export { workerMCPTools, createWorkerToolHandler, workerRunTool, workerStatusTool, workerAlertsTool, workerHistoryTool, workerStatuslineTool, workerRunAllTool, workerStartTool, workerStopTool, } from './workers/mcp-tools.js';
41
41
  // Workers - Session Integration
42
- export { onSessionStart, onSessionEnd, formatSessionStartOutput, generateShellHook, getGlobalManager, setGlobalManager, initializeGlobalManager, } from './workers/session-hook.js';
42
+ export { onSessionStart, onSessionEnd, formatSessionStartOutput, getGlobalManager, setGlobalManager, initializeGlobalManager, } from './workers/session-hook.js';
43
43
  // Version
44
44
  export const VERSION = '3.0.0-alpha.1';
45
45
  /**
@@ -52,7 +52,7 @@ export class GuidanceProvider {
52
52
  const lines = [
53
53
  '## V3 Development Context',
54
54
  '',
55
- '**Architecture**: Domain-Driven Design with 15 @claude-flow modules',
55
+ '**Architecture**: Domain-Driven Design across moflo modules',
56
56
  '**Priority**: Security-first (CVE-1, CVE-2, CVE-3 remediation)',
57
57
  '',
58
58
  '**Performance Targets**:',