moflo 4.9.19 → 4.9.21

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 (82) hide show
  1. package/.claude/commands/{simplify.md → flo-simplify.md} +4 -4
  2. package/.claude/guidance/shipped/moflo-agent-rules.md +172 -0
  3. package/.claude/guidance/shipped/moflo-claude-swarm-cohesion.md +73 -265
  4. package/.claude/guidance/shipped/moflo-cli-reference.md +6 -6
  5. package/.claude/guidance/shipped/moflo-core-guidance.md +66 -184
  6. package/.claude/guidance/shipped/moflo-cross-platform.md +1 -1
  7. package/.claude/guidance/shipped/moflo-error-handling.md +3 -3
  8. package/.claude/guidance/shipped/moflo-guidance-rules.md +17 -7
  9. package/.claude/guidance/shipped/moflo-memory-strategy.md +76 -182
  10. package/.claude/guidance/shipped/moflo-memorydb-maintenance.md +6 -8
  11. package/.claude/guidance/shipped/moflo-settings-injection.md +7 -9
  12. package/.claude/guidance/shipped/moflo-source-hygiene.md +5 -5
  13. package/.claude/guidance/shipped/moflo-spell-connectors.md +3 -4
  14. package/.claude/guidance/shipped/moflo-spell-custom-steps.md +3 -4
  15. package/.claude/guidance/shipped/moflo-spell-engine.md +40 -162
  16. package/.claude/guidance/shipped/moflo-spell-runner.md +134 -0
  17. package/.claude/guidance/shipped/moflo-spell-sandboxing.md +10 -57
  18. package/.claude/guidance/shipped/moflo-spell-troubleshooting.md +149 -0
  19. package/.claude/guidance/shipped/moflo-subagents.md +43 -114
  20. package/.claude/guidance/shipped/moflo-task-icons.md +4 -4
  21. package/.claude/guidance/shipped/moflo-user-facing-language.md +3 -3
  22. package/.claude/guidance/shipped/moflo-verbose-command-filtering.md +3 -3
  23. package/.claude/guidance/shipped/moflo-yaml-reference.md +4 -5
  24. package/.claude/helpers/gate.cjs +124 -14
  25. package/.claude/helpers/prompt-hook.mjs +4 -38
  26. package/.claude/helpers/simplify-classify.cjs +32 -11
  27. package/.claude/helpers/subagent-bootstrap.json +1 -1
  28. package/.claude/helpers/subagent-start.cjs +1 -1
  29. package/.claude/skills/connector-builder/SKILL.md +42 -429
  30. package/.claude/skills/connector-builder/templates/connector.md +189 -0
  31. package/.claude/skills/connector-builder/templates/step-command.md +176 -0
  32. package/.claude/skills/eldar/SKILL.md +7 -7
  33. package/.claude/skills/fl/SKILL.md +3 -3
  34. package/.claude/skills/fl/execution-modes.md +3 -3
  35. package/.claude/skills/fl/phases.md +3 -3
  36. package/.claude/skills/{simplify → flo-simplify}/SKILL.md +11 -11
  37. package/.claude/skills/guidance/SKILL.md +17 -9
  38. package/.claude/skills/memory-patterns/SKILL.md +1 -1
  39. package/.claude/skills/publish/SKILL.md +121 -36
  40. package/.claude/skills/reset-epic/SKILL.md +2 -2
  41. package/.claude/skills/spell-builder/SKILL.md +39 -226
  42. package/.claude/skills/spell-builder/architecture.md +1 -1
  43. package/.claude/skills/spell-builder/permissions.md +107 -0
  44. package/.claude/skills/spell-builder/preflight.md +101 -0
  45. package/.claude/skills/spell-schedule/SKILL.md +2 -3
  46. package/bin/gate.cjs +124 -14
  47. package/bin/prompt-hook.mjs +4 -38
  48. package/bin/session-start-launcher.mjs +66 -1
  49. package/bin/setup-project.mjs +63 -69
  50. package/bin/simplify-classify.cjs +32 -11
  51. package/dist/src/cli/commands/doctor-checks-deep.js +4 -0
  52. package/dist/src/cli/init/claudemd-generator.js +30 -33
  53. package/dist/src/cli/init/executor.js +28 -16
  54. package/dist/src/cli/init/helpers-generator.js +101 -51
  55. package/dist/src/cli/init/moflo-init.js +41 -114
  56. package/dist/src/cli/init/settings-generator.js +32 -14
  57. package/dist/src/cli/services/hook-block-hash.js +7 -2
  58. package/dist/src/cli/services/hook-wiring.js +86 -3
  59. package/dist/src/cli/services/subagent-bootstrap.js +1 -1
  60. package/dist/src/cli/version.js +1 -1
  61. package/package.json +2 -2
  62. package/scripts/post-install-bootstrap.mjs +19 -0
  63. package/.claude/guidance/shipped/moflo-session-start.md +0 -154
  64. package/.claude/guidance/shipped/moflo-spell-engine-architecture.md +0 -145
  65. package/.claude/skills/browser/SKILL.md +0 -204
  66. package/.claude/skills/github-code-review/SKILL.md +0 -1140
  67. package/.claude/skills/github-multi-repo/SKILL.md +0 -866
  68. package/.claude/skills/github-project-management/SKILL.md +0 -1272
  69. package/.claude/skills/github-release-management/SKILL.md +0 -1074
  70. package/.claude/skills/github-workflow-automation/SKILL.md +0 -1060
  71. package/.claude/skills/hive-mind-advanced/SKILL.md +0 -712
  72. package/.claude/skills/hooks-automation/SKILL.md +0 -1193
  73. package/.claude/skills/pair-programming/SKILL.md +0 -1202
  74. package/.claude/skills/performance-analysis/SKILL.md +0 -563
  75. package/.claude/skills/skill-builder/SKILL.md +0 -910
  76. package/.claude/skills/sparc-methodology/SKILL.md +0 -904
  77. package/.claude/skills/stream-chain/SKILL.md +0 -563
  78. package/.claude/skills/swarm-advanced/SKILL.md +0 -811
  79. package/.claude/skills/swarm-orchestration/SKILL.md +0 -179
  80. package/.claude/skills/verification-quality/SKILL.md +0 -649
  81. package/.claude/skills/worker-benchmarks/skill.md +0 -135
  82. package/.claude/skills/worker-integration/skill.md +0 -154
@@ -0,0 +1,149 @@
1
+ # Spell Troubleshooting — Sandbox, Network, and Permission Failures
2
+
3
+ **Purpose:** Diagnostic playbook for spell step failures that look like environmental issues but are actually capability/sandbox boundaries. Reference this when a step "should work" but produces DNS errors, silent no-ops, or confusing downstream failures. Pair with `.claude/guidance/moflo-spell-sandboxing.md` for the underlying enforcement model.
4
+
5
+ ---
6
+
7
+ ## Bash Step Fails With DNS / SSH Resolution Errors
8
+
9
+ The single most common spell failure mode. The step works fine in your normal shell, then fails inside a spell with what looks like a network/DNS problem.
10
+
11
+ ### Typical Error Messages
12
+
13
+ - `ssh: Could not resolve hostname github.com: Temporary failure in name resolution`
14
+ - `fatal: Could not read from remote repository.`
15
+ - `curl: (6) Could not resolve host ...`
16
+ - `getaddrinfo ENOTFOUND ...`
17
+ - Any other DNS/connection failure where the **same command works in your normal shell**.
18
+
19
+ ### Tell-Tale Clue
20
+
21
+ The error mentions `Temporary failure in name resolution` — a **glibc-specific** wording. That means the step is running inside a Linux sandbox (`bwrap` on Linux / WSL), **not** your outer shell. Git Bash or PowerShell won't produce that exact message.
22
+
23
+ ### Root Cause
24
+
25
+ `src/cli/spells/core/bwrap-sandbox.ts` isolates the network by default:
26
+
27
+ ```ts
28
+ if (!hasNet && !needsToolHomeAccess(options.permissionLevel)) {
29
+ args.push('--unshare-net'); // ← no network, no DNS
30
+ }
31
+ ```
32
+
33
+ A bash step gets network access **only when one of these is true**:
34
+
35
+ 1. The step declares a `net` capability, **or**
36
+ 2. The step's `permissionLevel` is `elevated` or `autonomous`.
37
+
38
+ If neither applies, bwrap runs the command in a namespace with `--unshare-net`, and DNS silently fails. **There is no log line announcing the network was taken away** — you just see the command's own DNS error.
39
+
40
+ ### Fix
41
+
42
+ For any bash step that does `git pull` / `git push` / `git fetch`, `gh` API calls, `curl`, `npm install`, or any other outbound network call:
43
+
44
+ ```yaml
45
+ - id: create-branch
46
+ type: bash
47
+ permissionLevel: elevated # ← grants network in bwrap
48
+ config:
49
+ command: "git pull origin main && ..."
50
+ ```
51
+
52
+ Or declare the `net` capability explicitly if the step doesn't need the full `elevated` profile. **Note:** `bash-command.ts` must include `net` in its declared capabilities for the engine to accept the grant — otherwise you'll see:
53
+
54
+ ```
55
+ Capability violation: step type "bash" does not declare capability "net"
56
+ ```
57
+
58
+ ### Quick Diagnosis Checklist
59
+
60
+ When a spell's bash step can't reach the network, walk through these in order:
61
+
62
+ | # | Question | If yes |
63
+ |---|----------|--------|
64
+ | 1 | Does the same command work in your outer shell? | Sandbox-related, not config — go to #2 |
65
+ | 2 | Is the error wording glibc-style (`Temporary failure in name resolution`)? | bwrap is involved — go to #3 |
66
+ | 3 | Does the failing step have `permissionLevel: elevated` or a `net` capability? | If no, add one and retry |
67
+ | 4 | Does the multi-command step start with `set -e`? | If no, add it (see § Multi-Command `set -e` Traps below) |
68
+
69
+ ---
70
+
71
+ ## Multi-Command `set -e` Traps
72
+
73
+ A bash step that chains multiple statements without `set -e` will **return exit code 0 even when the real work failed**, producing confusing errors several steps later.
74
+
75
+ ### Symptom
76
+
77
+ A spell step appears to succeed (`exitCode: 0`), but a later step fails with something that should have been impossible — typically:
78
+
79
+ - `pathspec did not match` on a branch that was never created
80
+ - `nothing to commit` when you expected staged changes
81
+ - File operations on paths that don't exist
82
+
83
+ ### Root Cause
84
+
85
+ Without `set -e`, a multi-command bash step like this:
86
+
87
+ ```yaml
88
+ - id: prep-branch
89
+ type: bash
90
+ config:
91
+ command: "git pull origin main && git checkout -b feat/x && git stash pop || true"
92
+ ```
93
+
94
+ …will mask a failure in `git pull` (e.g. blocked by `--unshare-net`) because the trailing `git stash pop || true` returns 0 for the whole step. Downstream steps assume the branch exists and produce the confusing `pathspec` error.
95
+
96
+ ### Fix
97
+
98
+ Lead every multi-command bash step with `set -e`:
99
+
100
+ ```yaml
101
+ - id: prep-branch
102
+ type: bash
103
+ permissionLevel: elevated
104
+ config:
105
+ command: |
106
+ set -e
107
+ git pull origin main
108
+ git checkout -b feat/x
109
+ git stash pop || true # only this one is allowed to fail
110
+ ```
111
+
112
+ `set -e` makes the shell exit on any non-zero status, surfacing the real failure at the right step.
113
+
114
+ ---
115
+
116
+ ## Capability Violation Errors
117
+
118
+ When a spell YAML restricts capabilities a command doesn't declare, or grants new types beyond the command's defaults, the runner blocks execution before the step runs.
119
+
120
+ | Error | Meaning | Fix |
121
+ |-------|---------|-----|
122
+ | `Capability violation: step type "X" does not declare capability "Y"` | YAML restricts a capability the step command doesn't list | Add `Y` to the step command's `capabilities` array (in code), or remove the restriction from YAML |
123
+ | `CAPABILITY_DENIED at runtime` | A command tried to access a path/host outside its effective scope | Tighten the command, or widen the YAML capability scope to include the resource |
124
+
125
+ See `.claude/guidance/moflo-spell-sandboxing.md` § Enforcement at Runtime for the two-layer enforcement model.
126
+
127
+ ---
128
+
129
+ ## Step Silently No-Ops
130
+
131
+ A step appears to run (`exitCode: 0`), produces no output, and downstream steps act as if no work happened.
132
+
133
+ | Likely cause | Diagnostic |
134
+ |--------------|------------|
135
+ | Command writes to stdout but bwrap blocks the working directory | Check `permissionLevel`; bwrap restricts `fs:write` to declared scopes |
136
+ | Variable interpolation produced an empty string | Run with `dryRun: true` to see resolved configs (see `moflo-spell-runner.md`) |
137
+ | `continueOnError: true` is hiding a real failure | Remove `continueOnError` temporarily, re-run, inspect error output |
138
+ | Trailing `|| true` on the only critical statement | Restructure with `set -e` and place `|| true` only on cleanup statements |
139
+
140
+ ---
141
+
142
+ ## See Also
143
+
144
+ - `.claude/guidance/moflo-spell-sandboxing.md` — Capability types, enforcement layers, permission levels (the model these failures exercise)
145
+ - `.claude/guidance/moflo-spell-engine.md` — Step definition format and types
146
+ - `.claude/guidance/moflo-spell-runner.md` — Dry-run validation, error codes, pause/resume
147
+ - `.claude/guidance/moflo-yaml-reference.md` — `sandbox:` block in `moflo.yaml` (master toggle, tier selection)
148
+ - `src/cli/spells/core/bwrap-sandbox.ts` — Source for `--unshare-net` and namespace setup
149
+ - `src/cli/spells/core/permission-resolver.ts` — Capability → permission level derivation
@@ -1,150 +1,79 @@
1
- # MoFlo Subagents Guide
1
+ # MoFlo Subagents — Spawn Protocol
2
2
 
3
- **Purpose:** Protocol for subagents spawned by coordinators. Follow these steps before doing any work.
3
+ **Purpose:** Steps every subagent MUST run when spawned by a coordinator. The single-sentence directive injected by `SubagentStart` (see `.claude/helpers/subagent-bootstrap.json`) tells every subagent to memory-search first, then follow this protocol. Universal coding/coordination rules every agent (coordinator OR subagent) shares live in `.claude/guidance/moflo-agent-rules.md` — read those after Step 1.
4
4
 
5
5
  ---
6
6
 
7
- ## 1. Search Memory FIRST
7
+ ## Step 1: Search Memory FIRST
8
8
 
9
- **Before reading any files or exploring code, search memory for guidance relevant to your task.**
9
+ **Before reading any files or exploring code, search memory.** This is the bootstrap action — moflo's gates will block your `Glob`/`Grep`/`Read` calls until you do.
10
10
 
11
- ### Namespaces to search:
12
-
13
- | Namespace | When to search | What it returns |
14
- |-----------|---------------|-----------------|
15
- | `guidance` | always | Guidance docs, coding rules, domain context |
16
- | `patterns` | always | Learned patterns from previous task execution |
17
- | `learnings` | always | User-directed decisions + distilled insights (post-mortems, gotchas, lessons learned) |
18
- | `code-map` | navigating code | Project overviews, directory contents, type-to-file mappings |
19
- | `tests` | test/coverage queries | Indexed test inventory — pinpoint specs and coverage for a given function/module |
20
-
21
- **Always search `patterns` and `learnings` alongside `guidance`.** Patterns hold solutions to already-solved problems; learnings hold incident insights and user-stated decisions. Skipping either means repeating past mistakes or violating standing decisions.
22
-
23
- **Search `code-map` BEFORE using Glob/Grep for navigation.** It's faster and returns structured results including file-level type mappings.
24
-
25
- **Search `tests` when looking for test coverage** of a function, module, or behavior — it indexes the test tree separately so you can pinpoint specs without grepping the whole repo.
26
-
27
- ### Option A: MCP Tools (Preferred)
28
-
29
- If you have MCP tools available (check for `mcp__moflo__*`), use them directly:
30
-
31
- | Tool | Purpose |
32
- |------|---------|
33
- | `mcp__moflo__memory_search` | Semantic search with domain-aware embeddings |
34
- | `mcp__moflo__memory_store` | Store patterns with auto-vectorization |
35
- | `mcp__moflo__hooks_route` | Get agent routing suggestions |
36
-
37
- ### Option B: CLI via Bash
38
-
39
- ```bash
40
- npx flo memory search --query "[describe your task]" --namespace guidance --limit 5
11
+ ```
12
+ mcp__moflo__memory_search query: "[describe your task]" namespace: "guidance"
41
13
  ```
42
14
 
43
- | Your task involves... | Search namespace | Example query |
44
- |-----------------------|------------------|---------------|
45
- | Database/entities | `guidance` + `patterns` + `learnings` | `"database entity migration"` |
46
- | Frontend components | `guidance` + `patterns` + `learnings` | `"React frontend component"` |
47
- | API endpoints | `guidance` + `patterns` + `learnings` | `"API route endpoint pattern"` |
48
- | Authentication | `guidance` + `patterns` + `learnings` | `"auth middleware JWT"` |
49
- | Prior solutions/gotchas | `patterns` + `learnings` | `"audit log service pattern"` |
50
- | Past incident/lesson | `learnings` | `"windows postinstall file locks"` |
51
- | Where is a file/type? | `code-map` | `"CompanyEntity file location"` |
52
- | What's in a directory? | `code-map` | `"back-office api routes"` |
53
- | Tests for a function | `tests` | `"audit log service tests"` |
54
- | Coverage for a module | `tests` | `"auth middleware test cases"` |
55
-
56
- Use results with score > 0.3. If no good results, fall back to reading project guidance docs.
57
-
58
- ---
59
-
60
- ## 2. Check for Project-Specific Overrides
15
+ Run the search **at least three times** once each against `guidance`, `patterns`, and `learnings`. Patterns hold prior solutions; learnings hold standing decisions and post-mortem insights. Skipping either repeats past mistakes. Add `code-map` when navigating code, `tests` when looking for test coverage.
61
16
 
62
- Claude Code automatically loads all `.claude/guidance/*.md` files into your context. If the consuming project has its own guidance files (e.g., domain rules, entity patterns, tech stack conventions), they are already available to you — no need to read them manually.
17
+ CLI fallback when MCP is unavailable: `npx flo memory search --query "..." --namespace guidance --limit 5`.
63
18
 
64
- Project-specific guidance always takes precedence over generic MoFlo guidance.
19
+ The full namespace reference, query examples by domain, and tool catalog live in `.claude/guidance/moflo-agent-rules.md` § Memory-First Protocol — read that next.
65
20
 
66
21
  ---
67
22
 
68
- ## 3. Universal Rules
69
-
70
- ### Memory Protocol
71
- - Search memory before exploring files
72
- - Store discoveries back to memory when done
73
- - Use `patterns` namespace for solutions and gotchas
74
- - Use `learnings` namespace for architectural choices, user-requested decisions, and distilled insights (`knowledge` is a deprecated alias — writes are auto-redirected)
23
+ ## Step 2: Apply Universal Agent Rules
75
24
 
76
- ### Git/Branches
77
- - Use conventional commit prefixes: `feat:`, `fix:`, `refactor:`, `test:`, `chore:`
78
- - Use branch prefixes: `feature/`, `fix/`, `refactor/`
79
- - Use kebab-case for branch names
25
+ Every moflo agent — coordinator or subagent — must follow `.claude/guidance/moflo-agent-rules.md`. The most load-bearing rules for subagents specifically:
80
26
 
81
- ### Pull Requests CRITICAL: Always target the correct repo
82
- **NEVER run bare `gh pr create` in a forked repository.** The `gh` CLI defaults to the upstream parent repo, not the fork's origin. This has caused PRs to be accidentally opened against upstream.
27
+ | Rule | Detail |
28
+ |------|--------|
29
+ | **Task Icons** | `TaskCreate` MUST use **ICON + [Role]** in `subject` and `activeForm` — see `.claude/guidance/moflo-task-icons.md`. Example: `🧪 [Tester] Run unit tests` / activeForm: `🧪 Running unit tests` |
30
+ | **PR target repo (CRITICAL)** | Never run bare `gh pr create` in a forked repo — it defaults to upstream. Always pass `--repo "$REPO"`. Full workflow in `moflo-agent-rules.md` |
31
+ | **MCP-first tool selection** | Prefer `mcp__moflo__*` tools over `npx flo` CLI. CLI is fallback only |
32
+ | **Build & test after changes** | Never leave failing tests; fix red signals at the source |
83
33
 
84
- **Required workflow:**
85
- ```bash
86
- # 1. Determine the correct repo from the origin remote
87
- REPO=$(git remote get-url origin | sed 's|.*github.com[:/]||;s|\.git$||')
88
-
89
- # 2. ALWAYS pass --repo to gh pr create
90
- gh pr create --repo "$REPO" --title "..." --body "..."
91
-
92
- # 3. For merge: also pass --repo
93
- gh pr merge <number> --repo "$REPO" --squash
94
- ```
34
+ The full set (git/branch conventions, file organization, build/test discipline, storing discoveries) is in `.claude/guidance/moflo-agent-rules.md`.
95
35
 
96
- This applies to ALL `gh` commands that target a repo: `pr create`, `pr merge`, `pr list`, `issue create`, etc.
36
+ ---
97
37
 
98
- ### File Organization
99
- - Never save working files to repository root
100
- - Keep changes focused (3-10 files)
101
- - Stay within feature scope
38
+ ## Step 3: Check for Project-Specific Overrides
102
39
 
103
- ### Build & Test
104
- - Build and test after code changes
105
- - Never leave failing tests
40
+ Claude Code automatically loads all `.claude/guidance/*.md` files into your context. If the consuming project has its own guidance files (domain rules, entity patterns, tech-stack conventions), they're already available — no need to read them manually.
106
41
 
107
- ### Task Icons (MANDATORY)
108
- - `TaskCreate` MUST use **ICON + [Role]** in `subject` and `activeForm`
109
- - Full icon map: `.claude/guidance/shipped/moflo-task-icons.md`
110
- - Example: `🧪 [Tester] Run unit tests` / activeForm: `🧪 Running unit tests`
42
+ **Project-specific guidance always takes precedence over generic MoFlo guidance.**
111
43
 
112
44
  ---
113
45
 
114
- ## 4. Store Discoveries
46
+ ## Step 4: Store Discoveries Before Reporting
115
47
 
116
- If you discover something new (pattern, solution, gotcha), store it:
48
+ Before signing off your work, store anything useful you discovered during the task. Future agents shouldn't have to re-discover what you already learned.
117
49
 
118
- ### MCP (Preferred):
119
- ```
120
- mcp__moflo__memory_store
121
- namespace: "patterns"
122
- key: "brief-descriptive-key"
123
- value: "1-2 sentence insight"
124
- ```
50
+ | Namespace | What to store |
51
+ |-----------|---------------|
52
+ | `patterns` | Solutions to tricky bugs, gotchas, workarounds |
53
+ | `learnings` | Architectural choices, user-stated decisions, post-mortem insights |
125
54
 
126
- ### CLI Fallback:
127
- ```bash
128
- npx flo memory store --namespace patterns --key "brief-descriptive-key" --value "1-2 sentence insight"
129
- ```
55
+ **Store:** Patterns that worked, gotchas you hit, workarounds for limitations.
56
+ **Skip:** Generic summaries of retrieved guidance, restated rules, trivial file-location notes.
130
57
 
131
- **Store:** Solutions to tricky bugs, patterns that worked, gotchas, workarounds
132
- **Skip:** Summaries of retrieved guidance, general rules, file locations
58
+ See `.claude/guidance/moflo-agent-rules.md` § Storing Discoveries for the full MCP/CLI invocation patterns.
133
59
 
134
60
  ---
135
61
 
136
- ## 5. When Complete
62
+ ## Step 5: When Complete
63
+
64
+ 1. Report findings to the coordinator
65
+ 2. Confirm any discoveries are stored (Step 4)
66
+ 3. The coordinator will mark your task `completed` via `TaskUpdate`
137
67
 
138
- 1. Report findings to coordinator
139
- 2. Store learnings if you discovered something new
140
- 3. Coordinator will mark your task as completed
68
+ Do not mark your own task completed — that's the coordinator's responsibility.
141
69
 
142
70
  ---
143
71
 
144
72
  ## See Also
145
73
 
146
- - `.claude/guidance/shipped/moflo-task-icons.md` — Mandatory ICON + [Role] format for every `TaskCreate` and `Agent` description spawned by a coordinator
147
- - `.claude/guidance/shipped/moflo-claude-swarm-cohesion.md` — How task lists and swarm coordinators cooperate when subagents are spawned in batches
148
- - `.claude/guidance/shipped/moflo-memory-strategy.md` — The memory-search-first rule this protocol enforces, with namespace-selection guidance
149
- - `.claude/guidance/shipped/moflo-memorydb-maintenance.md` — How the memory namespaces are populated and refreshed; required reading when search returns no results
150
- - `.claude/guidance/shipped/moflo-core-guidance.md` — Full CLI/MCP reference including the spell gates that block subagent spawn before memory is searched
74
+ - `.claude/guidance/moflo-agent-rules.md` — Universal rules every agent (coordinator OR subagent) shares
75
+ - `.claude/guidance/moflo-task-icons.md` — Mandatory ICON + [Role] format for every `TaskCreate` and `Agent` description
76
+ - `.claude/guidance/moflo-claude-swarm-cohesion.md` — How task lists and swarm coordinators cooperate when subagents are spawned in batches
77
+ - `.claude/guidance/moflo-memory-strategy.md` — Memory architecture, namespaces, search patterns
78
+ - `.claude/guidance/moflo-memorydb-maintenance.md` — How memory namespaces are populated and refreshed
79
+ - `.claude/guidance/moflo-core-guidance.md` — Full CLI/MCP reference including the spell gates that block subagent spawn before memory is searched
@@ -66,7 +66,7 @@ The spinner is the primary visual feedback during agent execution. Without icons
66
66
 
67
67
  ## See Also
68
68
 
69
- - `.claude/guidance/shipped/moflo-subagents.md` — Subagent protocol; `TaskCreate`/`Agent` icon rule is enforced as part of the spawning checklist
70
- - `.claude/guidance/shipped/moflo-claude-swarm-cohesion.md` — How task lists and swarms cooperate; icons distinguish swarm-spawned vs single-agent work
71
- - `.claude/guidance/shipped/moflo-user-facing-language.md` — Companion UX rule for any text shown to end users
72
- - `.claude/guidance/shipped/moflo-core-guidance.md` — Spell Gate that enforces icon format on `TaskCreate`
69
+ - `.claude/guidance/moflo-subagents.md` — Subagent protocol; `TaskCreate`/`Agent` icon rule is enforced as part of the spawning checklist
70
+ - `.claude/guidance/moflo-claude-swarm-cohesion.md` — How task lists and swarms cooperate; icons distinguish swarm-spawned vs single-agent work
71
+ - `.claude/guidance/moflo-user-facing-language.md` — Companion UX rule for any text shown to end users
72
+ - `.claude/guidance/moflo-core-guidance.md` — Spell Gate that enforces icon format on `TaskCreate`
@@ -37,6 +37,6 @@
37
37
 
38
38
  ## See Also
39
39
 
40
- - `.claude/guidance/shipped/moflo-task-icons.md` — Companion UX rule: spinner text must use ICON + [Role] so non-technical users can identify the working agent
41
- - `.claude/guidance/shipped/moflo-spell-sandboxing.md` — Permission disclosure output where this language rule has the largest user-visible surface
42
- - `.claude/guidance/shipped/moflo-error-handling.md` — Sibling rule for what error messages must contain; this doc governs how those messages are phrased
40
+ - `.claude/guidance/moflo-task-icons.md` — Companion UX rule: spinner text must use ICON + [Role] so non-technical users can identify the working agent
41
+ - `.claude/guidance/moflo-spell-sandboxing.md` — Permission disclosure output where this language rule has the largest user-visible surface
42
+ - `.claude/guidance/moflo-error-handling.md` — Sibling rule for what error messages must contain; this doc governs how those messages are phrased
@@ -35,11 +35,11 @@ npm run build -- --verbose 2>&1 | grep -E "error TS|Failed|Cannot find"
35
35
 
36
36
  ## Why It Matters
37
37
 
38
- Case study: issue #903 burned ~25K tokens across 5 tee-then-grep round-trips where a single grep-at-source would have surfaced the same signal once. Filtering at source is not an optimization — it is the default shape for any verbose command whose full output you do not need in your context.
38
+ A representative incident burned ~25K tokens across 5 tee-then-grep round-trips where a single grep-at-source would have surfaced the same signal once. Filtering at source is not an optimization — it is the default shape for any verbose command whose full output you do not need in your context.
39
39
 
40
40
  ---
41
41
 
42
42
  ## See Also
43
43
 
44
- - `.claude/guidance/shipped/moflo-core-guidance.md` — Hub for moflo's CLI/MCP surface and runtime conventions
45
- - `.claude/guidance/shipped/moflo-memory-strategy.md` — Companion rules on RAG indexing and context discipline
44
+ - `.claude/guidance/moflo-core-guidance.md` — Hub for moflo's CLI/MCP surface and runtime conventions
45
+ - `.claude/guidance/moflo-memory-strategy.md` — Companion rules on RAG indexing and context discipline
@@ -184,8 +184,7 @@ Global registration is useful for ad-hoc projects where you don't want to commit
184
184
 
185
185
  ## See Also
186
186
 
187
- - `.claude/guidance/shipped/moflo-core-guidance.md` — Hub: getting started, anti-drift defaults, troubleshooting
188
- - `.claude/guidance/shipped/moflo-cli-reference.md` — Commands, agents, hooks, hive-mind, ruvector — the surfaces this config gates
189
- - `.claude/guidance/shipped/moflo-spell-sandboxing.md` — What `sandbox:` actually does at the bash-step boundary, with capability/permission interaction
190
- - `.claude/guidance/shipped/moflo-session-start.md` — Where these config fields are read and applied during session start
191
- - `.claude/guidance/shipped/moflo-settings-injection.md` — What moflo writes into `.claude/settings.json` (the hook wiring; complementary to `moflo.yaml` toggles)
187
+ - `.claude/guidance/moflo-core-guidance.md` — Hub: getting started, anti-drift defaults, troubleshooting
188
+ - `.claude/guidance/moflo-cli-reference.md` — Commands, agents, hooks, hive-mind, ruvector — the surfaces this config gates
189
+ - `.claude/guidance/moflo-spell-sandboxing.md` — What `sandbox:` actually does at the bash-step boundary, with capability/permission interaction
190
+ - `.claude/guidance/moflo-settings-injection.md` — What moflo writes into `.claude/settings.json` (the hook wiring; complementary to `moflo.yaml` toggles)
@@ -7,7 +7,7 @@ var cp = require('child_process');
7
7
  var PROJECT_DIR = (process.env.CLAUDE_PROJECT_DIR || process.cwd()).replace(/^\/([a-z])\//i, '$1:/');
8
8
  var STATE_FILE = path.join(PROJECT_DIR, '.claude', 'workflow-state.json');
9
9
 
10
- var STATE_DEFAULTS = { tasksCreated: false, taskCount: 0, memorySearched: false, memorySearchedBy: {}, memoryRequired: true, learningsStored: false, testsRun: false, simplifyRun: false, simplifySnapshotSha: null, interactionCount: 0, sessionStart: null, lastBlockedAt: null };
10
+ var STATE_DEFAULTS = { tasksCreated: false, taskCount: 0, memorySearched: false, memorySearchedBy: {}, memoryRequired: true, learningsStored: false, testsRun: false, simplifyRun: false, simplifySnapshotSha: null, interactionCount: 0, sessionStart: null, lastBlockedAt: null, lastNamespaceHint: '', lastNamespaceHintEmittedBy: {} };
11
11
 
12
12
  // Per-actor memory-search tracking (#838). The legacy `memorySearched` boolean
13
13
  // is session-wide, so once the parent searches memory, every spawned subagent
@@ -83,6 +83,78 @@ var EXEMPT = ['.claude/', '.claude\\', 'CLAUDE.md', 'MEMORY.md', 'workflow-state
83
83
  var DANGEROUS = ['rm -rf /', 'format c:', 'del /s /q c:\\', ':(){:|:&};:', 'mkfs.', '> /dev/sda'];
84
84
  var DIRECTIVE_RE = /^(yes|no|yeah|yep|nope|sure|ok|okay|correct|right|exactly|perfect)\b/i;
85
85
  var TASK_RE = /\b(fix|bug|error|implement|add|create|build|write|refactor|debug|test|feature|issue|security|optimi)\b/i;
86
+
87
+ // Namespace classification (#931). The hint used to be emitted on every prompt
88
+ // by prompt-hook.mjs which cost ~40 tokens × every prompt × every consumer.
89
+ // Now we classify here, store on workflow-state, and let check-before-agent
90
+ // emit it once when Claude is actually about to spawn an agent.
91
+ //
92
+ // SYNC: these regexes + classifyNamespaceHint + applyPromptStateReset are
93
+ // duplicated verbatim in src/cli/init/helpers-generator.ts (the embedded
94
+ // gate.cjs fallback used by `flo init` when source helpers can't be located).
95
+ // Any edit to either copy MUST be applied to both — there is no shared module
96
+ // because helpers-generator emits a self-contained string template.
97
+ var NS_LEARNINGS_RE = /\b(remember|recall|insight|lesson learned|gotcha|post.?mortem)\b|we (decid|agree|chose|said)/;
98
+ var NS_TEST_RE = /\b(test|spec|coverage|tested|test case|test cases|tests for|spec for)\b/;
99
+ var NS_EXPLICIT = [
100
+ { pattern: /\b(pattern|convention|best practice|style|coding rule)\b/, ns: 'patterns', label: 'code patterns and conventions' },
101
+ { pattern: /\b(code.?map|file structure|project structure|directory)\b/, ns: 'code-map', label: 'codebase navigation' },
102
+ ];
103
+ var NS_PATTERN_RES = [/\b(template|example|similar to|how do we|how should)\b/];
104
+ var NS_DOMAIN_RES = [
105
+ /\b(guidance|guide|docs|documentation|rules|how-to)\b/,
106
+ /\b(architecture|design|domain|tenant|migrat|schema|deploy)/,
107
+ /\b(rule|requirement|constraint|compliance)\b/,
108
+ ];
109
+ var NS_NAV_RES = [
110
+ /\b(find|where|which file|look up|locate|endpoint|route|url|path)\b/,
111
+ /\b(class|function|method|component|service|entity|module)\b/,
112
+ ];
113
+
114
+ function classifyNamespaceHint(promptText) {
115
+ var lower = (promptText || '').toLowerCase();
116
+ if (NS_TEST_RE.test(lower)) return 'Memory namespace hint: use "tests" for test inventory and coverage lookups.';
117
+ if (NS_LEARNINGS_RE.test(lower)) return 'Memory namespace hint: use "learnings" for user-directed decisions and distilled insights.';
118
+ for (var i = 0; i < NS_EXPLICIT.length; i++) {
119
+ if (NS_EXPLICIT[i].pattern.test(lower)) return 'Memory namespace hint: use "' + NS_EXPLICIT[i].ns + '" for ' + NS_EXPLICIT[i].label + '.';
120
+ }
121
+ for (var j = 0; j < NS_DOMAIN_RES.length; j++) {
122
+ if (NS_DOMAIN_RES[j].test(lower)) return 'Memory namespace hint: search "guidance" and "learnings" for domain rules and project decisions.';
123
+ }
124
+ for (var k = 0; k < NS_PATTERN_RES.length; k++) {
125
+ if (NS_PATTERN_RES[k].test(lower)) return 'Memory namespace hint: use "patterns" for code patterns and conventions.';
126
+ }
127
+ for (var m = 0; m < NS_NAV_RES.length; m++) {
128
+ if (NS_NAV_RES[m].test(lower)) return 'Memory namespace hint: use "code-map" for codebase navigation.';
129
+ }
130
+ return '';
131
+ }
132
+
133
+ // Apply per-prompt state reset shared by `prompt-reminder` (full) and
134
+ // `prompt-state-reset` (defensive safety-net, no emission). Idempotent — both
135
+ // UserPromptSubmit hooks can run it without compounding any field. Caller
136
+ // owns interactionCount and the user-visible REMINDER/Context emissions, so
137
+ // this helper stays silent.
138
+ function applyPromptStateReset(state, promptText) {
139
+ state.memorySearched = false;
140
+ // Wipe per-actor memory tracking too — a new user prompt is a fresh window
141
+ // for both parent AND any subagents the parent may spawn during this turn.
142
+ state.memorySearchedBy = {};
143
+ // learningsStored is session-scoped — once stored, it stays true until session reset.
144
+ // Resetting per-prompt caused false blocks when PR creation was on a later prompt.
145
+ var DIRECTIVE_MAX_LEN = 20;
146
+ var escaped = /^@@\s*/.test(promptText || '');
147
+ state.memoryRequired = !escaped && (promptText || '').length >= 4 && (TASK_RE.test(promptText || '') || (promptText || '').length > DIRECTIVE_MAX_LEN);
148
+ // Stash namespace hint for check-before-agent to emit when Claude actually
149
+ // spawns an Agent (#931). Empty string when nothing matched — overwriting
150
+ // any stale value from the previous prompt.
151
+ state.lastNamespaceHint = classifyNamespaceHint(promptText);
152
+ // Per-actor emission tracking — each subagent's session gets the hint at
153
+ // most once per prompt, but a fresh prompt resets every actor's window so
154
+ // subsequent agents (parent + subagents that spawn their own agents) all
155
+ // see the new classification on their first check-before-agent.
156
+ state.lastNamespaceHintEmittedBy = {};
157
+ }
86
158
  // Match npm/yarn/pnpm/bun test, npx vitest|jest|..., bare runners at command-start only,
87
159
  // and language-native test commands. The bare-runner arm is anchored so that
88
160
  // `npm install jest`, `grep -r vitest src/`, and similar don't false-positive.
@@ -203,6 +275,11 @@ switch (command) {
203
275
  // Advisory only — agent spawning is never blocked.
204
276
  // Memory-first enforcement happens at the scan/read gate layer.
205
277
  // SubagentStart hook injects guidance directive into subagent context.
278
+ //
279
+ // #931 — TaskCreate REMINDER and the namespace hint moved here from
280
+ // prompt-reminder. They only matter when Claude is actually about to spawn
281
+ // an Agent; emitting per-prompt cost ~90 tokens × every prompt × every
282
+ // consumer.
206
283
  var s = readState();
207
284
  if (config.task_create_first && !s.tasksCreated) {
208
285
  process.stdout.write('REMINDER: Use TaskCreate before spawning agents. Task tool is blocked until then.\n');
@@ -210,6 +287,24 @@ switch (command) {
210
287
  if (config.memory_first && s.memoryRequired && !s.memorySearched) {
211
288
  process.stdout.write('REMINDER: Search memory (mcp__moflo__memory_search) before spawning agents.\n');
212
289
  }
290
+ if (s.lastNamespaceHint) {
291
+ // Per-actor single-shot. Each session_id gets the hint at most once per
292
+ // prompt, but the hint itself stays available for other actors (e.g.
293
+ // a subagent that spawns its own agent has its own session_id and is
294
+ // entitled to a fresh emission). Falls back to a `_legacy_` bucket when
295
+ // Claude Code didn't forward a session_id (older host or direct CLI
296
+ // invocation), preserving the old "emit once globally" behavior. The
297
+ // map is wiped by applyPromptStateReset on every new prompt.
298
+ var sid = process.env.HOOK_SESSION_ID || '';
299
+ var emittedBy = s.lastNamespaceHintEmittedBy || {};
300
+ var bucket = sid || '_legacy_';
301
+ if (!emittedBy[bucket]) {
302
+ process.stdout.write(s.lastNamespaceHint + '\n');
303
+ emittedBy[bucket] = true;
304
+ s.lastNamespaceHintEmittedBy = emittedBy;
305
+ writeState(s);
306
+ }
307
+ }
213
308
  break;
214
309
  }
215
310
  case 'check-before-scan': {
@@ -277,7 +372,8 @@ switch (command) {
277
372
  break;
278
373
  }
279
374
  case 'record-skill-run': {
280
- if ((process.env.TOOL_INPUT_skill || '') === 'simplify') {
375
+ var skName = (process.env.TOOL_INPUT_skill || '');
376
+ if (skName === 'simplify' || skName === 'flo-simplify') {
281
377
  var s = readState();
282
378
  var changed = false;
283
379
  if (!s.simplifyRun) { s.simplifyRun = true; changed = true; }
@@ -346,7 +442,7 @@ switch (command) {
346
442
  }
347
443
  var missing = [];
348
444
  if (config.testing_gate && !s.testsRun) missing.push('tests have not run since the last code edit (run npm test, vitest, jest, pytest, or similar)');
349
- if (config.simplify_gate && !s.simplifyRun) missing.push('/simplify has not run since the last code edit');
445
+ if (config.simplify_gate && !s.simplifyRun) missing.push('/flo-simplify has not run since the last code edit');
350
446
  if (config.learnings_gate && !s.learningsStored) missing.push('learnings have not been stored (call mcp__moflo__memory_store)');
351
447
  if (missing.length === 0) break;
352
448
  process.stderr.write('BLOCKED: gh pr create requires the following before opening a PR:\n');
@@ -371,20 +467,16 @@ switch (command) {
371
467
  break;
372
468
  }
373
469
  case 'prompt-reminder': {
470
+ // Full per-prompt reset. Wired as the first UserPromptSubmit hook (via
471
+ // prompt-hook.mjs). Owns interactionCount + Context warnings; the
472
+ // TaskCreate REMINDER and namespace hint moved to check-before-agent
473
+ // (#931) so they only fire when Claude is actually about to spawn an
474
+ // Agent.
374
475
  var s = readState();
375
- s.memorySearched = false;
376
- // Wipe per-actor memory tracking too — a new user prompt is a fresh window
377
- // for both parent AND any subagents the parent may spawn during this turn.
378
- s.memorySearchedBy = {};
379
- // learningsStored is session-scoped — once stored, it stays true until session reset.
380
- // Resetting per-prompt caused false blocks when PR creation was on a later prompt.
381
476
  var prompt = process.env.CLAUDE_USER_PROMPT || '';
382
- var DIRECTIVE_MAX_LEN = 20;
383
- var escaped = /^@@\s*/.test(prompt);
384
- s.memoryRequired = !escaped && prompt.length >= 4 && (TASK_RE.test(prompt) || prompt.length > DIRECTIVE_MAX_LEN);
477
+ applyPromptStateReset(s, prompt);
385
478
  s.interactionCount = (s.interactionCount || 0) + 1;
386
479
  writeState(s);
387
- if (!s.tasksCreated) console.log('REMINDER: Use TaskCreate before spawning agents. Task tool is blocked until then.');
388
480
  if (config.context_tracking) {
389
481
  var ic = s.interactionCount;
390
482
  if (ic > 30) console.log('Context: CRITICAL. Commit, store learnings, suggest new session.');
@@ -393,12 +485,30 @@ switch (command) {
393
485
  }
394
486
  break;
395
487
  }
488
+ case 'prompt-state-reset': {
489
+ // Defensive safety-net hook (#931 dedupe). Wired as the second
490
+ // UserPromptSubmit hook so an exception in prompt-hook.mjs doesn't skip
491
+ // the per-prompt state reset. Idempotent — applyPromptStateReset only
492
+ // sets fields to derived values, and we deliberately do NOT increment
493
+ // interactionCount or emit anything (that's prompt-reminder's job).
494
+ //
495
+ // Skip the disk write on the normal path: prompt-reminder runs first and
496
+ // already wrote the byte-identical post-reset state. Only writeState when
497
+ // the reset actually changed something (i.e., prompt-reminder was skipped
498
+ // because prompt-hook.mjs threw before invoking it).
499
+ var s = readState();
500
+ var prompt = process.env.CLAUDE_USER_PROMPT || '';
501
+ var before = JSON.stringify(s);
502
+ applyPromptStateReset(s, prompt);
503
+ if (JSON.stringify(s) !== before) writeState(s);
504
+ break;
505
+ }
396
506
  case 'compact-guidance': {
397
507
  console.log('Pre-Compact: Check CLAUDE.md for rules. Use memory search to recover context after compact.');
398
508
  break;
399
509
  }
400
510
  case 'session-reset': {
401
- writeState({ tasksCreated: false, taskCount: 0, memorySearched: false, memorySearchedBy: {}, memoryRequired: true, learningsStored: false, testsRun: false, simplifyRun: false, interactionCount: 0, sessionStart: new Date().toISOString(), lastBlockedAt: null });
511
+ writeState({ tasksCreated: false, taskCount: 0, memorySearched: false, memorySearchedBy: {}, memoryRequired: true, learningsStored: false, testsRun: false, simplifyRun: false, interactionCount: 0, sessionStart: new Date().toISOString(), lastBlockedAt: null, lastNamespaceHint: '', lastNamespaceHintEmittedBy: {} });
402
512
  break;
403
513
  }
404
514
  default: