ruvnet / ruvnet/ruflo

Regression: #2284 fix for auto-memory-hook `workingDir` reverted by dogfood-helper sync (a5f86ad0); still broken in 3.41.2

Open
#3,286 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
72.7k
Forks
8.6k
Avg merge
2d 23h
Merged PRs (30d)
83

Description

## Summary

The fix for #2284 (`auto-memory-hook.mjs` hardcodes `workingDir: PROJECT_ROOT`) landed in
`facec4cc` on 2026-06-04, was never propagated to the package-distributed copy, and was
then **reverted on the root copy** by `a5f86ad0` on 2026-07-04. Both copies on `main`
today, and the published `3.41.2` tarball, carry the original buggy line again.

#2284 is closed as COMPLETED, so the regression is invisible.

Separately: the fix addressed only `workingDir`. The underlying `PROJECT_ROOT` definition
it derives from was never touched, so `DATA_DIR` / `STORE_PATH` stay wrong even with the
original fix applied. Details in "Scope" below.

## Regression trail

| Date | Commit | Effect |
|---|---|---|
| 2026-06-04 | `facec4cc` | Fixes #2284 on `.claude/helpers/auto-memory-hook.mjs`: `-workingDir: PROJECT_ROOT` / `+workingDir: process.env.CLAUDE_FLOW_CWD \|\| process.cwd()` (two sites: `doImport`, `doSync`). |
| 2026-06-15 | `e7783f2f` | "reconcile diverged CLI-package helper copies (FIX 2/4/5)" propagates FIX 2/3/4/5 to `v3/@claude-flow/cli/.claude/helpers/`, but not this one. The distributed copy still has the bug. |
| 2026-07-04 | `a5f86ad0` | "chore: sync repo dogfood helpers to 3.23.0" copies the installed package's helpers over the repo's root copy. Since the package copy never received the fix, this reverts it: `-workingDir: process.env.CLAUDE_FLOW_CWD \|\| process.cwd()` / `+workingDir: PROJECT_ROOT`, twice. |

Verification on current `main`:

```
.claude/helpers/auto-memory-hook.mjs:20 const PROJECT_ROOT = join(__dirname, '../..');
.claude/helpers/auto-memory-hook.mjs:275 workingDir: PROJECT_ROOT,
.claude/helpers/auto-memory-hook.mjs:335 workingDir: PROJECT_ROOT,
v3/@claude-flow/cli/.claude/helpers/auto-memory-hook.mjs:20/275/335 (identical)
```

`npm pack @claude-flow/cli@3.41.2` ships the same three lines. The three affected helper
files are byte-identical between 3.41.1 and 3.41.2, so upgrading does not help.

## Scope: the fix was too narrow to begin with

`workingDir` is one of three consumers of the same bad root:

```js
// auto-memory-hook.mjs:20
const PROJECT_ROOT = join(__dirname, '../..');
const DATA_DIR = join(PROJECT_ROOT, '.claude-flow', 'data'); // :21
const STORE_PATH = join(DATA_DIR, 'auto-memory-store.json'); // :22
```

Restoring only the `workingDir` lines fixes *where the bridge looks for memory files*, but
the backend store is still written under the wrong root. Meanwhile `intelligence.cjs`
resolves its own root correctly:

```js
// intelligence.cjs:20-36
function resolveProjectRoot(startDir) {
if (process.env.CLAUDE_PROJECT_DIR) return path.resolve(process.env.CLAUDE_PROJECT_DIR);
// ...walk up looking for .git / .claude-flow
}
const PROJECT_ROOT = resolveProjectRoot(process.cwd());
const STORE_PATH = path.join(PROJECT_ROOT, '.claude-flow', 'data', 'auto-memory-store.json');
```

So the writer and the reader disagree on the store path. `intelligence.consolidate()`
returns `{"entries":0,"edges":0,"message":"No store to consolidate"}` forever, and
`intelligence.init()` returns `{"nodes":0,...,"message":"No memory entries to index"}` —
which the hook-handler prints only when `nodes > 0` (hook-handler.cjs:510), so the user
sees nothing at all. The hooks appear dead while exiting 0.

`metrics-db.mjs:15` and `learning-service.mjs:29` have the identical `join(__dirname, '../..')`
definition.

## Reproduction

Trigger condition is the `$HOME` fallback in the generated `settings.json` hooks:

```
sh -c 'D="${CLAUDE_PROJECT_DIR:-.}"; [ -f "$D/.claude/helpers/hook-handler.cjs" ] || D="${HOME}"; exec node "$D/.claude/helpers/hook-handler.cjs" route'
```

Any project without a local `.claude/helpers/` takes `D="$HOME"`, so the helper runs from
`~/.claude/helpers/` and `join(__dirname, '../..')` resolves to `$HOME` rather than the
project. (#2284 reported the same shape via the plugin marketplace path; the `$HOME`
fallback is a second route to it.)

```bash
cd /path/to/a/project-without-local-helpers
CLAUDE_PROJECT_DIR=$PWD node ~/.claude/helpers/auto-memory-hook.mjs import
# [AutoMemory] ✓ Imported 0 entries (0 skipped)

ls ~/.claude-flow/data/auto-memory-store.json # exists, contains []
ls ./.claude-flow/data/auto-memory-store.json # ENOENT — what intelligence.cjs reads
```

## Suggested fix

Fix the root rather than the three call sites, in both copies of all three helpers:

```js
const PROJECT_ROOT = process.env.CLAUDE_PROJECT_DIR || join(__dirname, '../..');
```

Preferring `CLAUDE_PROJECT_DIR` (rather than re-applying `CLAUDE_FLOW_CWD || process.cwd()`)
makes the `.mjs` helpers agree with `intelligence.cjs`'s existing `resolveProjectRoot()`
precedence by construction, which is the actual invariant being violated. Verified locally:
`Imported 2 entries` → `init: {"nodes":2,...}` → `consolidate: {"entries":2,...}`, with all
artifacts landing under `/.claude-flow/data/`.

Two process points worth considering, since this is the second time this file regresses:

1. `a5f86ad0`'s dogfood-sync direction (installed package → repo) silently overwrites repo
fixes that have not yet shipped. A guard or a sync in the other direction would have
caught it.
2. The two committed copies of these helpers keep diverging (`e7783f2f` exists solely to
reconcile them). A generated-from-single-source arrangement, or a CI check that diffs
`.claude/helpers/` against `v3/@claude-flow/cli/.claude/helpers/`, would close the class.

## Environment

- ruflo 3.41.1 (Homebrew global), `@claude-flow/cli` 3.41.1; verified identical in 3.41.2
- macOS (Darwin 25.6.0), node via Homebrew
- Project with no local `.claude/helpers/` and no `node_modules` (Go project), so both the
`$HOME` hook fallback and the `@claude-flow/memory` resolution path are exercised

## Related

- #2284 — the original bug, closed COMPLETED, regressed
- #2545 — `@claude-flow/memory` unresolvable; the Strategy 0 sidecar
(`.claude-flow/memory-package.json`) from that fix is still required for a project with no
`node_modules`, and `ruflo init` did not create one here
- #2633 — durable state anchored to raw `process.cwd()`; same family of root-resolution drift

Contributor guide

Open the contributing guide

Research direction

Start with .claude/helpers/auto-memory-hook.mjs and its matching v3/@claude-flow/cli copy, then compare metrics-db.mjs and learning-service.mjs with intelligence.cjs's root-resolution logic. Reproduce from a project without local helpers using the documented import command and inspect hook-handler.cjs:510. Done means both helper copies resolve the project consistently and import, init, and consolidate use the project's .claude-flow/data store.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, node.js
Domain
cli, developer-experience, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.