moflo 4.9.21 → 4.9.23

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 (194) hide show
  1. package/.claude/agents/analysis/analyze-code-quality.md +0 -121
  2. package/.claude/agents/analysis/code-analyzer.md +5 -26
  3. package/.claude/agents/architecture/system-design/arch-system-design.md +0 -119
  4. package/.claude/agents/base-template-generator.md +0 -1
  5. package/.claude/agents/core/coder.md +0 -22
  6. package/.claude/agents/core/planner.md +0 -16
  7. package/.claude/agents/core/researcher.md +0 -16
  8. package/.claude/agents/core/reviewer.md +0 -17
  9. package/.claude/agents/core/tester.md +0 -19
  10. package/.claude/agents/custom/test-long-runner.md +0 -2
  11. package/.claude/agents/development/dev-backend-api.md +0 -167
  12. package/.claude/agents/development/dev-database.md +43 -0
  13. package/.claude/agents/development/dev-frontend.md +42 -0
  14. package/.claude/agents/devops/ci-cd/ops-cicd-github.md +0 -112
  15. package/.claude/agents/documentation/api-docs/docs-api-openapi.md +0 -111
  16. package/.claude/agents/security/security-auditor.md +45 -0
  17. package/.claude/guidance/shipped/moflo-cli-reference.md +19 -16
  18. package/.claude/guidance/shipped/moflo-core-guidance.md +0 -2
  19. package/.claude/guidance/shipped/moflo-guidance-rules.md +5 -5
  20. package/.claude/guidance/shipped/moflo-spell-runner.md +1 -0
  21. package/.claude/guidance/shipped/moflo-spell-scheduling.md +225 -0
  22. package/.claude/guidance/shipped/moflo-spell-troubleshooting.md +1 -0
  23. package/.claude/helpers/gate.cjs +70 -3
  24. package/.claude/skills/fl/execution-modes.md +38 -15
  25. package/.claude/skills/fl/phases.md +67 -0
  26. package/.claude/skills/spell-schedule/SKILL.md +18 -5
  27. package/README.md +1 -1
  28. package/bin/gate.cjs +70 -3
  29. package/bin/index-guidance.mjs +32 -6
  30. package/bin/lib/retired-files.mjs +146 -0
  31. package/bin/session-start-launcher.mjs +116 -8
  32. package/dist/src/cli/appliance/rvfa-builder.js +1 -1
  33. package/dist/src/cli/commands/agent.js +3 -9
  34. package/dist/src/cli/commands/daemon.js +13 -17
  35. package/dist/src/cli/commands/hooks.js +4 -9
  36. package/dist/src/cli/commands/index.js +2 -0
  37. package/dist/src/cli/commands/retire.js +111 -0
  38. package/dist/src/cli/commands/spell-schedule.js +237 -49
  39. package/dist/src/cli/hooks/reasoningbank/index.js +7 -7
  40. package/dist/src/cli/init/executor.js +26 -54
  41. package/dist/src/cli/init/helpers-generator.js +66 -3
  42. package/dist/src/cli/init/settings-generator.js +17 -6
  43. package/dist/src/cli/mcp-tools/agent-tools.js +9 -27
  44. package/dist/src/cli/mcp-tools/hooks-tools.js +23 -21
  45. package/dist/src/cli/mcp-tools/memory-tools.js +16 -5
  46. package/dist/src/cli/memory/bridge-embedder.js +26 -6
  47. package/dist/src/cli/memory/bridge-entries.js +33 -15
  48. package/dist/src/cli/memory/controllers/semantic-router.js +18 -12
  49. package/dist/src/cli/memory/sona-optimizer.js +6 -6
  50. package/dist/src/cli/neural/domain/services/learning-service.js +3 -3
  51. package/dist/src/cli/services/agent-router.js +2 -5
  52. package/dist/src/cli/services/daemon-autostart-lifecycle.js +62 -0
  53. package/dist/src/cli/services/daemon-dashboard.js +187 -18
  54. package/dist/src/cli/services/daemon-readiness.js +19 -31
  55. package/dist/src/cli/services/ephemeral-namespace-purge.js +61 -33
  56. package/dist/src/cli/services/headless-worker-executor.js +7 -94
  57. package/dist/src/cli/services/hook-block-hash.js +4 -0
  58. package/dist/src/cli/services/worker-daemon.js +40 -66
  59. package/dist/src/cli/shared/events/example-usage.js +6 -6
  60. package/dist/src/cli/shared/hooks/task-hooks.js +8 -8
  61. package/dist/src/cli/spells/core/runner.js +12 -0
  62. package/dist/src/cli/spells/scheduler/scheduler.js +24 -9
  63. package/dist/src/cli/spells/schema/validator.js +2 -1
  64. package/dist/src/cli/spells/schema/validators/top-level.js +18 -0
  65. package/dist/src/cli/version.js +1 -1
  66. package/package.json +5 -2
  67. package/retired-files.json +1989 -0
  68. package/src/cli/data/model-registry.json +2 -2
  69. package/.claude/agents/consensus/byzantine-coordinator.md +0 -63
  70. package/.claude/agents/consensus/crdt-synchronizer.md +0 -997
  71. package/.claude/agents/consensus/gossip-coordinator.md +0 -63
  72. package/.claude/agents/consensus/performance-benchmarker.md +0 -851
  73. package/.claude/agents/consensus/quorum-manager.md +0 -823
  74. package/.claude/agents/consensus/raft-manager.md +0 -63
  75. package/.claude/agents/consensus/security-manager.md +0 -622
  76. package/.claude/agents/data/ml/data-ml-model.md +0 -193
  77. package/.claude/agents/github/code-review-swarm.md +0 -538
  78. package/.claude/agents/github/github-modes.md +0 -172
  79. package/.claude/agents/github/issue-tracker.md +0 -311
  80. package/.claude/agents/github/multi-repo-swarm.md +0 -551
  81. package/.claude/agents/github/pr-manager.md +0 -183
  82. package/.claude/agents/github/project-board-sync.md +0 -508
  83. package/.claude/agents/github/release-manager.md +0 -360
  84. package/.claude/agents/github/release-swarm.md +0 -580
  85. package/.claude/agents/github/repo-architect.md +0 -391
  86. package/.claude/agents/github/swarm-issue.md +0 -566
  87. package/.claude/agents/github/swarm-pr.md +0 -414
  88. package/.claude/agents/github/sync-coordinator.md +0 -426
  89. package/.claude/agents/github/workflow-automation.md +0 -606
  90. package/.claude/agents/goal/code-goal-planner.md +0 -440
  91. package/.claude/agents/goal/goal-planner.md +0 -168
  92. package/.claude/agents/hive-mind/collective-intelligence-coordinator.md +0 -127
  93. package/.claude/agents/hive-mind/queen-coordinator.md +0 -198
  94. package/.claude/agents/hive-mind/scout-explorer.md +0 -233
  95. package/.claude/agents/hive-mind/swarm-memory-manager.md +0 -184
  96. package/.claude/agents/hive-mind/worker-specialist.md +0 -208
  97. package/.claude/agents/neural/safla-neural.md +0 -73
  98. package/.claude/agents/optimization/benchmark-suite.md +0 -665
  99. package/.claude/agents/optimization/load-balancer.md +0 -431
  100. package/.claude/agents/optimization/performance-monitor.md +0 -672
  101. package/.claude/agents/optimization/resource-allocator.md +0 -674
  102. package/.claude/agents/optimization/topology-optimizer.md +0 -808
  103. package/.claude/agents/reasoning/goal-planner.md +0 -67
  104. package/.claude/agents/sona/sona-learning-optimizer.md +0 -74
  105. package/.claude/agents/sparc/architecture.md +0 -472
  106. package/.claude/agents/sparc/pseudocode.md +0 -318
  107. package/.claude/agents/sparc/refinement.md +0 -525
  108. package/.claude/agents/sparc/specification.md +0 -276
  109. package/.claude/agents/specialized/mobile/spec-mobile-react-native.md +0 -225
  110. package/.claude/agents/swarm/adaptive-coordinator.md +0 -391
  111. package/.claude/agents/swarm/hierarchical-coordinator.md +0 -321
  112. package/.claude/agents/swarm/mesh-coordinator.md +0 -383
  113. package/.claude/agents/testing/production-validator.md +0 -395
  114. package/.claude/agents/testing/tdd-london-swarm.md +0 -244
  115. package/.claude/agents/v3/adr-architect.md +0 -184
  116. package/.claude/agents/v3/aidefence-guardian.md +0 -277
  117. package/.claude/agents/v3/claims-authorizer.md +0 -208
  118. package/.claude/agents/v3/collective-intelligence-coordinator.md +0 -988
  119. package/.claude/agents/v3/ddd-domain-expert.md +0 -220
  120. package/.claude/agents/v3/injection-analyst.md +0 -232
  121. package/.claude/agents/v3/memory-specialist.md +0 -987
  122. package/.claude/agents/v3/performance-engineer.md +0 -1225
  123. package/.claude/agents/v3/pii-detector.md +0 -146
  124. package/.claude/agents/v3/reasoningbank-learner.md +0 -213
  125. package/.claude/agents/v3/security-architect-aidefence.md +0 -405
  126. package/.claude/agents/v3/security-architect.md +0 -865
  127. package/.claude/agents/v3/security-auditor.md +0 -771
  128. package/.claude/agents/v3/sparc-orchestrator.md +0 -182
  129. package/.claude/agents/v3/swarm-memory-manager.md +0 -142
  130. package/.claude/agents/v3/v3-integration-architect.md +0 -205
  131. package/.claude/commands/claude-flow-help.md +0 -103
  132. package/.claude/commands/claude-flow-memory.md +0 -107
  133. package/.claude/commands/claude-flow-swarm.md +0 -205
  134. package/.claude/commands/flo-simplify.md +0 -101
  135. package/.claude/commands/github/README.md +0 -11
  136. package/.claude/commands/github/code-review-swarm.md +0 -514
  137. package/.claude/commands/github/code-review.md +0 -25
  138. package/.claude/commands/github/github-modes.md +0 -146
  139. package/.claude/commands/github/github-swarm.md +0 -113
  140. package/.claude/commands/github/issue-tracker.md +0 -284
  141. package/.claude/commands/github/issue-triage.md +0 -25
  142. package/.claude/commands/github/multi-repo-swarm.md +0 -519
  143. package/.claude/commands/github/pr-enhance.md +0 -26
  144. package/.claude/commands/github/pr-manager.md +0 -164
  145. package/.claude/commands/github/project-board-sync.md +0 -471
  146. package/.claude/commands/github/release-manager.md +0 -332
  147. package/.claude/commands/github/release-swarm.md +0 -544
  148. package/.claude/commands/github/repo-analyze.md +0 -25
  149. package/.claude/commands/github/repo-architect.md +0 -361
  150. package/.claude/commands/github/swarm-issue.md +0 -482
  151. package/.claude/commands/github/swarm-pr.md +0 -285
  152. package/.claude/commands/github/sync-coordinator.md +0 -294
  153. package/.claude/commands/github/workflow-automation.md +0 -442
  154. package/.claude/commands/hooks/README.md +0 -11
  155. package/.claude/commands/hooks/overview.md +0 -58
  156. package/.claude/commands/hooks/post-edit.md +0 -117
  157. package/.claude/commands/hooks/post-task.md +0 -112
  158. package/.claude/commands/hooks/pre-edit.md +0 -113
  159. package/.claude/commands/hooks/pre-task.md +0 -111
  160. package/.claude/commands/hooks/session-end.md +0 -118
  161. package/.claude/commands/hooks/setup.md +0 -103
  162. package/.claude/commands/sparc/analyzer.md +0 -42
  163. package/.claude/commands/sparc/architect.md +0 -43
  164. package/.claude/commands/sparc/ask.md +0 -86
  165. package/.claude/commands/sparc/batch-executor.md +0 -44
  166. package/.claude/commands/sparc/code.md +0 -78
  167. package/.claude/commands/sparc/coder.md +0 -44
  168. package/.claude/commands/sparc/debug.md +0 -72
  169. package/.claude/commands/sparc/debugger.md +0 -44
  170. package/.claude/commands/sparc/designer.md +0 -43
  171. package/.claude/commands/sparc/devops.md +0 -98
  172. package/.claude/commands/sparc/docs-writer.md +0 -69
  173. package/.claude/commands/sparc/documenter.md +0 -44
  174. package/.claude/commands/sparc/innovator.md +0 -44
  175. package/.claude/commands/sparc/integration.md +0 -72
  176. package/.claude/commands/sparc/mcp.md +0 -106
  177. package/.claude/commands/sparc/memory-manager.md +0 -44
  178. package/.claude/commands/sparc/optimizer.md +0 -44
  179. package/.claude/commands/sparc/orchestrator.md +0 -116
  180. package/.claude/commands/sparc/post-deployment-monitoring-mode.md +0 -72
  181. package/.claude/commands/sparc/refinement-optimization-mode.md +0 -72
  182. package/.claude/commands/sparc/researcher.md +0 -44
  183. package/.claude/commands/sparc/reviewer.md +0 -44
  184. package/.claude/commands/sparc/security-review.md +0 -69
  185. package/.claude/commands/sparc/sparc-modes.md +0 -139
  186. package/.claude/commands/sparc/sparc.md +0 -99
  187. package/.claude/commands/sparc/spec-pseudocode.md +0 -69
  188. package/.claude/commands/sparc/spell-manager.md +0 -44
  189. package/.claude/commands/sparc/supabase-admin.md +0 -337
  190. package/.claude/commands/sparc/swarm-coordinator.md +0 -44
  191. package/.claude/commands/sparc/tdd.md +0 -44
  192. package/.claude/commands/sparc/tester.md +0 -44
  193. package/.claude/commands/sparc/tutorial.md +0 -68
  194. package/.claude/commands/sparc.md +0 -151
@@ -105,9 +105,11 @@ export function generateSettings(options) {
105
105
  daemon: {
106
106
  autoStart: true,
107
107
  // Note: this list is documentation for the user — the daemon's actual
108
- // worker registry lives in src/cli/services/worker-daemon.ts DEFAULT_WORKERS.
109
- // 'audit' is intentionally absent here because it's default-disabled
110
- // pending the perf fix in #631.
108
+ // worker registry lives in src/cli/services/worker-daemon.ts
109
+ // DEFAULT_WORKERS. The `audit`/`predict`/`document` workers were
110
+ // removed in #970 (no surfacing layer for findings + dashboard
111
+ // pollution); restore them as opt-in `flo doctor` one-shots if their
112
+ // value is ever re-established.
111
113
  workers: [
112
114
  'map', // Codebase mapping
113
115
  'optimize', // Performance optimization (high priority)
@@ -115,15 +117,12 @@ export function generateSettings(options) {
115
117
  'testgaps', // Test coverage gaps
116
118
  'ultralearn', // Deep knowledge acquisition
117
119
  'deepdive', // Deep code analysis
118
- 'document', // Auto-documentation for ADRs
119
120
  'refactor', // Refactoring suggestions (DDD alignment)
120
121
  'benchmark', // Performance benchmarking
121
122
  ],
122
123
  schedules: {
123
- audit: { interval: '1h', priority: 'critical' },
124
124
  optimize: { interval: '30m', priority: 'high' },
125
125
  consolidate: { interval: '2h', priority: 'low' },
126
- document: { interval: '1h', priority: 'normal', triggers: ['adr-update', 'api-change'] },
127
126
  deepdive: { interval: '4h', priority: 'normal', triggers: ['complex-change'] },
128
127
  ultralearn: { interval: '1h', priority: 'normal' },
129
128
  },
@@ -302,6 +301,18 @@ function generateHooksConfig(config) {
302
301
  matcher: '^mcp__moflo__memory_store$',
303
302
  hooks: [{ type: 'command', command: gateCmd('record-learnings-stored'), timeout: 2000 }],
304
303
  },
304
+ {
305
+ // #952 — when /fl is invoked with -s/--swarm, the gate blocks Agent
306
+ // spawns until mcp__moflo__swarm_init runs. Record the call here so
307
+ // the hard block in check-before-agent passes for legitimate /fl runs.
308
+ matcher: '^mcp__moflo__swarm_init$',
309
+ hooks: [{ type: 'command', command: gateCmd('record-swarm-init'), timeout: 2000 }],
310
+ },
311
+ {
312
+ // #952 — symmetric record for /fl -h/--hive runs.
313
+ matcher: '^mcp__moflo__hive-mind_init$',
314
+ hooks: [{ type: 'command', command: gateCmd('record-hive-init'), timeout: 2000 }],
315
+ },
305
316
  ];
306
317
  }
307
318
  // UserPromptSubmit — per-prompt state reset + Context warnings.
@@ -27,33 +27,16 @@ const CANONICAL_AGENT_TYPES = [
27
27
  ];
28
28
  const ALLOWED_AGENT_TYPES = new Set([
29
29
  ...CANONICAL_AGENT_TYPES,
30
- // Shipped Claude Code agent definitions (.claude/agents/**)
31
- 'adaptive-coordinator', 'adr-architect', 'aidefence-guardian',
30
+ // Claude Code built-ins
31
+ 'claude-code-guide', 'general-purpose',
32
+ // Shipped Claude Code agent definitions (.claude/agents/**) — both the
33
+ // canonical `name:` slug and the file basename are accepted.
32
34
  'analyze-code-quality', 'api-docs', 'arch-system-design',
33
- 'backend-dev', 'base-template-generator', 'benchmark-suite',
34
- 'byzantine-coordinator', 'cicd-engineer', 'claims-authorizer',
35
- 'claude-code-guide', 'code-analyzer', 'code-goal-planner',
36
- 'code-review-swarm', 'collective-intelligence-coordinator',
37
- 'crdt-synchronizer', 'data-ml-model', 'ddd-domain-expert',
38
- 'dev-backend-api', 'docs-api-openapi', 'general-purpose',
39
- 'github-modes', 'goal-planner', 'gossip-coordinator',
40
- 'hierarchical-coordinator', 'injection-analyst', 'issue-tracker',
41
- 'load-balancer', 'memory-specialist', 'mesh-coordinator',
42
- 'ml-developer', 'mobile-dev', 'multi-repo-swarm',
43
- 'ops-cicd-github', 'performance-benchmarker', 'performance-engineer',
44
- 'performance-monitor', 'pii-detector', 'planner',
45
- 'pr-manager', 'production-validator', 'project-board-sync',
46
- 'pseudocode', 'quorum-manager', 'queen-coordinator',
47
- 'raft-manager', 'reasoningbank-learner', 'refinement',
48
- 'release-manager', 'release-swarm', 'repo-architect',
49
- 'resource-allocator', 'safla-neural', 'scout-explorer',
50
- 'security-architect', 'security-architect-aidefence',
51
- 'security-auditor', 'security-manager', 'sona-learning-optimizer',
52
- 'sparc-orchestrator', 'spec-mobile-react-native', 'specification',
53
- 'swarm-issue', 'swarm-memory-manager', 'swarm-pr',
54
- 'sync-coordinator', 'system-architect', 'tdd-london-swarm',
55
- 'test-long-runner', 'topology-optimizer', 'v3-integration-architect',
56
- 'workflow-automation', 'worker-specialist',
35
+ 'backend-dev', 'base-template-generator', 'cicd-engineer',
36
+ 'code-analyzer', 'database-dev', 'dev-backend-api',
37
+ 'dev-database', 'dev-frontend', 'docs-api-openapi',
38
+ 'frontend-dev', 'ops-cicd-github', 'planner',
39
+ 'security-auditor', 'system-architect', 'test-long-runner',
57
40
  ]);
58
41
  const AGENT_TYPE_SLUG_RE = /^[a-z][a-z0-9-]*$/;
59
42
  export function toNonNegativeInt(value, fallback) {
@@ -78,7 +61,6 @@ export function validateAgentType(value) {
78
61
  const AGENT_TYPE_MODEL_DEFAULTS = {
79
62
  // Complex agents → opus
80
63
  'architect': 'opus',
81
- 'security-architect': 'opus',
82
64
  'system-architect': 'opus',
83
65
  'core-architect': 'opus',
84
66
  // Medium complexity → sonnet
@@ -211,7 +211,7 @@ function learnedPatternsFromOutcomes() {
211
211
  const TASK_PATTERNS = {
212
212
  'security-task': {
213
213
  keywords: ['authentication', 'security', 'auth', 'password', 'encryption', 'vulnerability', 'cve', 'audit'],
214
- agents: ['security-architect', 'security-auditor', 'reviewer'],
214
+ agents: ['security-auditor', 'reviewer'],
215
215
  },
216
216
  'testing-task': {
217
217
  keywords: ['test', 'testing', 'spec', 'coverage', 'unit test', 'integration test', 'e2e'],
@@ -223,7 +223,7 @@ const TASK_PATTERNS = {
223
223
  },
224
224
  'performance-task': {
225
225
  keywords: ['performance', 'optimize', 'speed', 'memory', 'benchmark', 'profiling', 'bottleneck'],
226
- agents: ['performance-engineer', 'coder', 'tester'],
226
+ agents: ['reviewer', 'coder', 'tester'],
227
227
  },
228
228
  'refactor-task': {
229
229
  keywords: ['refactor', 'restructure', 'clean', 'organize', 'modular', 'decouple'],
@@ -239,23 +239,25 @@ const TASK_PATTERNS = {
239
239
  },
240
240
  'database-task': {
241
241
  keywords: ['database', 'sql', 'query', 'schema', 'migration', 'orm'],
242
- agents: ['architect', 'coder', 'tester'],
242
+ agents: ['database-dev', 'coder', 'tester'],
243
243
  },
244
244
  'frontend-task': {
245
- keywords: ['frontend', 'ui', 'component', 'react', 'css', 'style', 'layout'],
246
- agents: ['coder', 'reviewer', 'tester'],
245
+ keywords: ['frontend', 'ui', 'component', 'react', 'vue', 'svelte', 'css', 'tailwind', 'style', 'layout', 'accessibility'],
246
+ agents: ['frontend-dev', 'reviewer', 'tester'],
247
247
  },
248
248
  'devops-task': {
249
249
  keywords: ['deploy', 'ci', 'cd', 'pipeline', 'docker', 'kubernetes', 'infrastructure'],
250
- agents: ['devops', 'coder', 'tester'],
250
+ agents: ['cicd-engineer', 'coder', 'tester'],
251
251
  },
252
+ // (github-task intent removed — github work routes to generic coder/reviewer
253
+ // with the gh CLI; specialized github-* agents were retired in #932)
252
254
  'swarm-task': {
253
255
  keywords: ['swarm', 'agent', 'coordinator', 'hive', 'mesh', 'topology'],
254
- agents: ['swarm-specialist', 'coordinator', 'architect'],
256
+ agents: ['coordinator', 'architect'],
255
257
  },
256
258
  'memory-task': {
257
259
  keywords: ['memory', 'cache', 'store', 'vector', 'embedding', 'persistence'],
258
- agents: ['memory-specialist', 'architect', 'coder'],
260
+ agents: ['researcher', 'architect', 'coder'],
259
261
  },
260
262
  };
261
263
  /**
@@ -436,30 +438,30 @@ const AGENT_PATTERNS = {
436
438
  '.yaml': ['coder', 'devops'],
437
439
  '.yml': ['coder', 'devops'],
438
440
  '.sh': ['devops', 'coder'],
439
- '.py': ['coder', 'ml-developer', 'researcher'],
441
+ '.py': ['coder', 'researcher'],
440
442
  '.sql': ['coder', 'architect'],
441
443
  '.css': ['coder', 'designer'],
442
444
  '.scss': ['coder', 'designer'],
443
445
  };
444
446
  // Keyword patterns for fallback routing (when semantic routing doesn't match)
445
447
  const KEYWORD_PATTERNS = {
446
- 'authentication': { agents: ['security-architect', 'coder', 'tester'], confidence: 0.9 },
447
- 'auth': { agents: ['security-architect', 'coder', 'tester'], confidence: 0.85 },
448
+ 'authentication': { agents: ['security-auditor', 'coder', 'tester'], confidence: 0.9 },
449
+ 'auth': { agents: ['security-auditor', 'coder', 'tester'], confidence: 0.85 },
448
450
  'api': { agents: ['architect', 'coder', 'tester'], confidence: 0.85 },
449
451
  'test': { agents: ['tester', 'reviewer'], confidence: 0.95 },
450
452
  'refactor': { agents: ['architect', 'coder', 'reviewer'], confidence: 0.9 },
451
- 'performance': { agents: ['performance-engineer', 'coder', 'tester'], confidence: 0.88 },
452
- 'security': { agents: ['security-architect', 'security-auditor', 'reviewer'], confidence: 0.92 },
453
- 'database': { agents: ['architect', 'coder', 'tester'], confidence: 0.85 },
454
- 'frontend': { agents: ['coder', 'designer', 'tester'], confidence: 0.82 },
455
- 'backend': { agents: ['architect', 'coder', 'tester'], confidence: 0.85 },
453
+ 'performance': { agents: ['reviewer', 'coder', 'tester'], confidence: 0.88 },
454
+ 'security': { agents: ['security-auditor', 'reviewer'], confidence: 0.92 },
455
+ 'database': { agents: ['database-dev', 'coder', 'tester'], confidence: 0.9 },
456
+ 'frontend': { agents: ['frontend-dev', 'reviewer', 'tester'], confidence: 0.9 },
457
+ 'backend': { agents: ['backend-dev', 'architect', 'coder', 'tester'], confidence: 0.9 },
456
458
  'bug': { agents: ['coder', 'tester', 'reviewer'], confidence: 0.88 },
457
459
  'fix': { agents: ['coder', 'tester', 'reviewer'], confidence: 0.85 },
458
460
  'feature': { agents: ['architect', 'coder', 'tester'], confidence: 0.8 },
459
- 'swarm': { agents: ['swarm-specialist', 'coordinator', 'architect'], confidence: 0.9 },
460
- 'memory': { agents: ['memory-specialist', 'architect', 'coder'], confidence: 0.88 },
461
- 'deploy': { agents: ['devops', 'coder', 'tester'], confidence: 0.85 },
462
- 'ci/cd': { agents: ['devops', 'coder'], confidence: 0.9 },
461
+ 'swarm': { agents: ['coordinator', 'architect'], confidence: 0.9 },
462
+ 'memory': { agents: ['researcher', 'architect', 'coder'], confidence: 0.88 },
463
+ 'deploy': { agents: ['cicd-engineer', 'coder', 'tester'], confidence: 0.85 },
464
+ 'ci/cd': { agents: ['cicd-engineer', 'coder'], confidence: 0.9 },
463
465
  };
464
466
  function getFileExtension(filePath) {
465
467
  const match = filePath.match(/\.[a-zA-Z0-9]+$/);
@@ -1675,7 +1677,7 @@ export const hooksBuildAgents = {
1675
1677
  { type: 'coder', configFile: join(outputDir, `coder.${format}`), capabilities: ['code-generation', 'refactoring', 'debugging'], optimizations: ['flash-attention', 'token-reduction'] },
1676
1678
  { type: 'architect', configFile: join(outputDir, `architect.${format}`), capabilities: ['system-design', 'api-design', 'documentation'], optimizations: ['context-caching', 'memory-persistence'] },
1677
1679
  { type: 'tester', configFile: join(outputDir, `tester.${format}`), capabilities: ['unit-testing', 'integration-testing', 'coverage'], optimizations: ['parallel-execution'] },
1678
- { type: 'security-architect', configFile: join(outputDir, `security-architect.${format}`), capabilities: ['threat-modeling', 'vulnerability-analysis', 'security-review'], optimizations: ['pattern-matching'] },
1680
+ { type: 'security-auditor', configFile: join(outputDir, `security-auditor.${format}`), capabilities: ['threat-modeling', 'vulnerability-analysis', 'security-review'], optimizations: ['pattern-matching'] },
1679
1681
  { type: 'reviewer', configFile: join(outputDir, `reviewer.${format}`), capabilities: ['code-review', 'quality-analysis', 'best-practices'], optimizations: ['incremental-analysis'] },
1680
1682
  ];
1681
1683
  const filteredAgents = focus === 'all' ? agents :
@@ -154,7 +154,7 @@ async function ensureInitialized() {
154
154
  export const memoryTools = [
155
155
  {
156
156
  name: 'memory_store',
157
- description: 'Store a value in memory with vector embedding for semantic search (sql.js + HNSW backend). Use upsert=true to update existing keys.',
157
+ description: 'Store a value in memory with vector embedding for semantic search (sql.js + HNSW backend). Upserts by default — pass upsert:false to fail on duplicate keys.',
158
158
  category: 'memory',
159
159
  inputSchema: {
160
160
  type: 'object',
@@ -168,7 +168,7 @@ export const memoryTools = [
168
168
  description: 'Optional tags for filtering',
169
169
  },
170
170
  ttl: { type: 'number', description: 'Time-to-live in seconds (optional)' },
171
- upsert: { type: 'boolean', description: 'If true, update existing key instead of failing (default: false)' },
171
+ upsert: { type: 'boolean', description: 'If false, fail on duplicate keys instead of replacing (default: true)' },
172
172
  },
173
173
  required: ['key', 'value'],
174
174
  },
@@ -180,7 +180,9 @@ export const memoryTools = [
180
180
  const value = typeof input.value === 'string' ? input.value : JSON.stringify(input.value);
181
181
  const tags = input.tags || [];
182
182
  const ttl = input.ttl;
183
- const upsert = input.upsert || false;
183
+ // #962: default upsert=true silent UNIQUE-constraint failures on update
184
+ // were dropping schedule cancels and similar updates on the floor.
185
+ const upsert = input.upsert === false ? false : true;
184
186
  validateMemoryInput(key, value);
185
187
  const startTime = performance.now();
186
188
  try {
@@ -364,12 +366,21 @@ export const memoryTools = [
364
366
  const namespace = input.namespace || 'default';
365
367
  try {
366
368
  const result = await deleteEntry({ key, namespace });
369
+ // Issue #963: surface the underlying reason when delete fails.
370
+ // `result.success` reflects whether the call itself succeeded; we
371
+ // require `deleted === true` for the MCP-level success boolean,
372
+ // and pass `result.error` through whenever the delete didn't take.
373
+ const deleted = result.deleted === true;
374
+ const errorReason = !deleted
375
+ ? (result.error ?? `No entry deleted (key='${key}', namespace='${namespace}'); reason not reported by storage layer`)
376
+ : undefined;
367
377
  return {
368
- success: result.deleted,
378
+ success: result.success === true && deleted,
369
379
  key,
370
380
  namespace,
371
- deleted: result.deleted,
381
+ deleted,
372
382
  backend: 'sql.js + HNSW',
383
+ ...(errorReason ? { error: errorReason } : {}),
373
384
  };
374
385
  }
375
386
  catch (error) {
@@ -44,11 +44,9 @@ export const EMBEDDING_MODEL_OPT_OUT = 'none';
44
44
  */
45
45
  export const EMBEDDING_MODEL_LEGACY_DEFAULT = 'local';
46
46
  /**
47
- * Namespaces that store internal moflo run-tracking, never user knowledge.
48
- * Writes here skip embedding generation entirely both `embedding` and
49
- * `embedding_model` land as NULL, distinct from the opt-out path which still
50
- * tags rows with `'none'`. Existing rows in these namespaces are hard-deleted
51
- * on upgrade by `services/ephemeral-namespace-purge.ts`.
47
+ * Namespaces that skip embedding generation in the bridge write path. Rows
48
+ * land with both `embedding` and `embedding_model` NULL (distinct from the
49
+ * opt-out path which still tags rows with `'none'`).
52
50
  *
53
51
  * Members:
54
52
  * - `hive-mind` — MCP broadcast traffic (msg:*, agent_join, consensus_propose)
@@ -56,7 +54,11 @@ export const EMBEDDING_MODEL_LEGACY_DEFAULT = 'local';
56
54
  * - `epic-state` — Epic progress (epic-N, story-M) written by commands/epic.ts
57
55
  * - `test-bridge-fix` — Single 2026-04-23 row left over from a one-off test
58
56
  *
59
- * See story #729 for the source-trace and rationale.
57
+ * See story #729 for the source-trace and rationale. The session-start
58
+ * launcher only purges {@link PURGE_ON_SESSION_START_NAMESPACES} — a strict
59
+ * subset that *excludes* `tasklist`, because the dashboard's Flo Runs tab
60
+ * (`daemon-dashboard.ts handleSpells`) reads tasklist; purging it on every
61
+ * session would empty the tab between sessions (#968).
60
62
  */
61
63
  export const EPHEMERAL_NAMESPACES = new Set([
62
64
  'hive-mind',
@@ -64,6 +66,24 @@ export const EPHEMERAL_NAMESPACES = new Set([
64
66
  'epic-state',
65
67
  'test-bridge-fix',
66
68
  ]);
69
+ /**
70
+ * Subset of {@link EPHEMERAL_NAMESPACES} that the session-start launcher
71
+ * hard-purges via `services/ephemeral-namespace-purge.ts`. Excludes
72
+ * `tasklist` — those rows back the dashboard's "Flo Runs" tab and are
73
+ * trimmed by row-count retention instead of bulk purge (#968).
74
+ */
75
+ export const PURGE_ON_SESSION_START_NAMESPACES = new Set([
76
+ 'hive-mind',
77
+ 'epic-state',
78
+ 'test-bridge-fix',
79
+ ]);
80
+ /**
81
+ * Maximum number of `tasklist` rows kept across session restarts. The
82
+ * session-start retention pass deletes oldest rows beyond this cap, so the
83
+ * dashboard's "Flo Runs" tab shows recent history without unbounded growth
84
+ * (#968). Sized for ~2 weeks of /flo activity at typical use.
85
+ */
86
+ export const TASKLIST_RETENTION_CAP = 200;
67
87
  let cachedEmbedder = null;
68
88
  let testOverride = null;
69
89
  class LazyFastembedBridgeEmbedder {
@@ -435,14 +435,30 @@ export async function bridgeGetEntry(options) {
435
435
  });
436
436
  }
437
437
  /**
438
- * Soft-delete an entry. Guarded, cache-invalidated, attested.
438
+ * Hard-delete an entry. Guarded, cache-invalidated, attested.
439
+ *
440
+ * Failure modes (issue #963): every non-success path now carries a
441
+ * human-readable `error` so MCP callers can surface the reason instead
442
+ * of seeing a silent `{ deleted: false }`.
439
443
  */
440
444
  export async function bridgeDeleteEntry(options) {
441
445
  return withDb(options.dbPath, async (ctx, registry) => {
442
446
  const { key, namespace = 'default' } = options;
447
+ const deleteFail = (error) => ({ success: false, deleted: false, key, namespace, remainingEntries: 0, error });
443
448
  const guardResult = await guardValidate(registry, 'delete', { key, namespace });
444
449
  if (!guardResult.allowed) {
445
- return { success: false, deleted: false, key, namespace, remainingEntries: 0, error: `MutationGuard rejected: ${guardResult.reason}` };
450
+ return deleteFail(`MutationGuard rejected: ${guardResult.reason}`);
451
+ }
452
+ let existed = false;
453
+ try {
454
+ const existsRows = execRows(ctx.db, `SELECT 1 as found FROM memory_entries WHERE key = ? AND namespace = ? AND status = 'active' LIMIT 1`, [key, namespace]);
455
+ existed = existsRows.length > 0;
456
+ }
457
+ catch (err) {
458
+ return deleteFail(`DB read failed during delete pre-check: ${errorDetail(err)}`);
459
+ }
460
+ if (!existed) {
461
+ return deleteFail(`Key '${key}' not found in namespace '${namespace}'`);
446
462
  }
447
463
  let changes = 0;
448
464
  try {
@@ -454,28 +470,30 @@ export async function bridgeDeleteEntry(options) {
454
470
  // db.getRowsModified() to read the row count from the last statement.
455
471
  changes = ctx.db.getRowsModified?.() ?? 0;
456
472
  }
457
- catch {
458
- return null;
473
+ catch (err) {
474
+ return deleteFail(`DELETE failed: ${errorDetail(err)}`);
459
475
  }
460
- if (changes > 0)
461
- persistBridgeDb(ctx.db, options.dbPath);
462
- await cacheInvalidate(registry, makeEntryCacheKey(namespace, key));
463
- if (changes > 0) {
464
- await logAttestation(registry, 'delete', key, { namespace });
476
+ if (changes === 0) {
477
+ // SELECT found the row but DELETE removed nothing. Most likely cause:
478
+ // bridge holds an in-memory snapshot that diverged from disk
479
+ // (sql.js writeback semantics — see feedback_sqljs_writeback_clobber.md).
480
+ return deleteFail(`Internal inconsistency: row matched SELECT but DELETE removed 0 rows (key='${key}', namespace='${namespace}'). Possible bridge cache staleness — restart the daemon and retry.`);
465
481
  }
482
+ persistBridgeDb(ctx.db, options.dbPath);
483
+ await cacheInvalidate(registry, makeEntryCacheKey(namespace, key));
484
+ await logAttestation(registry, 'delete', key, { namespace });
466
485
  let remaining = 0;
467
486
  try {
468
- const result = ctx.db.exec(`SELECT COUNT(*) as cnt FROM memory_entries WHERE status = 'active'`);
469
- remaining = result[0]?.values?.[0]?.[0] ?? 0;
487
+ const countRows = execRows(ctx.db, `SELECT COUNT(*) as cnt FROM memory_entries WHERE status = 'active'`);
488
+ remaining = Number(countRows[0]?.cnt ?? 0);
470
489
  }
471
490
  catch {
472
- // Non-fatal
491
+ // Non-fatal — count is informational
473
492
  }
474
- if (changes > 0)
475
- refreshVectorStatsCache();
493
+ refreshVectorStatsCache();
476
494
  return {
477
495
  success: true,
478
- deleted: changes > 0,
496
+ deleted: true,
479
497
  key,
480
498
  namespace,
481
499
  remainingEntries: remaining,
@@ -27,43 +27,49 @@ const DEFAULT_INTENTS = [
27
27
  name: 'memory',
28
28
  category: 'storage',
29
29
  keywords: ['memory', 'store', 'retrieve', 'search', 'embedding', 'vector', 'recall', 'persist'],
30
- agents: ['memory-specialist', 'swarm-memory-manager'],
30
+ agents: ['researcher', 'coder'],
31
+ },
32
+ {
33
+ name: 'frontend',
34
+ category: 'development',
35
+ keywords: ['frontend', 'ui', 'component', 'react', 'vue', 'svelte', 'css', 'tailwind', 'style', 'layout', 'accessibility', 'responsive'],
36
+ agents: ['frontend-dev', 'reviewer'],
37
+ },
38
+ {
39
+ name: 'database',
40
+ category: 'development',
41
+ keywords: ['database', 'sql', 'query', 'schema', 'migration', 'orm', 'index', 'postgres', 'mysql', 'sqlite', 'transaction'],
42
+ agents: ['database-dev', 'reviewer'],
31
43
  },
32
44
  {
33
45
  name: 'spell',
34
46
  category: 'workflow',
35
47
  keywords: ['spell', 'workflow', 'orchestrate', 'cast', 'pipeline', 'step'],
36
- agents: ['planner', 'sparc-orchestrator'],
48
+ agents: ['planner'],
37
49
  },
38
50
  {
39
51
  name: 'hooks',
40
52
  category: 'automation',
41
53
  keywords: ['hook', 'pre-task', 'post-task', 'event', 'trigger', 'automation'],
42
- agents: ['cicd-engineer', 'workflow-automation'],
54
+ agents: ['cicd-engineer', 'coder'],
43
55
  },
44
56
  {
45
57
  name: 'security',
46
58
  category: 'security',
47
59
  keywords: ['security', 'vulnerability', 'cve', 'audit', 'threat', 'permission', 'auth'],
48
- agents: ['security-auditor', 'security-architect'],
49
- },
50
- {
51
- name: 'neural',
52
- category: 'ml',
53
- keywords: ['neural', 'train', 'model', 'learning', 'reinforcement', 'sona', 'reasoningbank'],
54
- agents: ['ml-developer', 'safla-neural'],
60
+ agents: ['security-auditor', 'reviewer'],
55
61
  },
56
62
  {
57
63
  name: 'test',
58
64
  category: 'quality',
59
65
  keywords: ['test', 'vitest', 'unit', 'integration', 'tdd', 'coverage', 'assertion'],
60
- agents: ['tester', 'tdd-london-swarm'],
66
+ agents: ['tester'],
61
67
  },
62
68
  {
63
69
  name: 'github',
64
70
  category: 'integration',
65
71
  keywords: ['github', 'pr', 'pull request', 'issue', 'release', 'commit', 'branch'],
66
- agents: ['pr-manager', 'github-modes', 'release-manager'],
72
+ agents: ['coder', 'reviewer'],
67
73
  },
68
74
  ];
69
75
  export class SemanticRouter {
@@ -38,8 +38,8 @@ const AGENT_TYPES = [
38
38
  'optimizer',
39
39
  'debugger',
40
40
  'documenter',
41
- 'security-architect',
42
- 'performance-engineer',
41
+ 'security-auditor',
42
+ 'planner',
43
43
  ];
44
44
  /**
45
45
  * Task keywords for pattern extraction
@@ -77,13 +77,13 @@ const KEYWORD_CATEGORIES = {
77
77
  'document', 'docs', 'readme', 'comment', 'explain', 'guide',
78
78
  'tutorial', 'api-docs', 'specification', 'jsdoc',
79
79
  ],
80
- 'security-architect': [
80
+ 'security-auditor': [
81
81
  'security', 'auth', 'authentication', 'authorization', 'encrypt',
82
82
  'vulnerability', 'cve', 'secure', 'permission', 'role',
83
83
  ],
84
- 'performance-engineer': [
85
- 'profiling', 'bottleneck', 'latency', 'throughput', 'cache',
86
- 'scale', 'load', 'stress', 'concurrent', 'parallel',
84
+ planner: [
85
+ 'plan', 'breakdown', 'sequencing', 'estimate', 'milestone', 'roadmap',
86
+ 'task', 'dependency', 'goal',
87
87
  ],
88
88
  };
89
89
  // ============================================================================
@@ -118,9 +118,9 @@ export class LearningDomainService {
118
118
  review: 'reviewer',
119
119
  plan: 'planner',
120
120
  research: 'researcher',
121
- security: 'security-architect',
122
- performance: 'performance-engineer',
123
- memory: 'memory-specialist',
121
+ security: 'security-auditor',
122
+ performance: 'reviewer',
123
+ memory: 'researcher',
124
124
  };
125
125
  for (const [keyword, role] of Object.entries(keywordMap)) {
126
126
  if (taskLower.includes(keyword)) {
@@ -19,9 +19,7 @@ export const AGENT_CAPABILITIES = {
19
19
  'backend-dev': ['api', 'database', 'server', 'authentication'],
20
20
  'frontend-dev': ['ui', 'react', 'css', 'components'],
21
21
  devops: ['ci-cd', 'docker', 'deployment', 'infrastructure'],
22
- 'security-architect': ['security-design', 'threat-modeling', 'auth-flow'],
23
- 'security-auditor': ['vulnerability-scan', 'dependency-audit', 'compliance'],
24
- 'memory-specialist': ['memory-management', 'caching', 'persistence'],
22
+ 'security-auditor': ['security-design', 'threat-modeling', 'auth-flow', 'vulnerability-scan', 'dependency-audit', 'compliance'],
25
23
  coordinator: ['task-distribution', 'orchestration', 'scheduling'],
26
24
  analyst: ['data-analysis', 'metrics', 'reporting', 'monitoring'],
27
25
  optimizer: ['performance', 'profiling', 'optimization', 'benchmarking'],
@@ -41,8 +39,7 @@ const TASK_PATTERNS = [
41
39
  { regex: /ui|frontend|component|react|css|style/i, agentType: 'frontend-dev' },
42
40
  { regex: /deploy|docker|ci|cd|pipeline|infrastructure/i, agentType: 'devops' },
43
41
  // Specialized patterns
44
- { regex: /security|auth|permission|rbac|oauth/i, agentType: 'security-architect' },
45
- { regex: /vulnerability|cve|dependency.*update|npm audit/i, agentType: 'security-auditor' },
42
+ { regex: /security|auth|permission|rbac|oauth|vulnerability|cve|dependency.*update|npm audit/i, agentType: 'security-auditor' },
46
43
  { regex: /performance|optimize|profile|benchmark|speed/i, agentType: 'optimizer' },
47
44
  { regex: /analyz|metric|report|monitor|dashboard/i, agentType: 'analyst' },
48
45
  ];
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Daemon Autostart Lifecycle
3
+ *
4
+ * Reconciles the OS-native daemon login service against the count of enabled
5
+ * scheduled spells. Replaces the old prompt-based flow in `daemon-readiness.ts`
6
+ * (which left users with stale autostart entries when their last schedule was
7
+ * cancelled — see #960, #961).
8
+ *
9
+ * Idempotent: callers invoke `reconcileDaemonAutostart` after every mutation
10
+ * to `scheduled-spells`. It installs once, uninstalls once, and is a no-op
11
+ * for every other transition.
12
+ */
13
+ import { isDaemonInstalled as defaultIsDaemonInstalled, installDaemonService as defaultInstallDaemonService, uninstallDaemonService as defaultUninstallDaemonService, } from './daemon-service.js';
14
+ const NOOP = { transition: 'noop', message: null, warning: null };
15
+ /**
16
+ * Reconcile OS-native daemon autostart against schedule count.
17
+ *
18
+ * - count ≥ 1 + not installed → install
19
+ * - count = 0 + installed → uninstall
20
+ * - all other states → noop
21
+ *
22
+ * Never throws. Install/uninstall failures are returned as non-fatal warnings
23
+ * — the caller decides whether to print them. The schedule mutation itself is
24
+ * always considered the primary operation; autostart is best-effort.
25
+ */
26
+ export function reconcileDaemonAutostart(options) {
27
+ if (options.skip)
28
+ return NOOP;
29
+ const isInstalled = (options.isDaemonInstalled ?? defaultIsDaemonInstalled)(options.projectRoot);
30
+ if (options.enabledScheduleCount >= 1 && !isInstalled) {
31
+ const result = (options.installDaemonService ?? defaultInstallDaemonService)(options.projectRoot);
32
+ if (result.success) {
33
+ return {
34
+ transition: 'installed',
35
+ message: 'Daemon registered as OS login service so this schedule survives reboot.',
36
+ warning: null,
37
+ };
38
+ }
39
+ return {
40
+ transition: 'noop',
41
+ message: null,
42
+ warning: `Could not register daemon as OS login service: ${result.message}`,
43
+ };
44
+ }
45
+ if (options.enabledScheduleCount === 0 && isInstalled) {
46
+ const result = (options.uninstallDaemonService ?? defaultUninstallDaemonService)(options.projectRoot);
47
+ if (result.success) {
48
+ return {
49
+ transition: 'uninstalled',
50
+ message: 'No enabled schedules remain — daemon unregistered from OS login services.',
51
+ warning: null,
52
+ };
53
+ }
54
+ return {
55
+ transition: 'noop',
56
+ message: null,
57
+ warning: `Could not unregister daemon from OS login services: ${result.message}`,
58
+ };
59
+ }
60
+ return NOOP;
61
+ }
62
+ //# sourceMappingURL=daemon-autostart-lifecycle.js.map