moflo
CLAUDE.md19 starsChanged 3 months agoMITView on GitHub
Hard requirement, no exceptions. Consumers run moflo on Windows dev boxes, macOS laptops, and Linux CI runners. Any code that ships in bin/, src/cli/, .claude/scripts/, or node_modules/moflo/ MUST work identically on all three. The smoke harness runs on all three CI platforms specifically to catch divergence. Before any change, audit it against the cross-platform checklist: Verify before pushing — don't trust your local OS: Concrete examples of what cross-platform misses look like in practice: See feedback_cross_platform_mandatory.md (auto-memory) for the running…
- Installs packages
- Commits and pushes
In this repository30 other files it gives its agents.
- src/CLAUDE.mdCLAUDE.md
- communeSkill
- connector-builderSkill
- distillSkill
- divineSkill
- eldarSkill
- flflSkill
- flo-simplifySkill
- floSkill
- floSkill
- guidanceSkill
- healerSkill
- luminariumSkill
- meditateSkill
- memory-optimizationSkill
- memory-patternsSkill
- memory-teamSkill
- memory-worktreeSkill
- optimize-learningsSkill
- perf-auditSkill
- publishSkill
- quickenSkill
- reasoningbank-intelligenceSkill
- reset-epicSkill
- spell-builderSkill
- spell-scheduleSkill
- test-gapsSkill
- vector-searchSkill
- verifySkill
- wardSkill
The file
We split this CLAUDE.md into the rules it gives an agent
7 rules. About 0 are common, 2 are distinctive, and 5 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 21
If your local OS is Windows, mentally simulate the POSIX path (symlinks, case-sensitivity, missing tasklist).
- Distinctive: line 50
If you can't name the consumer surface and failure mode for a non-trivial change, stop and re-scope before writing code.
- Distinctive: line 98
If it goes red, replace the identifier with a neutral placeholder — do not add it to an allowlist.
- Very specific: line 127
Search results carry a compact navigation crumb (parentDoc, prev/next, chunkTitle).
- Very specific: line 137
Prefer MCP (mcp__moflo__* — memory, swarm, agent, task, hooks, hive-mind, neural) over the CLI.
- Very specific: line 141
After npm install touches moflo, check .moflo/restart-pending.json — if present, surface its message field to the user verbatim, then …
- Very specific: line 158
Before creating, rewriting, or editing any .claude/guidance//*.md file, MUST read both:
≈ “Common” is an estimate: at least 1 in 5 of the 26,980 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
⚠ Rule #1 — All shipped code MUST be cross-platform (Linux + macOS + Windows)
Hard requirement, no exceptions. Consumers run moflo on Windows dev boxes, macOS laptops, and Linux CI runners. Any code that ships in bin/, src/cli/, .claude/scripts/, or node_modules/moflo/ MUST work identically on all three. The smoke harness runs on all three CI platforms specifically to catch divergence.
Before any change, audit it against the cross-platform checklist:
- Paths — use
path.join,path.sep,path.resolve. NEVER hardcode/or\. NEVER hardcode/tmp,/usr/local,C:\\Users, etc. - Symlinks — POSIX has them; Windows mostly doesn't. If you compare two paths for identity,
fs.realpathSyncBOTH sides first (otherwise/var/folders/...≠/private/var/folders/...on macOS — see #1145). - Case sensitivity — POSIX FS is case-sensitive; macOS APFS + Windows NTFS are case-insensitive by default. Don't write
Foo.tsandfoo.tsin the same directory. - Line endings — files written by moflo MUST use platform-appropriate EOL or be marked
text=autoin.gitattributes. Tests that hash file contents must normalize. - Shell commands —
bash/grep/sed/cat/finddon't exist on Windows out of the box. Use Node primitives (fs,child_processwithspawnnot shell,Glob/Greptools) instead of shelling out. If you MUST shell, branch onprocess.platform. - Process introspection —
tasklist/wmic/Get-CimInstanceon Windows vsps//proc/<pid>/cmdlineon POSIX. Seedaemon-lock.ts:isDaemonProcess*for the right shape. - Spawning daemons — Windows requires
shell: true+ quoted strings (Node 24 DEP0190); POSIX usesdetached: true. Seecommands/daemon.ts:startBackgroundDaemon. - Tempdir + Windows port reservations —
os.tmpdir()is platform-correct; ports 49152-65535 are reserved on Windows (EACCES) — use 40000-44999 in tests. rm/cp/mkdirin spell bash steps — Windows lacks these on PATH. Usenode -ewithfs/osfor file ops in cross-platform spells.
Verify before pushing — don't trust your local OS:
- The smoke harness (
harness/consumer-smoke/run.mjs) covers all three platforms in CI. Watch macOS + Ubuntu runs, not just Windows. tests/system/runs cross-platform;tests/bin/has explicit Windows + POSIX branches.- If your local OS is Windows, mentally simulate the POSIX path (symlinks, case-sensitivity, missing
tasklist). If POSIX, simulate Windows.
Concrete examples of what cross-platform misses look like in practice:
- #1145 follow-up (this session) —
normalizeProjectRootdidn'trealpathSync→ macOS daemon resolved/var/folders/...→/private/var/folders/...while client saw the unresolved path → identity check false-positived → smoke failed on macOS + Ubuntu, passed on Windows. Shipped because verification was Windows-only. feedback_spell_bash_minimal_path.md— spell bash steps on Windows lackmkdir/rm/cpon PATH; usenode -ewith fs/os.feedback_docker_sandbox_git_safe_directory.md—git config --global safe.directorygets overridden by bind-mounted.gitconfig; must use--system.
See feedback_cross_platform_mandatory.md (auto-memory) for the running list.
⚠ Rule #2 — MoFlo is a library shipped to other projects — READ FIRST, every change
This is an open-source library. The package is installed as a devDependency into consumer projects to make Claude Code more effective in those projects. It is NOT a standalone application — every change you make ships to N consumers via npm install moflo and runs from their node_modules/moflo/... on their machines.
Before writing any code or opening any PR, articulate three things to yourself (and to the user, if non-trivial):
- Consumer surface touched — which file class is this?
bin/,src/cli/,.claude/scripts/,mcp-tools/, hook handlers, init/, settings-generator,claudemd-generator.ts, anything synced tonode_modules/moflo/. Editing a test or internal helper has near-zero blast radius. Editing the launcher, a hook, or anythingflo initwrites touches every consumer. - Failure mode for the on-the-current-version consumer — what breaks for someone on
moflo@<previous>who picks this change up vianpm install moflo@<latest>? Is there a migration? Does the consumer need to do anything? Will their existing.moflo/state still parse? Their hooks still wire? - Round-trip cost — does this require publish-then-reinstall before it takes effect (most runtime fixes do — see the dogfood note below), or does the source edit alone suffice (build/test/internal code)?
Concrete examples of what "consumer impact" looks like in practice:
- #860 — missing
CLAUDE_CODE_HEADLESSguard in the launcher → daemon-spawned headless Claude in every consumer triggered the indexer chain, pegging CPU on a 15-min loop. Cost: a stale-since-shipped guard fired in N consumer environments before anyone noticed. - #854 — silent
catch {}in launcher upgrade flow → consumers stuck across moflo 4.8.x → 4.9.2 with partial migrations and no diagnostic crumbs. Cost: 4+ versions worth of consumer-invisible breakage. - #586 / collapse epic — workspace renamed
@claude-flow/*→@moflo/*→ every consumer with bare imports needed coordinated migration; 5-invariant drift guard now blocks regressions. - #798 — MCP swarm/agent handlers stubbed out as a "simplification" → headline product surface broke in every consumer; 10-story epic to repair.
If you can't name the consumer surface and failure mode for a non-trivial change, stop and re-scope before writing code. "I'll just clean this up while I'm here" is the antipattern that produced every bullet above.
See feedback_consumer_blast_radius.md (auto-memory) for the full posture.
⚠ Rule #3 — No client or contributor project names, ever
moflo is open source and installs into consumer projects. A client's project name, personal filesystem path, or contact domain appearing anywhere in this repo is a disclosure leak. Not a style nit, and not limited to shipped code — git history is permanent.
The vector is issue resolution. These names arrive when an outside project files a PR or issue
and the fix gets written up citing where the bug was seen. Writing Symptoms in the wild
(<their-project>/code) into a regression test's header feels like good provenance and is exactly
how 38 files got contaminated — including 9 runtime output.writeln banners that printed a client
domain into every consumer's terminal, and the Co-Authored-By trailer flo init used to stamp
into every consumer's .claude/settings.json (removed outright in #1398 — moflo no longer writes
any attribution; see the note below).
When resolving an issue or PR that originated outside moflo, never record the reporter's identity. Cite the issue number — that is the durable, non-leaking reference.
Below, <client> stands in for the real name — written literally here so these examples do not
themselves trip the guard.
| Instead of | Write |
Symptoms in the wild (<client>/code, 4.9.7 → 4.9.8) | Symptoms in the wild (a consumer project, 4.9.7 → 4.9.8) |
/Users/eric/Projects/<client>/code | /Users/eric/Projects/consumer-app/code |
const <client>Block = [...] | const consumerBlock = [...] |
<client>-style stale block | consumer-style stale block |
noreply@<client>.com | noreply@cielolimitada.com |
Applies to every surface: runtime strings, JSDoc headers, test fixture names and paths, commit
trailers, and docs/internal/** post-mortems.
No attribution trailers at all (#1398). Separate from the leak rule above: moflo does not add
Co-Authored-By:, Generated with …, or any other tool-attribution line to commits or PR bodies —
not in consumer projects and not in this repo. A consumer's git history is theirs and is permanent;
signing it is not moflo's call. The attribution block is no longer written by flo init, is
stripped from existing projects on session start, and the git-commit safety hook defaults to
adding nothing. Do not reintroduce any of it.
Enforced by tests/guards/client-name-leak-guard.test.ts, which matches the shapes these
identifiers take (project dir under a home path, contact domain in an email, domain on an
attribution line) rather than any list of names — so a brand-new name trips it on first use. The
guard holds no denylist on purpose: spelling the names out to block them would recreate the leak.
If it goes red, replace the identifier with a neutral placeholder — do not add it to an allowlist.
⚠ Dogfooding & local-vs-installed delivery — mandatory reading
MoFlo dogfoods itself: the daemon, hooks, statusline, MCP server, and embeddings indexer ALL run from node_modules/moflo/... (NOT from the source tree). Source edits don't take effect for those runtime layers until publish + reinstall + Claude Code restart. Resolving paths between the source tree and the installed package has dist-vs-source depth pitfalls that bite every consumer if you get them wrong.
Before any of the following, you MUST read .claude/guidance/internal/dogfooding.md:
- Diagnosing any "X is broken" symptom visible in the editor (statusline, daemon, hooks, indexer, upgrade UI) — see § Runtime Symptom Diagnosis
- Adding a new file in
bin/,bin/lib/,src/cli/,dist/, or anything synced to.claude/scripts/— see § Delivering Changes That Work Both Local AND Installed (manifest scope + sync layers) - Resolving any path between TS code and
bin/*.mjs(e.g.dist/src/cli/services/...→bin/lib/...) — see § Delivering Changes That Work Both Local AND Installed § 2 (the../../../../anti-pattern that broke #1126's first iteration) - Adding cross-process daemon coordination, atomic file swaps, or any platform-sensitive primitive — see § Delivering Changes That Work Both Local AND Installed § 6
- Touching the smoke harness or chasing local-vs-CI smoke divergence — see § Smoke Harness Reality
Skip this and you'll either waste a session debugging code that isn't running, ship a change that works in dogfood but breaks every consumer install, or break a consumer's .moflo/ state in a way that takes a full publish-rollback-cycle to recover from.
<!-- MOFLO:INJECTED:START -->MoFlo — AI Agent Orchestration
FIRST ACTION ON EVERY PROMPT — AND EVERY TOPIC CHANGE: Search Memory
Your first tool call MUST be mcp__moflo__memory_search — before any Glob/Grep/Read or read-like Bash (cat, grep, node -e). Search again on every new subject, mid-prompt — new symbol, area, subsystem, or sub-question. A long task is many searches, not one. Pick the namespace by question shape: code-map for "where is symbol X defined", tests for "what tests cover Y", patterns for "what's our pattern for Z", guidance for project rules, learnings for "did we hit this before". Pivot on the bare symbol/keyword (not a natural-language question), and trust similarity ≥ 0.80 as a confident hit. When the user says "remember this", call mcp__moflo__memory_store with namespace learnings.
Traverse chunks, don't bulk-retrieve
Search results carry a compact navigation crumb (parentDoc, prev/next, chunkTitle). For adjacent/sibling/hierarchical context use mcp__moflo__memory_get_neighbors; for full chunk content use mcp__moflo__memory_retrieve; Read the source doc only via parentPath when truly needed. Full protocol + worked examples per namespace: .claude/guidance/moflo-memory-protocol.md.
Gates
- Blocking (hook exits non-zero): memory search before Glob/Grep/guidance Read and before read-like Bash/PowerShell commands; tests +
/flo-simplify+ learnings +/verifybeforegh pr create;swarm_init/hive-mind_initbefore Agent under/fl -s|-h. - Advisory (reminder only):
TaskCreatebefore spawning the Agent tool, entries in ICON+[Role] format — see.claude/guidance/moflo-task-icons.md. - Not enforced: re-searching after a mid-prompt topic change — no hook sees the pivot. Do it anyway.
Tools
Prefer MCP (mcp__moflo__* — memory, swarm, agent, task, hooks, hive-mind, neural) over the CLI. CLI binaries: flo (main), flo-search (semantic search), flo doctor --fix (heal). Full catalog: .claude/guidance/moflo-core-guidance.md.
After upgrading MoFlo
After npm install touches moflo, check .moflo/restart-pending.json — if present, surface its message field to the user verbatim, then delete the file. (Claude Code only loads new hooks/MCP/launcher at session start.)
Monorepos
Moflo state lives at the monorepo root .moflo/ — never run flo init inside a sub-workspace of an existing moflo project, or the MCP server and CLI silently bind to different daemons.
Full Reference
- Universal agent rules (memory protocol, git/PR conventions, file org, build/test):
.claude/guidance/moflo-agent-rules.md - Fix small defects in the PR you are already in — don't file them:
.claude/guidance/moflo-inline-fixes.md - Subagent spawn protocol:
.claude/guidance/moflo-subagents.md - Task + swarm coordination:
.claude/guidance/moflo-claude-swarm-cohesion.md - CLI, hooks, swarm, memory, moflo.yaml:
.claude/guidance/moflo-core-guidance.md
<!-- MOFLO:INJECTED:END -->⚠ Editing guidance — read both rule sets first
Before creating, rewriting, or editing any .claude/guidance/**/*.md file, MUST read both:
.claude/guidance/shipped/moflo-guidance-rules.md— universal writing rules (Purpose line, imperative voice, decision tables, concrete examples, 500-line cap, specific H2 headings, anti-patterns, RAG chunking, See Also)..claude/guidance/internal/guidance-rules.md— moflo-only extensions (moflo-prefix on shipped files, shipped/internal partition contract, bucket-decision rules).
Drive-by edits count too. Auto-memory files under ~/.claude/projects/.../memory/ follow the universal rules where they apply.
Broken Window Theory (mandatory — moflo repo only)
Zero tolerance for unresolved failures. Every failing test, every warning, every bug gets fixed before moving on — no exceptions by severity, no "probably flaky" without individual re-verification. If a test fails in the full suite, retest individually to distinguish real failures from flaky ones. If flaky, fix the flakiness itself (tight timeouts, resource contention, etc.) — don't just re-run and move on. A red signal is never acceptable as background noise.
Fix small defects here — don't file them (mandatory)
The default for a defect you find mid-task is to fix it in the PR you are already in. Filing is the exception and must be earned: name which threshold in .claude/guidance/shipped/moflo-inline-fixes.md § 2 the defect crosses, or fix it. A ticket that costs more to triage than the fix costs to make is pure loss.
Never file a defect your own change caused, unmasked, or invalidated — a test you turned red, a stale bound or count, a test that pinned the bug you just fixed, a lint or type error your edit introduced. That is not a discovery, it is part of the change.
Batch fixes into one push. Fix everything found, run the suite once, push once. Serialised one-fix-per-CI-round pushes are slower than a single careful pass and buy nothing.
Full rule, decision table, and how to surface drive-bys: .claude/guidance/shipped/moflo-inline-fixes.md.
⛔ Protected functionality — swarm + hive-mind (mandatory)
Swarm and hive-mind are CRITICAL moflo product surface. They are headline capabilities (flo swarm, flo hive-mind, MCP tools swarm_* / agent_* / task_* / hive-mind_*, queen/worker hierarchy, consensus). They MUST remain wired and functional across every refactor, migration, collapse, rename, and "cleanup".
Regression includes — not just deletion — but also:
- Disconnection — leaving infrastructure in place but reducing MCP handlers to stubs returning hardcoded literals (e.g.
{ swarmId: 'swarm-' + Date.now() },{ agentCount: 0, taskCount: 0 }, file-based JSON writes that bypass the coordinator). This is the silent failure mode that triggered epic #798. - Stubbing / "simplification" — replacing real coordinator calls with synthetic returns under "we'll wire it later".
- Migration drift — completing one half of a migration (e.g. hive-mind to MessageBus) without the matching swarm/agent half.
Mandatory verification on any change to src/cli/mcp-tools/{swarm,agent,task,hive-mind}-tools.ts, src/cli/swarm/**, src/cli/commands/{swarm,agent,hive-mind}.ts, or related MCP wiring:
agent_spawninvokescoordinator.spawnAgent(...)— not a JSON store writeswarm_initinvokescoordinator.initialize(...)— not literalswarm-${Date.now()}swarm_status/swarm_healthquery the coordinator — not hardcoded valuestask_*invokescoordinator.distributeTasks/executeTask/cancelTaskhive-mind_*routes throughMessageBus+WriteThroughAdapter(Story #121); workers register with the shared coordinator- End-to-end system tests at
tests/system/swarm-restoration-e2e.test.tsexercise the wired path
If a refactor seems to require disconnecting handlers temporarily, STOP and surface it. Load-bearing change requiring explicit owner sign-off — never an in-passing tidy-up. Default to preservation.
Cost of violation: Epic #798 (10 stories) exists solely to repair this regression. The user described it as "costing critical time and money to repair when it NEVER should have been necessary." This rule is non-negotiable.
See feedback_swarm_hive_never_regress.md in auto-memory for full detail.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

