moflo 4.12.3 → 4.12.4-rc.10
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.
- package/.claude/agents/core/coder.md +19 -27
- package/.claude/agents/core/planner.md +51 -29
- package/.claude/agents/core/researcher.md +20 -28
- package/.claude/agents/core/reviewer.md +24 -33
- package/.claude/agents/core/tester.md +17 -22
- package/.claude/guidance/shipped/moflo-claude-swarm-cohesion.md +4 -0
- package/.claude/guidance/shipped/moflo-memory-strategy.md +1 -0
- package/.claude/guidance/shipped/moflo-sdd.md +21 -6
- package/.claude/guidance/shipped/moflo-spell-engine.md +13 -10
- package/.claude/guidance/shipped/moflo-spell-runner.md +34 -0
- package/.claude/guidance/shipped/moflo-spell-scheduling.md +30 -0
- package/.claude/guidance/shipped/moflo-yaml-reference.md +52 -0
- package/.claude/helpers/gate-hook.mjs +76 -2
- package/.claude/helpers/gate.cjs +795 -26
- package/.claude/helpers/hook-handler.cjs +0 -0
- package/.claude/helpers/prompt-hook.mjs +9 -0
- package/.claude/helpers/statusline.cjs +59 -5
- package/.claude/skills/connector-builder/SKILL.md +5 -4
- package/.claude/skills/fl/execution-modes.md +9 -0
- package/.claude/skills/fl/phases.md +31 -34
- package/.claude/skills/fl/sdd.md +1 -1
- package/.claude/skills/flo-simplify/SKILL.md +3 -1
- package/.claude/skills/publish/SKILL.md +80 -19
- package/.claude/skills/spell-builder/SKILL.md +5 -4
- package/.claude/skills/spell-builder/architecture.md +4 -4
- package/.claude/skills/spell-builder/connectors/github-cli/README.md +22 -17
- package/.claude/skills/spell-builder/connectors/http/README.md +18 -11
- package/.claude/skills/spell-builder/connectors/local-outlook/README.md +8 -7
- package/.claude/skills/spell-builder/connectors/playwright/README.md +10 -8
- package/.claude/skills/spell-builder/steps/agent/README.md +25 -21
- package/.claude/skills/verify/SKILL.md +30 -5
- package/README.md +0 -1
- package/bin/build-embeddings.mjs +49 -24
- package/bin/gate-hook.mjs +76 -2
- package/bin/gate.cjs +795 -26
- package/bin/generate-code-map.mjs +70 -17
- package/bin/index-all.mjs +38 -0
- package/bin/index-guidance.mjs +161 -113
- package/bin/index-patterns.mjs +11 -5
- package/bin/index-tests.mjs +6 -4
- package/bin/lib/embedding-backlog.mjs +96 -0
- package/bin/lib/get-backend.mjs +57 -4
- package/bin/lib/guidance-config.mjs +119 -0
- package/bin/lib/incremental-write.mjs +17 -3
- package/bin/lib/index-fingerprint.mjs +0 -0
- package/bin/migrations/purge-spec-chunks.mjs +79 -0
- package/bin/prompt-hook.mjs +9 -0
- package/bin/session-start-launcher.mjs +87 -25
- package/dist/src/cli/commands/agent.js +1 -89
- package/dist/src/cli/commands/analyze.js +1 -1
- package/dist/src/cli/commands/benchmark.js +11 -8
- package/dist/src/cli/commands/claims.js +2 -2
- package/dist/src/cli/commands/completions.js +1 -1
- package/dist/src/cli/commands/config.js +256 -96
- package/dist/src/cli/commands/deployment.js +6 -6
- package/dist/src/cli/commands/diagnose.js +1 -1
- package/dist/src/cli/commands/doctor-checks-config.js +18 -22
- package/dist/src/cli/commands/doctor-checks-deep.js +4 -1
- package/dist/src/cli/commands/doctor-checks-swarm.js +13 -2
- package/dist/src/cli/commands/doctor-embedding-hygiene.js +15 -1
- package/dist/src/cli/commands/doctor-fixes.js +130 -13
- package/dist/src/cli/commands/doctor.js +1 -1
- package/dist/src/cli/commands/embeddings.js +64 -23
- package/dist/src/cli/commands/github.js +1 -1
- package/dist/src/cli/commands/guidance.js +10 -10
- package/dist/src/cli/commands/hive-mind.js +8 -70
- package/dist/src/cli/commands/hooks.js +32 -219
- package/dist/src/cli/commands/index.js +3 -0
- package/dist/src/cli/commands/mcp.js +5 -2
- package/dist/src/cli/commands/memory.js +74 -49
- package/dist/src/cli/commands/neural.js +24 -24
- package/dist/src/cli/commands/performance.js +26 -15
- package/dist/src/cli/commands/plugins.js +2 -2
- package/dist/src/cli/commands/providers.js +2 -2
- package/dist/src/cli/commands/retire.js +1 -1
- package/dist/src/cli/commands/route.js +1 -1
- package/dist/src/cli/commands/runs.js +247 -0
- package/dist/src/cli/commands/security.js +4 -4
- package/dist/src/cli/commands/start.js +4 -7
- package/dist/src/cli/commands/status.js +33 -21
- package/dist/src/cli/commands/task.js +8 -0
- package/dist/src/cli/config/cli-config-store.js +326 -0
- package/dist/src/cli/hooks/workers/index.js +15 -9
- package/dist/src/cli/index.js +44 -34
- package/dist/src/cli/init/claudemd-generator.js +3 -3
- package/dist/src/cli/init/helpers-generator.js +331 -27
- package/dist/src/cli/init/moflo-init.js +16 -6
- package/dist/src/cli/init/moflo-yaml-template.js +40 -3
- package/dist/src/cli/init/settings-generator.js +31 -10
- package/dist/src/cli/mcp-client.js +12 -2
- package/dist/src/cli/mcp-server.js +5 -23
- package/dist/src/cli/mcp-tools/analysis-tools.js +103 -0
- package/dist/src/cli/mcp-tools/coverage-tools.js +206 -0
- package/dist/src/cli/mcp-tools/hive-mind-tools.js +71 -0
- package/dist/src/cli/mcp-tools/hooks-tools.js +25 -9
- package/dist/src/cli/mcp-tools/memory-admin-tools.js +544 -0
- package/dist/src/cli/mcp-tools/memory-tools.js +26 -5
- package/dist/src/cli/mcp-tools/neural-tools.js +56 -87
- package/dist/src/cli/mcp-tools/performance-tools.js +76 -39
- package/dist/src/cli/mcp-tools/progress-tools.js +142 -0
- package/dist/src/cli/mcp-tools/security-tools.js +1 -1
- package/dist/src/cli/mcp-tools/session-tools.js +116 -0
- package/dist/src/cli/mcp-tools/spell-tools.js +10 -2
- package/dist/src/cli/mcp-tools/synthetic.js +74 -0
- package/dist/src/cli/mcp-tools/system-tools.js +126 -78
- package/dist/src/cli/mcp-tools/task-tools.js +101 -1
- package/dist/src/cli/memory/bridge-embedder.js +28 -0
- package/dist/src/cli/memory/bridge-entries.js +148 -22
- package/dist/src/cli/memory/hnsw-lite.js +57 -13
- package/dist/src/cli/memory/hnsw-persistence.js +375 -18
- package/dist/src/cli/memory/hnsw-sidecar-lock.js +272 -0
- package/dist/src/cli/memory/hnsw-singleton.js +52 -1
- package/dist/src/cli/memory/index.js +1 -1
- package/dist/src/cli/memory/memory-initializer.js +1 -1
- package/dist/src/cli/movector/coverage-router.js +48 -6
- package/dist/src/cli/movector/diff-classifier.js +8 -6
- package/dist/src/cli/movector/flash-attention.js +1 -1
- package/dist/src/cli/movector/vector-db.js +1 -1
- package/dist/src/cli/parser.js +81 -12
- package/dist/src/cli/runtime/headless.js +8 -8
- package/dist/src/cli/services/cherry-pick-learnings.js +10 -1
- package/dist/src/cli/services/daemon-dashboard.js +15 -0
- package/dist/src/cli/services/daemon-lock.js +5 -2
- package/dist/src/cli/services/daemon-spell-executor.js +18 -1
- package/dist/src/cli/services/ephemeral-namespace-purge.js +97 -34
- package/dist/src/cli/services/hook-block-hash.js +11 -3
- package/dist/src/cli/services/hook-wiring.js +91 -2
- package/dist/src/cli/services/moflo-version.js +62 -0
- package/dist/src/cli/services/movector-training.js +1 -1
- package/dist/src/cli/services/run-token-rollup.js +168 -0
- package/dist/src/cli/services/spell-gate.js +6 -4
- package/dist/src/cli/services/worker-daemon.js +37 -7
- package/dist/src/cli/shared/hooks/safety/git-commit.js +6 -2
- package/dist/src/cli/shared/utils/load-average.js +59 -0
- package/dist/src/cli/shared/utils/project-initialized.js +52 -0
- package/dist/src/cli/spells/commands/agent-command.js +55 -25
- package/dist/src/cli/spells/commands/bash-command.js +17 -0
- package/dist/src/cli/spells/core/run-budget.js +331 -0
- package/dist/src/cli/spells/core/run-ledger.js +139 -0
- package/dist/src/cli/spells/core/runner.js +113 -11
- package/dist/src/cli/spells/core/step-retry.js +147 -0
- package/dist/src/cli/spells/factory/pause-resume.js +25 -2
- package/dist/src/cli/spells/factory/runner-bridge.js +2 -0
- package/dist/src/cli/spells/factory/runner-factory.js +11 -0
- package/dist/src/cli/spells/index.js +1 -0
- package/dist/src/cli/spells/schema/validator.js +2 -1
- package/dist/src/cli/spells/schema/validators/steps.js +44 -0
- package/dist/src/cli/spells/schema/validators/top-level.js +37 -0
- package/dist/src/cli/suggest.js +1 -1
- package/dist/src/cli/swarm/swarm-persistence.js +112 -0
- package/dist/src/cli/swarm/unified-coordinator.js +146 -3
- package/dist/src/cli/version.js +1 -1
- package/package.json +5 -3
- package/dist/src/cli/mcp-tools/github-tools.js +0 -318
|
@@ -195,36 +195,29 @@ src/
|
|
|
195
195
|
## MCP Tool Integration
|
|
196
196
|
|
|
197
197
|
### Memory Coordination
|
|
198
|
-
```javascript
|
|
199
|
-
// Report implementation status
|
|
200
|
-
mcp__moflo__memory_store {
|
|
201
|
-
key: "swarm/coder/status",
|
|
202
|
-
namespace: "coordination",
|
|
203
|
-
value: JSON.stringify({
|
|
204
|
-
agent: "coder",
|
|
205
|
-
status: "implementing",
|
|
206
|
-
feature: "user authentication",
|
|
207
|
-
files: ["auth.service.ts", "auth.controller.ts"],
|
|
208
|
-
timestamp: Date.now()
|
|
209
|
-
})
|
|
210
|
-
}
|
|
211
198
|
|
|
199
|
+
Store decisions that outlive this run, in the namespaces named in your operating
|
|
200
|
+
context above. Prose in `value` — it is what gets embedded, so a JSON blob
|
|
201
|
+
retrieves badly; structure goes in `metadata`, stored verbatim.
|
|
202
|
+
|
|
203
|
+
```javascript
|
|
212
204
|
// Share code decisions
|
|
213
205
|
mcp__moflo__memory_store {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
value:
|
|
217
|
-
|
|
206
|
+
namespace: "patterns",
|
|
207
|
+
key: "auth-service-shape",
|
|
208
|
+
value: "Auth is a singleton service behind a factory so the jwt signer can be swapped in tests; endpoints are /auth/login and /auth/logout on the express router.",
|
|
209
|
+
metadata: {
|
|
218
210
|
patterns: ["singleton", "factory"],
|
|
219
211
|
dependencies: ["express", "jwt"],
|
|
220
|
-
|
|
221
|
-
}
|
|
212
|
+
apiEndpoints: ["/auth/login", "/auth/logout"]
|
|
213
|
+
}
|
|
222
214
|
}
|
|
223
215
|
|
|
224
|
-
//
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
216
|
+
// Look up what an earlier agent established. Semantic search first — reach for
|
|
217
|
+
// memory_retrieve only when you already know the exact key.
|
|
218
|
+
mcp__moflo__memory_search {
|
|
219
|
+
query: "auth service dependencies",
|
|
220
|
+
namespace: "patterns"
|
|
228
221
|
}
|
|
229
222
|
```
|
|
230
223
|
|
|
@@ -232,14 +225,13 @@ mcp__moflo__memory_retrieve {
|
|
|
232
225
|
```javascript
|
|
233
226
|
// Track implementation metrics
|
|
234
227
|
mcp__moflo__performance_benchmark {
|
|
235
|
-
|
|
228
|
+
suite: "memory",
|
|
236
229
|
iterations: 10
|
|
237
230
|
}
|
|
238
231
|
|
|
239
|
-
//
|
|
232
|
+
// Read this process's CPU / memory / heap usage
|
|
240
233
|
mcp__moflo__performance_report {
|
|
241
|
-
|
|
242
|
-
metrics: ["response-time", "memory-usage"]
|
|
234
|
+
format: "detailed"
|
|
243
235
|
}
|
|
244
236
|
```
|
|
245
237
|
|
|
@@ -114,45 +114,67 @@ plan:
|
|
|
114
114
|
## MCP Tool Integration
|
|
115
115
|
|
|
116
116
|
### Task Orchestration
|
|
117
|
-
```javascript
|
|
118
|
-
// Orchestrate complex tasks
|
|
119
117
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
118
|
+
Submit the breakdown to the coordinator. A task ID only exists once the
|
|
119
|
+
coordinator has issued it — storing a breakdown in memory dispatches nothing,
|
|
120
|
+
and polling an ID you invented yourself always comes back empty.
|
|
121
|
+
|
|
122
|
+
```javascript
|
|
123
|
+
// Submit the whole breakdown in one call. Tasks are load-balanced across
|
|
124
|
+
// available agents; `type` must be one of research | analysis | coding |
|
|
125
|
+
// testing | review | documentation | coordination | consensus | custom.
|
|
126
|
+
mcp__moflo__task_orchestrate {
|
|
127
|
+
tasks: [
|
|
128
|
+
{ type: "research", description: "Research auth libraries", priority: "high" },
|
|
129
|
+
{ type: "analysis", description: "Design auth flow", priority: "high" },
|
|
130
|
+
{ type: "coding", description: "Implement auth service", priority: "normal" },
|
|
131
|
+
{ type: "testing", description: "Write auth tests", priority: "normal" }
|
|
132
|
+
]
|
|
134
133
|
}
|
|
134
|
+
// → { success: true, submitted: 4, assigned: 3, queued: 1,
|
|
135
|
+
// tasks: [ { taskId: "task_...", status: "assigned", ... }, ... ] }
|
|
135
136
|
|
|
136
|
-
//
|
|
137
|
+
// Poll an ID the coordinator returned — never one you named yourself.
|
|
137
138
|
mcp__moflo__task_status {
|
|
138
|
-
taskId: "
|
|
139
|
+
taskId: "<taskId from the response above>"
|
|
139
140
|
}
|
|
141
|
+
|
|
142
|
+
// Or survey everything in flight instead of polling one at a time.
|
|
143
|
+
mcp__moflo__task_list { status: "running,queued" }
|
|
140
144
|
```
|
|
141
145
|
|
|
146
|
+
Use `mcp__moflo__task_create` for a single task; it takes the same fields and
|
|
147
|
+
returns the same projection, including the `taskId`.
|
|
148
|
+
|
|
149
|
+
**Ordering lives on the native Task layer, not here.** `task_create` and
|
|
150
|
+
`task_orchestrate` accept no dependency field — the coordinator load-balances
|
|
151
|
+
what you submit. Express prerequisites with `TaskUpdate({ addBlockedBy: [...] })`
|
|
152
|
+
on the native tasks, per *What → Native Tasks; How → MoFlo orchestration* in
|
|
153
|
+
`.claude/guidance/moflo-claude-swarm-cohesion.md`.
|
|
154
|
+
|
|
142
155
|
### Memory Coordination
|
|
156
|
+
|
|
157
|
+
Live task state belongs to the coordinator — read it with `task_status` /
|
|
158
|
+
`task_list` rather than mirroring it into memory. Store what stays useful after
|
|
159
|
+
this run: a decision and its rationale that a future agent would otherwise have
|
|
160
|
+
to rediscover.
|
|
161
|
+
|
|
143
162
|
```javascript
|
|
144
|
-
//
|
|
163
|
+
// Prose in `value` — it is what gets embedded, so a JSON blob retrieves badly.
|
|
164
|
+
// Structure goes in `metadata`, which is stored verbatim and not embedded.
|
|
145
165
|
mcp__moflo__memory_store {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
value:
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
timestamp: Date.now()
|
|
154
|
-
})
|
|
166
|
+
namespace: "patterns",
|
|
167
|
+
key: "auth-rollout-sequencing",
|
|
168
|
+
value: "Auth work is sequenced research → design → implement → test because the library choice determines the flow design; parallelising design against research produced rework twice.",
|
|
169
|
+
metadata: {
|
|
170
|
+
plannedTasks: 12,
|
|
171
|
+
blockedOn: ["library selection"]
|
|
172
|
+
}
|
|
155
173
|
}
|
|
156
174
|
```
|
|
157
175
|
|
|
158
|
-
|
|
176
|
+
Use the namespaces named in this agent's operating context above — `patterns`
|
|
177
|
+
for reusable approaches, `learnings` for decisions and gotchas. The `swarm-*`
|
|
178
|
+
namespaces are the coordinator's own persistence; do not write to them.
|
|
179
|
+
|
|
180
|
+
Remember: A good plan executed now is better than a perfect plan executed never. Focus on creating actionable, practical plans that drive progress. Dispatch through the coordinator; use memory for what outlives the run.
|
|
@@ -119,46 +119,38 @@ read specific-file.ts
|
|
|
119
119
|
## MCP Tool Integration
|
|
120
120
|
|
|
121
121
|
### Memory Coordination
|
|
122
|
-
```javascript
|
|
123
|
-
// Report research status
|
|
124
|
-
mcp__moflo__memory_store {
|
|
125
|
-
key: "swarm/researcher/status",
|
|
126
|
-
namespace: "coordination",
|
|
127
|
-
value: JSON.stringify({
|
|
128
|
-
agent: "researcher",
|
|
129
|
-
status: "analyzing",
|
|
130
|
-
focus: "authentication system",
|
|
131
|
-
files_reviewed: 25,
|
|
132
|
-
timestamp: Date.now()
|
|
133
|
-
})
|
|
134
|
-
}
|
|
135
122
|
|
|
123
|
+
Store findings that stay useful after this run, in the namespaces named in your
|
|
124
|
+
operating context above. Prose in `value` — it is what gets embedded, so a JSON
|
|
125
|
+
blob retrieves badly; structure goes in `metadata`, stored verbatim.
|
|
126
|
+
|
|
127
|
+
```javascript
|
|
136
128
|
// Share research findings
|
|
137
129
|
mcp__moflo__memory_store {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
value:
|
|
141
|
-
|
|
130
|
+
namespace: "patterns",
|
|
131
|
+
key: "auth-stack-survey",
|
|
132
|
+
value: "Auth here is passport + jwt behind an MVC/repository split; the passport version is two majors behind and there is no rate limiting on the login route.",
|
|
133
|
+
metadata: {
|
|
134
|
+
patternsFound: ["MVC", "Repository", "Factory"],
|
|
142
135
|
dependencies: ["express", "passport", "jwt"],
|
|
143
|
-
potential_issues: ["outdated auth library", "missing rate limiting"],
|
|
144
136
|
recommendations: ["upgrade passport", "add rate limiter"]
|
|
145
|
-
}
|
|
137
|
+
}
|
|
146
138
|
}
|
|
147
139
|
|
|
148
|
-
// Check prior research
|
|
140
|
+
// Check prior research. memory_search is semantic — it takes a `query`, not a
|
|
141
|
+
// key glob. Pivot the query on the bare symbol or topic.
|
|
149
142
|
mcp__moflo__memory_search {
|
|
150
|
-
|
|
151
|
-
namespace: "
|
|
143
|
+
query: "authentication stack",
|
|
144
|
+
namespace: "patterns",
|
|
152
145
|
limit: 10
|
|
153
146
|
}
|
|
154
147
|
```
|
|
155
148
|
|
|
156
149
|
### Analysis Tools
|
|
157
150
|
```javascript
|
|
158
|
-
//
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
analysis_type: "code_quality"
|
|
151
|
+
// Understand what a change touches and how risky it is
|
|
152
|
+
mcp__moflo__analyze_diff {
|
|
153
|
+
ref: "main"
|
|
162
154
|
}
|
|
163
155
|
|
|
164
156
|
// Track research metrics
|
|
@@ -172,14 +164,14 @@ mcp__moflo__agent_status {
|
|
|
172
164
|
- Share findings with planner for task decomposition via memory
|
|
173
165
|
- Provide context to coder for implementation through shared memory
|
|
174
166
|
- Supply tester with edge cases and scenarios in memory
|
|
175
|
-
- Document
|
|
167
|
+
- Document findings in the `patterns` namespace so later agents retrieve them
|
|
176
168
|
|
|
177
169
|
## Best Practices
|
|
178
170
|
|
|
179
171
|
1. **Be Thorough**: Check multiple sources and validate findings
|
|
180
172
|
2. **Stay Organized**: Structure research logically and maintain clear notes
|
|
181
173
|
3. **Think Critically**: Question assumptions and verify claims
|
|
182
|
-
4. **Document Everything**: Store
|
|
174
|
+
4. **Document Everything**: Store findings in `patterns` (or `learnings` for decisions and gotchas)
|
|
183
175
|
5. **Iterate**: Refine research based on new discoveries
|
|
184
176
|
6. **Share Early**: Update memory frequently for real-time coordination
|
|
185
177
|
|
|
@@ -269,51 +269,42 @@ npm run complexity-check
|
|
|
269
269
|
## MCP Tool Integration
|
|
270
270
|
|
|
271
271
|
### Memory Coordination
|
|
272
|
-
```javascript
|
|
273
|
-
// Report review status
|
|
274
|
-
mcp__moflo__memory_store {
|
|
275
|
-
key: "swarm/reviewer/status",
|
|
276
|
-
namespace: "coordination",
|
|
277
|
-
value: JSON.stringify({
|
|
278
|
-
agent: "reviewer",
|
|
279
|
-
status: "reviewing",
|
|
280
|
-
files_reviewed: 12,
|
|
281
|
-
issues_found: {critical: 2, major: 5, minor: 8},
|
|
282
|
-
timestamp: Date.now()
|
|
283
|
-
})
|
|
284
|
-
}
|
|
285
272
|
|
|
273
|
+
Store findings that outlive this run, in the namespaces named in your operating
|
|
274
|
+
context above. Prose in `value` — it is what gets embedded, so a JSON blob
|
|
275
|
+
retrieves badly; structure goes in `metadata`, stored verbatim.
|
|
276
|
+
|
|
277
|
+
```javascript
|
|
286
278
|
// Share review findings
|
|
287
279
|
mcp__moflo__memory_store {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
value:
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
}
|
|
280
|
+
namespace: "patterns",
|
|
281
|
+
key: "auth-review-findings",
|
|
282
|
+
value: "Login builds its SQL by string concatenation (auth.js:45) and the user service loads roles per-row inside a loop, so both the injection risk and the N+1 come from the same request path.",
|
|
283
|
+
metadata: {
|
|
284
|
+
securityIssues: ["SQL injection in auth.js:45"],
|
|
285
|
+
performanceIssues: ["N+1 queries in user.service.ts"],
|
|
286
|
+
actionItems: ["Fix SQL injection", "Batch the role lookup", "Add tests"]
|
|
287
|
+
}
|
|
296
288
|
}
|
|
297
289
|
|
|
298
|
-
//
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
290
|
+
// Look up what the implementer established. Semantic search first — reach for
|
|
291
|
+
// memory_retrieve only when you already know the exact key.
|
|
292
|
+
mcp__moflo__memory_search {
|
|
293
|
+
query: "auth service shape",
|
|
294
|
+
namespace: "patterns"
|
|
302
295
|
}
|
|
303
296
|
```
|
|
304
297
|
|
|
305
298
|
### Code Analysis
|
|
306
299
|
```javascript
|
|
307
|
-
//
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
analysis_type: "code_quality"
|
|
300
|
+
// Assess the risk and shape of the change under review
|
|
301
|
+
mcp__moflo__analyze_diff {
|
|
302
|
+
ref: "main"
|
|
311
303
|
}
|
|
312
304
|
|
|
313
|
-
//
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
analysis_type: "security"
|
|
305
|
+
// Scan the diff for prompt-injection and unsafe content
|
|
306
|
+
mcp__moflo__aidefence_scan {
|
|
307
|
+
input: "<the diff or file under review>"
|
|
317
308
|
}
|
|
318
309
|
```
|
|
319
310
|
|
|
@@ -251,35 +251,30 @@ describe('Security', () => {
|
|
|
251
251
|
## MCP Tool Integration
|
|
252
252
|
|
|
253
253
|
### Memory Coordination
|
|
254
|
-
```javascript
|
|
255
|
-
// Report test status
|
|
256
|
-
mcp__moflo__memory_store {
|
|
257
|
-
key: "swarm/tester/status",
|
|
258
|
-
namespace: "coordination",
|
|
259
|
-
value: JSON.stringify({
|
|
260
|
-
agent: "tester",
|
|
261
|
-
status: "running tests",
|
|
262
|
-
test_suites: ["unit", "integration", "e2e"],
|
|
263
|
-
timestamp: Date.now()
|
|
264
|
-
})
|
|
265
|
-
}
|
|
266
254
|
|
|
267
|
-
|
|
255
|
+
Store what stays useful after this run, in the namespaces named in your
|
|
256
|
+
operating context above. Prose in `value` — it is what gets embedded, so a JSON
|
|
257
|
+
blob retrieves badly; structure goes in `metadata`, stored verbatim.
|
|
258
|
+
|
|
259
|
+
```javascript
|
|
260
|
+
// Share what the run revealed, not the raw tally
|
|
268
261
|
mcp__moflo__memory_store {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
value:
|
|
262
|
+
namespace: "patterns",
|
|
263
|
+
key: "auth-suite-flakiness",
|
|
264
|
+
value: "The two failing auth tests both assert on token expiry against a real clock, so they fail whenever the suite runs slowly under load — freeze the clock rather than widening the tolerance.",
|
|
265
|
+
metadata: {
|
|
272
266
|
passed: 145,
|
|
273
267
|
failed: 2,
|
|
274
268
|
coverage: "87%",
|
|
275
269
|
failures: ["auth.test.ts:45", "api.test.ts:123"]
|
|
276
|
-
}
|
|
270
|
+
}
|
|
277
271
|
}
|
|
278
272
|
|
|
279
|
-
//
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
273
|
+
// Look up what the implementer established. Semantic search first — reach for
|
|
274
|
+
// memory_retrieve only when you already know the exact key.
|
|
275
|
+
mcp__moflo__memory_search {
|
|
276
|
+
query: "auth service shape",
|
|
277
|
+
namespace: "patterns"
|
|
283
278
|
}
|
|
284
279
|
```
|
|
285
280
|
|
|
@@ -287,7 +282,7 @@ mcp__moflo__memory_retrieve {
|
|
|
287
282
|
```javascript
|
|
288
283
|
// Run performance benchmarks
|
|
289
284
|
mcp__moflo__performance_benchmark {
|
|
290
|
-
|
|
285
|
+
suite: "all",
|
|
291
286
|
iterations: 100
|
|
292
287
|
}
|
|
293
288
|
|
|
@@ -94,6 +94,8 @@ npx flo hive-mind init --topology hierarchical-mesh --consensus byzantine
|
|
|
94
94
|
|
|
95
95
|
Include task IDs in agent prompts. The `SubagentStart` hook automatically injects the subagent protocol directive — don't repeat it.
|
|
96
96
|
|
|
97
|
+
Asking for a swarm is asking for agents: an ambient "don't call the Agent tool unless the user requested it" is satisfied by that request. Registering agents via MCP without dispatching them leaves a swarm that passes every gate and does no parallel work.
|
|
98
|
+
|
|
97
99
|
```javascript
|
|
98
100
|
TaskUpdate({ taskId: "1", status: "in_progress" })
|
|
99
101
|
Task({
|
|
@@ -117,6 +119,8 @@ TaskList() // Shows what's now unblocked
|
|
|
117
119
|
TaskUpdate({ taskId: "2", status: "in_progress" }) // Next agent starts
|
|
118
120
|
```
|
|
119
121
|
|
|
122
|
+
Close every task you open. moflo's PR gate reads the session transcript on `gh pr create` and prints `N tasks created this session, M still open` (#1374) — an unclosed list reports as unfinished work on the PR. Mark tasks that no longer apply `status: "deleted"`; that closes the loop exactly like `completed`.
|
|
123
|
+
|
|
120
124
|
---
|
|
121
125
|
|
|
122
126
|
## Coordinator Responsibilities
|
|
@@ -35,6 +35,7 @@ Source files (`.claude/guidance/*.md`, `docs/**/*.md`, code, tests) flow through
|
|
|
35
35
|
| `patterns` | Per-file code patterns (services, routes, exports) | `index-patterns.mjs` |
|
|
36
36
|
| `tests` | Test structure and patterns | `index-tests.mjs` |
|
|
37
37
|
| `learnings` | User-stored patterns from work sessions | `mcp__moflo__memory_store` |
|
|
38
|
+
| `verify` | Per-run `/verify` verdict records, keyed `verify:<slug>` | `/verify` skill Step 5 |
|
|
38
39
|
|
|
39
40
|
Namespaces are independent indexes. Search defaults to `all`; pass `namespace: "guidance"` to target one.
|
|
40
41
|
|
|
@@ -27,16 +27,31 @@ Specs and plans persist as Markdown, one directory per unit of work, under the c
|
|
|
27
27
|
<specs_dir>/<slug>/plan.md # the "steps" + how each criterion is verified
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
**Always create and mutate them through the `flo sdd` CLI** — never hand-write the path in a skill step (cross-platform, Rule #1: the CLI builds every path with `path.join`).
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
### Specs are NOT indexed into memory
|
|
33
|
+
|
|
34
|
+
Earlier versions indexed `spec.md` / `plan.md` into the `guidance` namespace. They no longer are, and the specs directory is excluded from the guidance walk even when it sits inside a `guidance.directories` entry.
|
|
35
|
+
|
|
36
|
+
A spec is pre-implementation intent for **one** unit of work, not a project rule. Once implemented it is stale-by-construction, and specs accumulate without bound — so a superseded approach kept surfacing at high similarity alongside real guidance, and the namespace degraded as the project aged. Nothing was gained in exchange: the active spec's path is already known (the `flo sdd` CLI just returned it), so **read it from disk** rather than searching for it.
|
|
37
|
+
|
|
38
|
+
| To… | Use |
|
|
39
|
+
|---|---|
|
|
40
|
+
| Read the spec/plan you are working on | `Read` the path `flo sdd` returned |
|
|
41
|
+
| Find prior specs across sessions | `flo sdd list` / `flo sdd status <slug>` |
|
|
42
|
+
| Recall what an implementation actually taught you | `memory_search` namespace `learnings` |
|
|
43
|
+
| Recall a past verify verdict | `memory_search` namespace `verify` |
|
|
44
|
+
|
|
45
|
+
Existing spec rows are removed by the `purge-spec-chunks` migration on the next session start.
|
|
46
|
+
|
|
47
|
+
**Where specs live is configurable (`sdd.specs_dir`, #1294).** The default `.moflo/specs` is **gitignored** by `flo init`. To make specs reviewable in the PR, point `sdd.specs_dir` at a **tracked** path and commit them:
|
|
33
48
|
|
|
34
49
|
| `sdd.specs_dir` | Committed? | Use when |
|
|
35
50
|
|-----------------|------------|----------|
|
|
36
|
-
| `.moflo/specs` (default) | No (gitignored) |
|
|
37
|
-
| `docs/specs`, `.specs`, … (tracked) | Yes | You want
|
|
51
|
+
| `.moflo/specs` (default) | No (gitignored) | Specs are scratch — the PR body carries the acceptance criteria. Best at high spec volume. |
|
|
52
|
+
| `docs/specs`, `.specs`, … (tracked) | Yes | You want the spec diffed and reviewed alongside the code |
|
|
38
53
|
|
|
39
|
-
Set it once in `moflo.yaml`; the `flo sdd` CLI and the session-start indexer both honor it
|
|
54
|
+
Set it once in `moflo.yaml`; the `flo sdd` CLI and the session-start indexer both honor it — the CLI to write specs there, the indexer to exclude them.
|
|
40
55
|
|
|
41
56
|
Each artifact carries a `status` of `draft` or `reviewed` in its frontmatter. The constitution layer (`CLAUDE.md` + `.claude/guidance/`) is referenced by every stage — never restate its invariants inside a spec.
|
|
42
57
|
|
|
@@ -64,7 +79,7 @@ The two review checkpoints are the point: **a spec must be reviewed before its p
|
|
|
64
79
|
When enforced, `gh pr create` is blocked until the change has been verified end-to-end since the last code edit.
|
|
65
80
|
|
|
66
81
|
- **On by default (#1294).** Enforced for every `/flo` run; disable per-project with `gates.verify_before_done: false` or per-run with `--no-verify`. On upgrade, consumers with no `verify_before_done` key start enforcing; an explicit value is preserved. Docs-only diffs are exempt, so a pure-docs PR is never blocked.
|
|
67
|
-
- **Satisfy it by running the `/verify` skill** — `/flo` delegates to it. It exercises the change against the plan's (or ticket's) acceptance criteria and records its own outcome to memory (`namespace:
|
|
82
|
+
- **Satisfy it by running the `/verify` skill** — `/flo` delegates to it. It exercises the change against the plan's (or ticket's) acceptance criteria and records its own outcome to memory (`namespace: verify, key: verify:<slug>`). It reuses the Tests-phase run rather than repeating it (no double verify).
|
|
68
83
|
- **A source edit invalidates a prior verification** — re-run `/verify` after editing. `/ward` and `/quicken` are targeted audits, not the completion gate.
|
|
69
84
|
|
|
70
85
|
---
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Spell Engine — Definition Format & Step Types
|
|
2
2
|
|
|
3
|
-
**Purpose:** How to define a spell (YAML/JSON schema, arguments, steps, variable interpolation) and a reference for the
|
|
3
|
+
**Purpose:** How to define a spell (YAML/JSON schema, arguments, steps, variable interpolation) and a reference for the built-in step command types. For execution mechanics (running, dry-run, error codes, pause/resume, layering, credentials), see `.claude/guidance/moflo-spell-runner.md`.
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -96,16 +96,16 @@ steps:
|
|
|
96
96
|
config:
|
|
97
97
|
command: "curl -s {args.api_url}"
|
|
98
98
|
- id: process
|
|
99
|
-
type:
|
|
99
|
+
type: bash
|
|
100
100
|
config:
|
|
101
|
-
|
|
101
|
+
command: 'claude -p "Analyze this response: {fetch-url.stdout}"'
|
|
102
102
|
```
|
|
103
103
|
|
|
104
104
|
---
|
|
105
105
|
|
|
106
106
|
## Step Command Types
|
|
107
107
|
|
|
108
|
-
**
|
|
108
|
+
**Fifteen built-in step types are registered automatically** (one of them, `agent`, is registered but not executable — see below). Each implements `execute()`, `validate()`, `describeOutputs()`, and optional `rollback()`. To add new step types via JS/TS files, YAML composite steps, or `moflo-step-*` npm packages, see `.claude/guidance/moflo-spell-custom-steps.md`.
|
|
109
109
|
|
|
110
110
|
### bash — Run a Shell Command
|
|
111
111
|
|
|
@@ -122,18 +122,21 @@ steps:
|
|
|
122
122
|
|
|
123
123
|
---
|
|
124
124
|
|
|
125
|
-
### agent —
|
|
125
|
+
### agent — NOT EXECUTABLE
|
|
126
|
+
|
|
127
|
+
**Do not use this step type.** It has never spawned a subagent — moflo has no agent spawner in the spell runner. It is still registered so existing spell YAML keeps parsing, but casting it now always fails with an explanatory error (#1334). Earlier versions returned `success: true` and a `result` string for work that never happened.
|
|
128
|
+
|
|
129
|
+
**To run a Claude subagent from a spell, use a `bash` step:**
|
|
126
130
|
|
|
127
131
|
```yaml
|
|
128
132
|
- id: research
|
|
129
|
-
type:
|
|
133
|
+
type: bash
|
|
130
134
|
config:
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
background: false # Optional. Default false.
|
|
135
|
+
command: 'claude -p "Find all API endpoints in {args.directory}"'
|
|
136
|
+
timeout: 300000
|
|
134
137
|
```
|
|
135
138
|
|
|
136
|
-
**Outputs:**
|
|
139
|
+
**Outputs:** none — the step always fails. `agentType` and `prompt` are echoed in the failure for diagnosis only.
|
|
137
140
|
|
|
138
141
|
---
|
|
139
142
|
|
|
@@ -93,6 +93,40 @@ const result = loadSpellByName('deploy-staging', { /* same options */ });
|
|
|
93
93
|
|
|
94
94
|
**Set `continueOnError: true` on a step to keep running after failure.** The failed step is recorded in results but execution continues. Without this flag, a step failure triggers rollback of completed steps and terminates the spell.
|
|
95
95
|
|
|
96
|
+
### retry
|
|
97
|
+
|
|
98
|
+
**Add a `retry` block to a step that can fail transiently — a flaky HTTP call, a rate limit, a momentary network drop.** Without it, one transient failure discards every completed step in the run. This matters most on the scheduled path, where a run dying at step 7 of 9 at 3am produces a failed record and no work.
|
|
99
|
+
|
|
100
|
+
```yaml
|
|
101
|
+
- id: fetch-report
|
|
102
|
+
type: http
|
|
103
|
+
retry:
|
|
104
|
+
attempts: 3 # total attempts INCLUDING the first
|
|
105
|
+
backoffMs: 1000 # base delay before attempt 2; doubles thereafter
|
|
106
|
+
maxDelayMs: 30000 # optional: ceiling on any single delay
|
|
107
|
+
maxTotalDelayMs: 60000 # optional: ceiling on the sum of all delays
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**Retry is opt-in per step and never applied by default.** Blanket retry is wrong for non-idempotent work — silently re-running a step that posts to Slack or writes a file is worse than failing. A step with no `retry` block runs exactly once, exactly as before.
|
|
111
|
+
|
|
112
|
+
**Only non-deterministic failures are retried.**
|
|
113
|
+
|
|
114
|
+
| Failure | Retried? | Why |
|
|
115
|
+
|---------|----------|-----|
|
|
116
|
+
| Step returned failure / threw | Yes | The classic transient case |
|
|
117
|
+
| Step timed out | Yes | May succeed when the upstream recovers |
|
|
118
|
+
| Capability violation, unknown step type, invalid config | No | Deterministic — N attempts produce one outcome at N times the cost |
|
|
119
|
+
| Auth-shaped error (401, expired token) | No | Owned by the credential-refresh path below, which can actually fix it |
|
|
120
|
+
| Cancelled | No | The run is already tearing down |
|
|
121
|
+
|
|
122
|
+
**Backoff is bounded twice and interruptible.** Each delay is capped by `maxDelayMs`, their sum by `maxTotalDelayMs` (60s default) — so `attempts: 50` cannot stall a scheduled run. Once the aggregate budget is spent, remaining attempts run back-to-back rather than being cancelled. The wait also aborts on the run's signal, so a wall-clock ceiling breach (`spells.budget.*.maxWallClockMs`) cuts a backoff short instead of being served after it. Delays carry ±10% jitter so a `parallel` block of steps hitting the same rate limit does not retry in lockstep.
|
|
123
|
+
|
|
124
|
+
**Each attempt is billed independently.** A retried step that spawns `claude -p` consumes one `maxModelInvocations` reservation per attempt — retry and the spend ceiling compose, and the ceiling wins.
|
|
125
|
+
|
|
126
|
+
**`attempts` appears in the step result** only when the step declared a `retry` block, so a step that succeeded on attempt 3 is distinguishable from one that succeeded immediately, and records for existing spells are unchanged.
|
|
127
|
+
|
|
128
|
+
An unrecognised key inside `retry` is a validation error, not a silent "no retry" — the same failure direction the budget block uses.
|
|
129
|
+
|
|
96
130
|
---
|
|
97
131
|
|
|
98
132
|
## Pause and Resume
|
|
@@ -87,6 +87,35 @@ Practical floors:
|
|
|
87
87
|
|
|
88
88
|
---
|
|
89
89
|
|
|
90
|
+
## Bounding Spend on Unattended Runs
|
|
91
|
+
|
|
92
|
+
**Set `spells.budget.scheduled` before scheduling any spell that invokes `claude -p`.** A scheduled run is unattended: nothing observes how many times it calls the model, so a loop step or a too-frequent cron can spend without a signal until the bill arrives. `flo init` writes these values into new projects; existing projects are untouched on upgrade and must opt in.
|
|
93
|
+
|
|
94
|
+
```yaml
|
|
95
|
+
spells:
|
|
96
|
+
budget:
|
|
97
|
+
scheduled:
|
|
98
|
+
maxModelInvocations: 30 # `claude -p` spawns allowed per run
|
|
99
|
+
maxWallClockMs: 2400000 # 40 minutes end to end
|
|
100
|
+
dailyModelInvocations: 300 # rolling 24h across ALL scheduled runs
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
| Ceiling | Scope | Enforced | On breach |
|
|
104
|
+
|---------|-------|----------|-----------|
|
|
105
|
+
| `maxModelInvocations` | One run | Reservation before the process spawns | The spawn is refused — a denied invocation is never billed |
|
|
106
|
+
| `maxWallClockMs` | One run | Deadline timer on the run's abort signal | The in-flight step is aborted |
|
|
107
|
+
| `dailyModelInvocations` | Every run in this project, trailing 24h | Reservation checked against the on-disk ledger | The spawn is refused before the process starts |
|
|
108
|
+
|
|
109
|
+
**Set `dailyModelInvocations`, not just the per-run keys — a per-run ceiling cannot bound a schedule.** The two answer different questions. A per-run ceiling asks "did this run go haywire"; the daily one asks "is this project spending more than I meant to." A five-minute cron under a 30-invocation per-run cap satisfies the per-run check 288 times a day and still reaches 8,640 invocations. Only the rolling window sees the total.
|
|
110
|
+
|
|
111
|
+
The count persists in `.moflo/spell-invocation-ledger.json` and is checked **before** the per-run ceiling, so a breach message names the limit that actually stopped the run. Delete the file to reset the window; a corrupt or unreadable ledger fails open rather than blocking every scheduled run.
|
|
112
|
+
|
|
113
|
+
**A breach aborts the run and ignores `continueOnError`.** It surfaces three ways: a `BUDGET_EXCEEDED` error on the result, `abortReason: budget-exceeded` plus a structured `budgetBreach` in the run's `tasklist` record, and a warning line in the daemon log.
|
|
114
|
+
|
|
115
|
+
**This is a proxy for spend, not a measurement of it.** moflo counts invocations, not tokens — metering would require changing what a bash step returns to downstream steps, and `claude -p "say hi"` counts the same as `claude -p "refactor this subsystem"`. Use `spells.budget.interactive` (configured separately, never inherited from `scheduled`, and deliberately loose because a human is present) to cap session-attached runs, and a per-spell `budget:` block to tighten a single spell. Full key reference: `.claude/guidance/moflo-yaml-reference.md`.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
90
119
|
## Storage Namespaces
|
|
91
120
|
|
|
92
121
|
**Two memory namespaces back the scheduler.** Both are project-scoped — schedules and history don't leak across projects.
|
|
@@ -221,5 +250,6 @@ If step 5 is empty, jump straight to the failure-modes table above — don't loo
|
|
|
221
250
|
- `.claude/guidance/moflo-spell-engine.md` — Definition format, step types, variable interpolation
|
|
222
251
|
- `.claude/guidance/moflo-spell-runner.md` — Execution lifecycle, dry-run, layering, errors
|
|
223
252
|
- `.claude/guidance/moflo-spell-sandboxing.md` — Capability levels (`read`/`hooks`/`swarm`) referenced by the `mofloLevel` cap
|
|
253
|
+
- `.claude/guidance/moflo-yaml-reference.md` — Full `spells.budget` key reference and the per-spell `budget:` block
|
|
224
254
|
- `.claude/guidance/moflo-spell-troubleshooting.md` — Broader spell failure-mode catalog beyond scheduling
|
|
225
255
|
- `.claude/guidance/moflo-core-guidance.md` — CLI, hooks, daemon, MCP reference hub
|