From 1d79068c56874c419a53376c558c5afeed00cf83 Mon Sep 17 00:00:00 2001 From: ruv Date: Sun, 27 Sep 2026 13:30:29 -0400 Subject: [PATCH] fix(ci): repair CI regressions surfaced by the integrated community fixes - plugins/ruflo-adr smoke step 20: #3432 correctly split the memory-db cwd into a more precise DB_ROOT (nearest .git/.swarm ancestor of ROOT), but the smoke check still only recognized the literal `cwd: ROOT` string. Accept `cwd: DB_ROOT` too. - plugins/ruflo-core smoke step 6: #3428 replaced the old "pinned to v3.6" CLI compatibility line with an accurate description of the new resolve-installed-before-npx-fallback contract. Updated the smoke check to verify that contract's env vars are documented instead of a version pin that no longer exists. - session-tools.ts: CodeQL flagged Math.random()-derived session IDs as insecure randomness in a security context, newly reachable through #3486's activate path. Switched both session ID generators to randomUUID(), matching the convention already used in mcp-server.ts and autopilot-state.ts. --- plugins/ruflo-adr/scripts/smoke.sh | 12 ++++++++---- plugins/ruflo-core/scripts/smoke.sh | 11 ++++++++--- v3/@claude-flow/cli/src/mcp-tools/session-tools.ts | 5 +++-- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/plugins/ruflo-adr/scripts/smoke.sh b/plugins/ruflo-adr/scripts/smoke.sh index 64a6181b0..3c37a6d4e 100755 --- a/plugins/ruflo-adr/scripts/smoke.sh +++ b/plugins/ruflo-adr/scripts/smoke.sh @@ -160,14 +160,18 @@ grep -q "from './lib/parse-adrs.mjs'" "$ROOT/scripts/import.mjs" || miss="$miss grep -q "from './lib/parse-adrs.mjs'" "$ROOT/scripts/reindex.mjs" || miss="$miss reindex.mjs-not-using-lib" [[ -z "$miss" ]] && ok || bad "$miss" -# 20. import.mjs and verify.mjs pass cwd to every memory subprocess call (#2666 point 2) -step "20. import.mjs + verify.mjs pass cwd: ROOT to every npx memory subprocess" +# 20. import.mjs and verify.mjs pass an explicit memory-project-root cwd to every +# memory subprocess call (#2666 point 2). #3097 split this into DB_ROOT (nearest +# .git/.swarm ancestor of ROOT) so a scan root can differ from the memory-db root; +# either an explicit ROOT or DB_ROOT satisfies the "not the inherited process cwd" +# contract this step checks. +step "20. import.mjs + verify.mjs pass cwd: ROOT/DB_ROOT to every npx memory subprocess" miss="" imp_calls=$(grep -c "spawnSync('npx'" "$ROOT/scripts/import.mjs") -imp_cwd=$(grep -c "cwd: ROOT" "$ROOT/scripts/import.mjs") +imp_cwd=$(grep -c "cwd: ROOT\|cwd: DB_ROOT" "$ROOT/scripts/import.mjs") [[ "$imp_calls" -gt 0 && "$imp_cwd" -ge "$imp_calls" ]] || miss="$miss import.mjs($imp_cwd/$imp_calls)" ver_calls=$(grep -c "spawnSync('npx'" "$ROOT/scripts/verify.mjs") -ver_cwd=$(grep -c "cwd: ROOT" "$ROOT/scripts/verify.mjs") +ver_cwd=$(grep -c "cwd: ROOT\|cwd: DB_ROOT" "$ROOT/scripts/verify.mjs") [[ "$ver_calls" -gt 0 && "$ver_cwd" -ge "$ver_calls" ]] || miss="$miss verify.mjs($ver_cwd/$ver_calls)" [[ -z "$miss" ]] && ok || bad "$miss" diff --git a/plugins/ruflo-core/scripts/smoke.sh b/plugins/ruflo-core/scripts/smoke.sh index 8bfa5a6aa..c3c5c8bfa 100755 --- a/plugins/ruflo-core/scripts/smoke.sh +++ b/plugins/ruflo-core/scripts/smoke.sh @@ -59,9 +59,14 @@ else bad "expected ≥25 distinct ruflo-* references, got $n" fi -step "6. README pins @claude-flow/cli to v3.6" -grep -qE "@claude-flow/cli.*v3\.6|v3\.6.*claude-flow/cli" "$ROOT/README.md" \ - && ok || bad "Compatibility pin to v3.6 missing" +# #3428: the launcher no longer pins to a fixed CLI minor line — it resolves a +# built/installed @claude-flow/cli first and only falls back to `npx @latest`. +# The compatibility contract now documents that resolution order instead of a +# version pin; verify the README still describes it accurately. +step "6. README documents the CLI resolution/fallback contract" +grep -qE "RUFLO_MCP_CLI_OVERRIDE" "$ROOT/README.md" \ + && grep -qE "RUFLO_MCP_SKIP_NPX" "$ROOT/README.md" \ + && ok || bad "CLI resolution/fallback contract missing from README" step "7. README cross-references sibling contracts" F="$ROOT/README.md" diff --git a/v3/@claude-flow/cli/src/mcp-tools/session-tools.ts b/v3/@claude-flow/cli/src/mcp-tools/session-tools.ts index 66d2d0f15..3da5bda41 100644 --- a/v3/@claude-flow/cli/src/mcp-tools/session-tools.ts +++ b/v3/@claude-flow/cli/src/mcp-tools/session-tools.ts @@ -5,6 +5,7 @@ */ import { existsSync, readFileSync, readdirSync, unlinkSync, statSync, writeFileSync } from 'node:fs'; +import { randomUUID } from 'node:crypto'; import { join } from 'node:path'; import { type MCPTool, getProjectCwd } from './types.js'; import { @@ -162,7 +163,7 @@ export const sessionTools: MCPTool[] = [ if (!v.valid) return { success: false, error: v.error }; } - const sessionId = `session-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`; + const sessionId = `session-${Date.now()}-${randomUUID().slice(0, 8)}`; // Load related data based on options const data = loadRelatedStores({ @@ -548,7 +549,7 @@ export const sessionTools: MCPTool[] = [ let parsed: SessionRecord; try { parsed = JSON.parse(readFileSync(inputPath, 'utf-8')); } catch (e) { return { error: `Invalid session JSON: ${(e as Error).message}` }; } - const newId = `session-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`; + const newId = `session-${Date.now()}-${randomUUID().slice(0, 8)}`; const stats = parsed.stats || { tasks: 0, agents: 0, memoryEntries: 0, totalSize: 0 }; const session: SessionRecord = { sessionId: newId,