Commit Graph

37 Commits

Author SHA1 Message Date
Dragan Spiridonov 3030924f22 fix(security): compare candidate and prefix in the same canonical form (#3011)
* fix(security): compare candidate and prefix in the same canonical form (#3010)

`validate()` resolved the candidate with `fs.realpath` but the allowed
prefixes were only `path.resolve()`d, so the two sides were compared in
different forms and nothing under a prefix reached through a symlink could
ever match. On macOS that is every temp directory — `os.tmpdir()` is
`/var/folders/...` and `/var` is a symlink to `/private/var` — so
`ruflo proxy install` rejected the binary it had just signature-verified.
Linux is unaffected because `/tmp` is real, which is why CI stayed green.

Keep both forms of every prefix and compare against the one matching how
the candidate was resolved. Canonicalizing the prefixes outright would have
broken `validateSync()` / `isWithinAllowed()`, which are documented as
lexical-only, in the mirror direction.

When the candidate's leaf does not exist, canonicalize its longest existing
ancestor instead of falling back to the lexical path — otherwise
`allowNonExistent` (the default) would regress under a symlinked prefix.
That also closes a hole this exposed: `<allowed>/escape/not-written-yet`,
where `escape` symlinks outside the prefix, was previously accepted because
`realpath` threw ENOENT on the missing leaf.

Escapes stay blocked, and the regression tests construct the symlink
explicitly rather than relying on the macOS quirk, so they hold on every
platform. 3 of the 6 fail without this change.

Co-Authored-By: RuFlo <ruv@ruv.net>

* fix(security): keep root prefixes usable and leave strict results untouched

Three defects found by an adversarial review of the previous commit.

`allowNonExistent: false` was still canonicalizing the candidate on ENOENT.
The call already fails, so the only effect was rewriting the `resolvedPath`
and `matchedPrefix` reported back — a silent shape change for any caller
reading those off a rejected result. Canonicalize only when non-existent
paths are actually allowed.

A root prefix (`/`, `C:\`, a UNC share root) already ends in a separator, so
anchoring the boundary as `prefix + path.sep` searched for `//` and rejected
every descendant. Pre-existing at all three comparison sites — this change
only widened how a prefix can end up being a root, since one can now
canonicalize to it. Extracted `isWithinPrefix`, which keeps the boundary
anchored so `/srv/app-secrets` is still outside `/srv/app`.

The guarded symlink tests returned early instead of skipping, so they
reported as passed on a host that cannot create links, and the flag was
never reset between cases. They now skip properly and reset per case.

Also documents that prefixes are canonicalized once, at construction: the
allowlist keeps denoting what it named when configured, rather than handing
whoever can rewrite a link the ability to redirect it later.

Co-Authored-By: RuFlo <ruv@ruv.net>

---------

Co-authored-by: RuFlo <ruv@ruv.net>
2026-08-13 17:02:17 -04:00
rUv c1e8e0c41f fix(security): realpath allowed prefixes so a symlinked prefix isn't rejected (#3010) (#3013)
PathValidator.validate() canonicalizes the candidate path through
fs.realpath (when resolveSymlinks is on, the default), but the constructor
only ever path.resolve()d the allowed prefixes — never realpath'd them. On
any platform where a prefix is itself reached through a symlink (e.g.
macOS os.tmpdir() under /var, itself a symlink to /private/var), the
realpath'd candidate can never match the non-realpath'd prefix, and every
path under that prefix — including the prefix's own contents — is
rejected as "outside allowed directories".

This broke `ruflo proxy install` on macOS: the download and Ed25519
signature verification both succeed, then the defense-in-depth path check
in proxy/install.ts fails on the extracted binary, which lives under a
workDir created via os.tmpdir().

Fix: realpath the prefixes at construction time too, with the same
ENOENT-tolerant fallback to path.resolve() that validate() already uses
for candidates (a prefix directory that doesn't exist yet degrades
gracefully instead of throwing).
2026-08-13 08:36:25 -04:00
rUv f074987ea0 feat(security): implement ADR-377 — AgentDB Retrieval Security Layer (#2874)
Implements all 3 phases of ADR-377 (ruvnet/ruflo#2516, tracked in #2873):
AgentDB's retrieval and write paths had zero certified defenses against
memory poisoning — SMSR (arXiv:2606.12703) shows 93-100% undefended attack
success. All three phases are off by default; enabling each is opt-in via
env flag until independently benchmarked, per the ADR's own gate criteria.

Phase 1 — AgentDbRetrievalGuard (@claude-flow/memory)
- New `agentdb-retrieval-guard.ts`, wired into `AgentDBBackend.search()`
  (covers `query()`'s semantic path too, since it calls `search()`
  internally). Reuses `@claude-flow/security`'s `ToolOutputGuardrail`
  (ADR-131) for the actual OWASP LLM01/LLM08 pattern scan rather than
  duplicating it — `@claude-flow/memory` now depends on
  `@claude-flow/security` (no cycle: security has zero workspace deps).
- Size gate + guardrail scan per retrieved chunk. Flag-only by default;
  `CLAUDE_FLOW_RETRIEVAL_GUARD_STRICT=true` drops unsafe/oversized chunks
  instead of just annotating them. Both flags off by default
  (`CLAUDE_FLOW_RETRIEVAL_GUARD=true` to enable scanning at all).

Phase 2 — MemoryPoisonForensics (@claude-flow/hooks)
- New `workers/memory-poison-forensics.ts`: rolling-window z-score anomaly
  detection on write-interval and content-length features per
  (agentId, namespace), reproducing the Forensic Trajectory Signatures
  (arXiv:2606.30566) shape (behavioral features on write *sequences*, not
  content). Opt-in `HookEvent.PostToolUse` handler for memory-write tools;
  `CLAUDE_FLOW_POISON_FORENSICS=0` disables recording.
- NOT wired into any of this repo's three separate "worker" dispatch
  systems (hooks' own workers/index.ts codebase-analyzers,
  @claude-flow/swarm's worker-dispatch.ts 12-trigger table, or the CLI's
  scheduled daemon) — @claude-flow/swarm is a deliberately
  zero-workspace-dependency package and adding hooks there would break
  that property; picking the wrong one of three ambiguous dispatch tables
  seemed worse than leaving that integration as an explicit follow-up.
  See the file header for detail.

Phase 3 — McpCallerIdentity (@claude-flow/security)
- New `mcp-caller-identity.ts`: per-invocation Ed25519-signed capability
  tokens (callerId + toolName + nonce + 30s TTL by default), native
  node:crypto sign/verify following the same pattern already used by
  `@claude-flow/browser`'s witness-signer.ts (reimplemented rather than
  cross-imported — a security-primitives module depending on the browser
  package would be a backwards layering dependency).
- Standalone issue/verify API; deliberately NOT wired into
  `AgentAuthorizationPropagator.checkToolCall` (ADR-144) or any tool
  dispatcher — this repo has at least 3 distinct `ToolRegistry`
  implementations and guessing which is authoritative risked silently
  wiring the wrong path. `CLAUDE_FLOW_MCP_CALLER_AUTH` defaults to
  disabled, matching the ADR's own text: key distribution needs a
  follow-on ADR before this ships enabled.

Deviations from the ADR's guessed file paths/class names (documented
inline where relevant): the ADR was written against aspirational paths
(`agentdb/retrieval-guard.ts`, a `BackgroundWorker` interface,
`SafeExecutor`) that don't match the real repo layout — implementation
targets the actual `AgentDBBackend`, the actual worker systems, and the
actual `AgentAuthorizationPropagator`/tool-registries respectively.

Tests: 31 new tests across the three packages (9 + 11 + 11), all passing;
full existing suites re-run clean (memory 451, hooks 145, security 570 —
zero regressions).
2026-07-30 14:09:34 -04:00
rUv ddd27576cb fix(release): ship Capability Brain as a self-contained 3.32.30 train (#2829)
* fix(release): bundle policy and Codex runtimes

* fix(release): verify self-contained three-package archives
2026-07-29 01:30:53 -04:00
rUv dbb1f1e1dd feat: capability brain and governed federation plane (#2825)
Adds the live Ruflo capability brain, governed federation and Cognitum product planes, source-bound concurrent harness contracts, ADRs 325-329, and the v3.32.28 guarded release train.
2026-07-29 00:13:16 -04:00
rUv b08246b04a chore(release): bump to 3.32.27 (#2823)
* chore(release): bump to 3.32.27

* chore(release): publish policy security dependency

* chore(release): sign 3.32.27 helper manifest

* ci: harden policy release gates
2026-07-28 22:38:57 -04:00
rUv 495a451cf6 feat: add ADR-324 agentic policy engine (#2822)
* feat(memory): typed provenance in AgentDB (ADR-323)

Corrects and implements the 2026-07-28 dream-cycle research proposal
(PR #2804, closed as superseded) for typed memory provenance in
AgentDB, addressing MemIR/MemSyco-Bench's "provenance-role collapse"
and memory-induced sycophancy findings.

The dream-cycle PR's proposed schema change targeted the wrong table
(`vector_indexes`, which is per-namespace HNSW index metadata, not
per-entry) and its filename collided with the already-merged
`ADR-322-metaharness-flywheel-integration.md` (#2817) — both corrected
here as ADR-323 against `memory_entries`, the real per-record table.

- memory-initializer.ts: `provenance_type` column (user_claim |
  agent_output | system_observation | tool_result | unknown, default
  unknown) on `memory_entries`, migrated for existing DBs via
  `ensureSchemaColumns()`. `storeEntry()`/`searchEntries()` accept and
  validate `provenanceType`/`provenanceFilter`.
- memory-bridge.ts: same wiring for the native better-sqlite3 AgentDB
  v3 path (`bridgeStoreEntry`/`bridgeSearchEntries`).
- commands/memory.ts: `memory store --provenance <type>`, `memory
  search --provenance-filter <types>` (comma-separated, OR semantics).
- mcp-tools/memory-tools.ts + cli-core/mcp-tools/memory-defs.ts:
  `memory_store`'s `provenance_type` param, `memory_search`'s
  `provenance_filter` param (kept in sync across both tool-def sets).

Found and fixed during implementation: an initial design skipped the
RaBitQ/HNSW acceleration paths entirely whenever a provenance filter
was requested (neither carries provenance_type on their candidates).
This reproducibly crashed the CLI process on exit (a libuv assertion
on Windows) after printing correct results. Fixed by never skipping
those paths — RaBitQ now fetches provenance_type in its existing
per-candidate query, HNSW does one batched (namespace, key) lookup
afterward — eliminating the crash across repeated runs. See ADR-323's
"Implementation note" for detail.

7 new end-to-end tests (adr-323-memory-provenance.test.ts), including
a repeated-run regression guard for the crash. Full existing memory
suite re-verified with no regressions (one pre-existing, environment-
specific #2558 test failure confirmed identical against unmodified
main — better-sqlite3's native bridge is unavailable in this dev
environment, unrelated to this change).

Closes the follow-up from dream-cycle PR #2804 (closed as superseded).

Co-Authored-By: claude-flow <ruv@ruv.net>

* fix(memory): enforce provenance across retrieval paths

* feat: add agentic policy engine

* fix: align Codex MCP integration

* fix: keep MetaHarness dependencies optional

* fix: declare MetaHarness as optional peers

* fix: sync workspace lockfile

* fix: document policy tool selection guidance

* test: cover governed in-process flywheel

* ci: make MetaHarness absence drill deterministic
2026-07-28 22:12:19 -04:00
rUv 27410d402b feat(security): ADR-320 — MCP Composition Inspector v2 + ChannelGuard v2 (#2791)
Follow-up from dream-cycle issue #2783 / PR #2784. Implements the v2 that the already-shipped v1 (commits 381b7ebcc/581cd2bf3) explicitly deferred: SimHash-based cross-tool fragment detection for MCP composition, and a ChannelGuard reusing the real InputValidator instead of a reinvented catalog. 29 new tests, 134/134 existing hooks tests passing, 0 regressions, clippy clean.
2026-07-27 17:03:26 -07:00
rUv 076ccf3fed fix(release): exclude security workspace artifacts (#2712) 2026-07-17 16:30:44 -04:00
rUv 14c41d7784 fix(auth): verify OAuth exports in security release (#2711) 2026-07-17 16:29:16 -04:00
ruvnet 87101e28bc fix(proxy): complete Windows OAuth service flow 2026-07-16 17:04:27 -04:00
ruvnet f52ab6e906 feat(proxy): integrate Cognitum auth and meta-proxy lifecycle 2026-07-16 15:56:56 -04:00
rUv 402b701a9d fix(security): ADR-165 Phase 1 — close 5 critical CVEs + refresh registry + audit CI gate (#2508)
* fix(security): ADR-165 Phase 1 — close all critical CVEs, refresh registry, add CI gate

Closes ADR-165 Phase 1. Both workspaces pass `npm audit --audit-level=critical`.

## Before (2026-06-29)

| Workspace | Critical | High | Moderate | Total |
|-----------|----------|------|----------|-------|
| Root      | **1**    | 6    | 31       | 38    |
| v3        | **4**    | 33   | 57       | 97    |

## After

| Workspace | Critical | High | Moderate | Total |
|-----------|----------|------|----------|-------|
| Root      | **0**    | 0    | 31       | 31    |
| v3        | **0**    | 27   | 58       | 88    |

All 5 critical advisories closed (vitest GHSA-5xrq, handlebars prototype-pollution,
protobufjs constructor-pollution, plus 2 more in v3). 12 of 39 high advisories
closed via overrides; the remaining 27 v3 highs are deeper transitive chains
that would require breaking-change major bumps — flagged for ADR-165 Phase 2.

## Changes

### Root workspace overrides (package.json)

- `vitest`: `^1.0.0` → `^3.2.6` (closes critical GHSA-5xrq CVSS 9.8)
- `hono`: `>=4.11.4` → `>=4.12.25` (closes 6 hono advisories)
- `undici`: `>=7.18.0` → `>=8.5.0` (closes 7 undici advisories — bumps the
  stale pin that ADR-165 flagged as still-in-vulnerable-range)
- `vite`: `>=6.4.6` → `>=8.0.16` (closes 2 vite advisories)
- NEW `@grpc/grpc-js`: `>=1.14.4`
- NEW `form-data`: `>=4.0.6`
- NEW `http-proxy-middleware`: `>=3.0.7`
- `@hono/node-server`: `>=1.19.10` → `>=1.19.14`

### v3 workspace overrides (v3/package.json + pnpm.overrides)

- `vitest`: `^4.0.16` → `^4.1.0` (and `@vitest/coverage-v8` matched)
- Top-level + pnpm overrides: `handlebars: >=4.7.9`, `protobufjs: >=8.6.0`
- 27 sub-package `package.json` updated to `vitest ^4.1.0`

### CVE registry refresh (v3/@claude-flow/security/src/CVE-REMEDIATION.ts)

Rewritten from 5 stale Jan-2026 entries to 16 total: 15 fixed, 1 open
(ADR165-OPEN-01 — PII pipeline wiring per ADR-164 §6.1 not yet on
dispatch-layer). `SECURITY_SUMMARY` is now computed dynamically from the
registry; `validateRemediation()` correctly returns `allFixed: false`
with 1 issue. ADR-165 §5 flagged this as THE Phase 2 priority — now closed.

### New CI gate

`.github/workflows/cve-audit.yml`:
- `audit-root` — `npm audit --audit-level=critical` in root, blocking
- `audit-v3` — same in v3, blocking
- `audit-high-report` — warn-only summary on high-severity drift
- Triggers: PR, push to main, daily cron

### ADR-165 §9 evidence ledger addendum

Captures AFTER-remediation `npm audit --json` metadata for both workspaces.
The diff between BEFORE (already in §9) and AFTER makes Phase 1 verifiable.

Also CORRECTED one prior surprise in §9: the `validate-input.ts` in
`mcp-tools/` is NOT a 9-line shim. It's 269 lines of real implementation.
(That was an inaccurate findings note from the initial audit.)

### §7.3 research items resolved

- `protobufjs` v3 chain confirmed gone after override pins
- `handlebars` v3 chain confirmed not user-reachable on the workflow path
  (toolchain-only; override sufficient)
- `validate-input.ts` confirmed real implementation, not a shim (registry
  entry corrected)
- CORS surface check: no `cors()` / `app.use(cors` call sites — the hono
  CORS-wildcard advisory is not exploitable on the current server
- ADR-164 §6.1 PII pipeline NOT wired in current agentbbs dispatch —
  recorded as ADR165-OPEN-01 (Phase 3 work)

## Gates (all PASS)

- `npm audit --audit-level=critical` root: exit 0 (was non-zero)
- `npm audit --audit-level=critical` v3:   exit 0 (was non-zero)
- vitest suites: 105/109 pass (4 skip-conditional — same as before)
- ADR-112 audit: 352/352 tools with guidance
- business-pods smoke: 11/11 PASS
- agentbbs smoke: 8/8 PASS
- agenticow smoke: 8/8 PASS
- cli build: clean (tsc)

## Phase 2+ deferred

The 27 v3 high-severity advisories that remain are transitive chains with
no patched-in-range version. ADR-165 §6 Phase 2 picks these up after the
`cve-watch.yml` automation in §6 lands (NEW PR — not in scope here).

Co-Authored-By: RuFlo <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01WbBa4nccx5aGhXphoHxcni

* chore(lock): regen v3/pnpm-lock.yaml after override updates (PR #2508 CI fix)

PR #2508 added handlebars + protobufjs to v3 overrides + bumped vitest pin,
but v3/pnpm-lock.yaml wasn't regenerated. CI surfaced
ERR_PNPM_LOCKFILE_CONFIG_MISMATCH on every install step.

Same pattern as the previous lockfile-drift fixes on PR #2500 and #2503.

* fix(ci): cve-audit.yml jq-only + regen witness manifests for #1609 marker drift

Two PR #2508 CI failures fixed:

1. Static-regression-guard tripped on cve-audit.yml line 52: the static
   YAML strict-parser sees `if high > 0:` inside the `run: |` block as
   a YAML block-mapping key indicator. Refactored all 3 inline-python
   blocks to use jq (preinstalled on ubuntu-latest) — no embedded
   `if x > 0:` lines, so the YAML guard passes.

2. Witness marker drift smoke flagged fix-marker #1609 — the Phase 1
   vitest bump (4.0.16 → 4.1.0) drifted the cited marker string in
   v3/@claude-flow/aidefence/package.json. Updated `marker` field in
   all 3 platform manifests + `desc` to reference ADR-165 Phase 1, then
   re-signed via plugins/ruflo-core/scripts/witness/regen.mjs.

Co-Authored-By: RuFlo <ruv@ruv.net>
2026-06-29 22:41:24 -04:00
ruvnet 0740ec7416 chore(release): 3.10.38 — CI/witness/security cluster fixes (#2311 #2274 #2312 #2275)
@claude-flow/security 3.0.0-alpha.8 → 3.0.0-alpha.10 (alpha.9 was already
on npm). Adds @noble/ed25519 to dependencies so its TS build succeeds
standalone — closes the TS2307 break that has been red on main since
2026-06-02 (#2311, #2275).

@claude-flow/cli, claude-flow, ruflo 3.10.37 → 3.10.38. CLI also pins
@claude-flow/security to ^3.0.0-alpha.10 so users picking up the wrapper
get the noble dep automatically.

All three published with latest+alpha+v3alpha aligned at 3.10.38.

Co-Authored-By: RuFlo <ruv@ruv.net>
2026-06-08 14:52:00 +02:00
ruvnet 5f3d7f33f2 fix(ci+witness): unblock CI build, witness verify, and trajectory smoke (#2311 #2274 #2312 #2275)
Three HIGH-severity verification-cluster fixes shipping together.

#2311 — `@claude-flow/security` build fails with TS2307: `Cannot find module
'@noble/ed25519'`. The package imports it in integrity-verifier.ts:260 but
never declared it as a dep — the root override didn't propagate (lesson
from #2112). Declare it directly. Unblocks the `ToolOutputGuardrail smoke
(ADR-131)` job and the broader `V3 CI/CD Pipeline failing on main` cluster
documented in #2275.

#2274 — `plugins/ruflo-core/scripts/witness/verify.mjs:175` unconditionally
assigned `ed.etc.sha512Sync`. On `@noble/ed25519` v2 some patch versions
freeze `etc`, throwing `TypeError: Cannot add property sha512Sync, object
is not extensible` and aborting witness verification on every run (6+
documented occurrences). Guard with `if (!ed.etc.sha512Sync)` and a
try/catch fallback — sha512Sync is already wired internally on v2, so the
shim is only needed on v1. Verified against macOS, Linux, and Windows
manifests on this checkout: all three return `Ed25519 signature valid: yes`
with regressed=0 missing=0.

#2312 — `scripts/smoke-trajectory-graph-edges.mjs` TEST 2 OOMs at ~4 GB on
GitHub-runner default heap, killing the `graph trajectory hooks smoke
(ADR-130 P3)` job (SIGABRT exit 134). The allocation lives deep inside
`intelligence.recordTrajectory` → `@ruvector/ruvllm SonaCoordinator` on
first call; the runtime cause is tracked separately. Bump
`NODE_OPTIONS=--max-old-space-size=6144` on the CI step so the job
completes while the leak is investigated.

Co-Authored-By: RuFlo <ruv@ruv.net>
2026-06-08 14:46:00 +02:00
ruv 1c98cbee6e feat(security): P1 implementations for ADR-144, ADR-145, ADR-146
Three independent P1 components, each scoped to a single PR-sized change.
All three are off by default — flips become default in v4.0 — so existing
pipelines keep their exact behaviour.

ADR-144 P1 — AgentAuthorizationPropagator (#2248)
  v3/@claude-flow/security/src/authorization/propagator.ts (new)
  • AuthScope envelope (principal, granted tools/servers, delegation depth, expiry)
  • wrapOutbound: monotonically-reducing scope, depth-decrement, expiry check
  • checkToolCall: typed decisions (tool-not-in-scope / server-not-in-scope /
    scope-expired / delegation-depth-exhausted) — never throws, telemetry-friendly
  • verifyServerAuth: fail-closed on missing/empty credentials (P1 permissive
    accept for non-empty — P4 wires real validator)
  • Provenance buffer ring-bounded for P5 telemetry sink
  • makeLegacyPermissiveScope shim for legacy-mode migrations
  18 unit tests covering every invariant; all pass.

ADR-145 P1 — PluginIntegrityVerifier (#2254)
  v3/@claude-flow/security/src/plugins/integrity-verifier.ts (new)
  v3/@claude-flow/cli/src/plugins/trust/trust-anchors.json (new placeholder)
  • Canonical JSON serialisation (deterministic key order) + SHA-256 manifest hash
  • Ed25519 detached signature verification via @noble/ed25519 (probe-and-fall-
    back, mirrors verify.mjs #1880 pattern so untrusted environments skip
    rather than throw)
  • Trust-anchor allowlist with exact / wildcard scope matching + expiry
  • Structured VerificationStatus (pass / signature-missing / signature-invalid
    / manifest-hash-mismatch / unknown-signer / signer-expired)
  • Stage-2 semantic-intent scan (SCH defence) lands in P2
  13 unit tests including the round-trip sign→verify and tamper-flip cases.

ADR-146 P2 — guardrail call site in MCP dispatch (#2149 follow-up)
  v3/@claude-flow/cli/src/mcp-client.ts — patch callMCPTool
  • Lazy-resolves @claude-flow/security so cold-import cost doesn't hit
    every CLI invocation; falls back to no-op if module unavailable
  • Walks the result object one level deep (matches the flat-record shape
    of every existing tool — deeper traversal would change the p99 latency
    contract)
  • Rejected fields replaced with typed marker: '<rejected-by-guardrail
    tool="X" category=Y>' so callers can surface the rejection rather than
    silently dropping
  • Off by default. CLAUDE_FLOW_STRICT_GUARDRAIL=true turns it on; precedence
    documented inline so the env-var audit passes without an escape-hatch entry.
  4 wiring tests (legacy passthrough, strict-mode reject of known injection,
  strict-mode passthrough on safe content, non-object results pass through).

Security index exports updated for all three. Builds clean (tsc with no
errors). All 4 audits + 2 regression smokes pass locally.

Co-Authored-By: RuFlo <ruv@ruv.net>
2026-06-02 05:44:29 -04:00
rUv a6dd4ab3d5 fix(plugins/ruflo-core/hooks): #2155 — wrap 3 unwrapped .sh hooks in /bin/bash -c (#2161)
* feat(security): #2149 ADR-131 P1 — ToolOutputGuardrail + OWASP 2026 mapping

Closes the OWASP ASI01 (Agent Goal Hijacking) gap identified in the
2026-05-26 dream cycle. Adds a pure, synchronous, pattern-based screener
for content crossing the agent's content boundary (MCP tool results,
memory reads, external API responses) before it enters reasoning.

Design (full rationale in ADR-131):
- Eight built-in pattern categories: instruction-override, embedded-system
  (ChatML / Llama [INST] / <system>), exfiltration, role-hijack, jailbreak,
  hidden-unicode (bidi + zero-width), tool-spoofing, truncation
- Default policy: critical→reject, high→redact, medium→flag, low→allow
- Pure-function shape — safe to invoke in every tool result / memory read
- 32KB content scans in 0.1ms locally (target: <1ms p99)

Scope:
- P1 (this PR): class + tests + exports + ADR + OWASP matrix + CI smoke
- P2-P5 (follow-on): MCP dispatch, memory read, swarm Raft payload,
  per-tool policy + telemetry — tracked in ADR-131

Validation:
- 24/24 vitest tests pass (9ms)
- 11/11 smoke checks against built dist/index.js
- Tested against the four canonical ASI01 attack shapes
- CI guard `tool-output-guardrail-smoke` wired into v3-ci.yml

OWASP Top 10 for Agentic Applications 2026 control matrix added:
v3/docs/security/owasp-agents-2026-mapping.md — flags ASI01/06/09/10 as
highest-priority remaining gaps.

Co-Authored-By: RuFlo <ruv@ruv.net>

* fix(plugins/ruflo-core/hooks): #2155 — wrap 3 unwrapped .sh hooks in /bin/bash -c

Three hooks (PreToolUse:Bash, PreToolUse:Write|Edit|MultiEdit, Stop)
invoked scripts/ruflo-hook.sh directly without an outer shell wrapper.
On Windows, Claude Code's hook executor spawned the .sh path, Node read
the shebang, attempted to exec /bin/bash (absent on Windows), and exited
with code 126 — surfacing as PostToolUse:Bash/PreToolUse:Bash/Stop hook
errors in every user session.

Wrapped each invocation in /bin/bash -c '... || true' to match the
existing pattern of the four other hooks in the same file. The || true
fallback now executes inside the bash subshell rather than relying on
the .sh body being readable. Validated as still working on POSIX.

Co-Authored-By: RuFlo <ruv@ruv.net>
2026-05-27 09:00:35 -04:00
ruv 5b71c7ac13 release(alpha.43+44): pin neural→sona@0.1.5, republish modules w/ standalone READMEs, add npm download badges everywhere (#2022)
This commit closes the chain started in ca0a6fa5c (standalone use recipes
landed in repo but never reached npm because no version bumps shipped).

## Changes

### Module version bumps (alpha.43)
- @claude-flow/memory     → 3.0.0-alpha.17  (republish standalone use README)
- @claude-flow/embeddings → 3.0.0-alpha.18  (republish standalone use README)
- @claude-flow/security   → 3.0.0-alpha.8   (republish standalone use README)
- @claude-flow/neural     → 3.0.0-alpha.9   (pin @ruvector/sona to 0.1.5,
                                             republish standalone use README)
- @claude-flow/cli        → 3.7.0-alpha.43  (repin to new modules above)
- claude-flow             → 3.7.0-alpha.43  (umbrella)
- ruflo                   → 3.7.0-alpha.43  (umbrella)

### Umbrella bump (alpha.44) — npm download badges
- @claude-flow/cli        → 3.7.0-alpha.44
- claude-flow             → 3.7.0-alpha.44
- ruflo                   → 3.7.0-alpha.44

### Neural sona pin (root fix for #2022)
@claude-flow/neural alpha.8 had `"@ruvector/sona": "latest"`, and
@ruvector/sona@0.1.6 (current latest on npm) shipped as an empty publish
— README + package.json only, no index.js or native bins. So every
fresh `npm install @claude-flow/neural@alpha.8` broke at import time
with `Cannot find package '.../node_modules/@ruvector/sona/index.js'`.

Alpha.9 pins to the exact known-good 0.1.5 (which has index.js + 7
platform-specific .node bins). Will revert to a range once
@ruvector/sona@0.1.7+ ships with content (tracked in #2022).

### npm download badges across every published package README
Added `shields.io/npm/dm/<pkg>` (monthly downloads) badges to:
  - claims, cli-core, plugins (had no npm badges at all)
  - plugin-agent-federation, plugin-iot-cognitum (no npm badges)
  - browser, codex, mcp (had version badge, missing downloads)
  - umbrella root README (now badges both `ruflo` + `claude-flow`)
The ruflo/README.md and v3/@claude-flow/cli/README.md auto-copy from
root via prepublishOnly, so they inherit the new badges on publish.

Packages that already carried downloads badges (aidefence, deployment,
embeddings, guidance, hooks, integration, memory, neural, performance,
providers, security, shared, swarm, testing) are unchanged.

## Live functional check on the published artifacts

  - Fresh `npm install @claude-flow/neural@3.0.0-alpha.9`:
    sona resolves to 0.1.5; `import('@claude-flow/neural')` returns
    A2CAlgorithm, BalancedMode, BaseModeImplementation, BatchMode,
    CuriosityModule, ... (was broken before alpha.9).
  - Standalone use sections from ca0a6fa5c now visible on npmjs.com for
    memory@alpha.17, embeddings@alpha.18, security@alpha.8, neural@alpha.9.
  - npm dm/ badges resolve and render the current weekly download count.

Co-Authored-By: RuFlo <ruv@ruv.net>
2026-05-16 16:46:34 -04:00
ruv ca0a6fa5cb docs(modules): publish standalone-use recipes for memory, embeddings, security + flag @ruvector/sona empty-publish blocking neural
Adds a 'Standalone use (without the Ruflo CLI)' section to each
module's README right after Installation, with copy-pasteable
recipes verified against the published artifacts (fresh `npm install`
clean room, no patched dist, exit 0 for every example).

Recipes:

@claude-flow/memory (@3.0.0-alpha.16)
  1. HNSWIndex — add 3 vectors, search top-2, no other deps
  2. ControllerRegistry + injected AgentDB — proves the v3
     governance layer works on a caller-owned AgentDB instance
     (the agentdb injection field added in #2019)

@claude-flow/embeddings
  1. MockEmbeddingService + cosineSimilarity — embed + compare
     without network calls
  2. Provider swap snippet showing OpenAI / Transformers / etc.
     keep the same API surface

@claude-flow/security (@3.0.0-alpha.7)
  1. InputValidator.validate(EmailSchema) +
     new PasswordHasher({ rounds: 12 }) +
     createCredentialGenerator().generateApiKey() — three of the
     OWASP top 10 in ~15 lines
  2. createDevelopmentExecutor — git through the allowlist gate;
     createProjectPathValidator — refuses `../` traversal with
     errors[] surfaced

Bugs uncovered by running the recipes against live npm:

  - `embed()` returns { embedding, tokens, ... }, not a raw Float32Array
    (recipe destructures `.embedding`).
  - createPasswordHasher(rounds: number) accepts a NUMBER, not a
    config object (passing `{ rounds: 12 }` made config.rounds nest
    into `{ rounds: 12 }` and bcryptjs threw 'Illegal arguments:
    string, object'). Switched recipe to `new PasswordHasher(...)`.
  - generateCredentials() does NOT generate API keys — that lives
    on `CredentialGenerator.generateApiKey(prefix)`. Recipe now
    uses createCredentialGenerator().generateApiKey().
  - PathValidator result is { isValid, errors[], ... }, not
    { valid, error }. Recipe matches the real shape.

Not included — @claude-flow/neural standalone recipe:

  @claude-flow/neural@3.0.0-alpha.8 currently fails on fresh
  install because @ruvector/sona@0.1.6 is an empty publish (only
  README + package.json — no index.js, no native bins).
  @ruvector/sona@0.1.5 had full content (index.js + 7 platform
  bins), so this is a regression in the latest sona release that
  blocks the entire neural package from loading.

  Rather than ship a broken recipe, the neural README gains a
  'Known issue' callout pointing at @ruvector/sona@0.1.6. Fix
  path: republish @ruvector/sona with content or pin
  @claude-flow/neural to @ruvector/sona@^0.1.5 in its next bump.

Co-Authored-By: RuFlo <ruv@ruv.net>
2026-05-16 10:00:27 -04:00
rUv ed6d847fa6 fix(security): drop bcrypt → bcryptjs to eliminate tar CVE chain (closes #1608) (#1818)
* fix(security): drop bcrypt → bcryptjs to eliminate tar CVE chain (#1608)

`@claude-flow/security` was pulling 6 HIGH-severity CVEs through this
transitive chain:

  @claude-flow/security → bcrypt@5.1.1 → @mapbox/node-pre-gyp@1.0.11
                       → tar@<=7.5.10  (vulnerable)

  CVEs (all tar <=7.5.10):
  - GHSA-34x7-hfp2-rc4v  Hardlink path traversal → arbitrary file create
  - GHSA-8qq5-rm4j-mr97  Symlink poisoning → arbitrary file overwrite
  - GHSA-83g3-92jg-28cx  Hardlink target escape → arbitrary read/write
  - GHSA-qffp-2rhf-9h96  Drive-relative hardlink path traversal
  - GHSA-9ppj-qmqm-q256  Drive-relative symlink path traversal
  - GHSA-r6q2-hw4h-h46w  Race condition in node-tar path reservations

Downstream consumers of `@claude-flow/security` were forced to add a
`tar` `overrides` block to their own `package.json` to clear
`npm audit`. The umbrella `claude-flow` package already does this, but
direct consumers of `@claude-flow/security` (or anything that depends
on it transitively) couldn't rely on that.

Switch from `bcrypt` (native, requires @mapbox/node-pre-gyp build chain)
to `bcryptjs@^3.0.3` (pure JS, zero native deps, zero tar dependency):

  - Same hash format (`$2a$`, `$2b$`, `$2y$`) — existing hashes verify
    unchanged.
  - Same API surface for the calls this module makes (`bcrypt.hash`,
    `bcrypt.compare`); the `import * as bcrypt from 'bcryptjs'` form
    keeps the rest of the module's call sites byte-identical.
  - Drops the `@types/bcrypt` devDep — bcryptjs ships its own types.

Bumps `@claude-flow/security` 3.0.0-alpha.6 → 3.0.0-alpha.7. Republish
required for downstream consumers to pick up the fix; the source change
itself doesn't move until that publish lands.

Closes #1608.

Co-Authored-By: RuFlo <ruv@ruv.net>

* chore(lockfile): regenerate v3/pnpm-lock.yaml for bcryptjs swap

Companion to the bcrypt → bcryptjs swap in
@claude-flow/security/package.json. CI runs with `--frozen-lockfile`
so the manifest change couldn't land without a matching lockfile.

Most of the diff is incidental patch-version drift of
@opentelemetry/api 1.9.0 → 1.9.1 across vitest dev-deps; the
load-bearing change is the @claude-flow/security entry switching
from `bcrypt` to `bcryptjs` and dropping `@types/bcrypt`.

Co-Authored-By: RuFlo <ruv@ruv.net>
2026-05-06 16:53:18 -04:00
Dragan Spiridonov e50df67226 fix: critical security & performance fixes across 6 packages (#1558)
* fix: critical security & performance fixes across 6 packages

Addresses 11 vulnerabilities from security audit + 5 additional issues
found during devil's advocate review, plus test suite fixes across
memory, security, and swarm packages.

## Security Fixes (Critical)

- CRIT-01: SQL injection in embeddings search — replaced string
  interpolation with parameterized queries (db.prepare/bind)
- CRIT-02: Command injection in 4 files — replaced execSync template
  literals with execFileSync + input validation regex:
  - ruvector/import.ts (docker container name)
  - init.ts (embedding model name, 2 locations)
  - agent-browser-adapter.ts (CLI args)
- CRIT-03: Browser eval hardening — 12 dangerous patterns blocked,
  configurable 20KB length limit via CLAUDE_FLOW_MAX_EVAL_SCRIPT_LENGTH

## Security Fixes (High)

- HIGH-01: ESLint rules restricting child_process imports (both
  import and require) with overrides for safe-executor/daemon/mcp-server
- HIGH-02: Hive-mind truthiness fix (=== true vs !== false)
- HIGH-03: Prototype pollution prevention — safeJsonParse with JSON
  reviver stripping __proto__/constructor/prototype in 3 memory backends
- HIGH-04: Plugin sandbox warning on unsandboxed plugin load
- HIGH-05: HNSW hash collision fix — dual-hash (djb2+sdbm) producing
  53-bit values with bidirectional map and linear probing

## Security Fixes (DA Review)

- DA-CRIT-1: Local json-security.ts to avoid cross-package imports
- DA-CRIT-2: PostgreSQL schema name validation (validateSchemaName)
  added to all 6 ruvector commands via pg-utils.ts
- DA-CRIT-3: PID injection prevention in mcp-server — /proc read +
  execFileSync replacing execSync with PID interpolation
- DA-HIGH-3: Timestamp validation (validateTimestamp) in ruvector import
- DA-HIGH-4: 4 additional browser eval bypass patterns (globalThis,
  .constructor, Reflect, eval())
- DA-HIGH-5: ESLint no-restricted-modules for require() coverage

## Performance Fixes

- PERF-01: BoundedSet<T> for gossip seenMessages — Map-based LRU
  eviction capped at 100K entries, prevents unbounded memory growth
- PERF-02: Bulk operations use Promise.allSettled with batch size 50,
  logging partial failures instead of aborting
- PERF-03: CLI lazy loading — reduced sync imports from 37 to 10
  core commands, async getCommandsByCategory() for help display

## Test Suite Fixes

- Fixed 11 broken import paths in security tests (../../security/ →
  ../src/ and ../../helpers/ → ../helpers/)
- Added vitest.config.ts for security package (was inheriting root
  config with missing setup.ts reference)
- Added allowedDirectories to SecurityConfig test fixture
- Fixed sanitizePath test expectation (leading slash removal)
- Fixed hardcoded /workspaces/claude-flow path in memory tests
- Fixed semanticRouter controller test (auto-enables with agentdb)
- Fixed database-provider count test (namespace-scoped assertion)
- Fixed swarm latency tests (toBeGreaterThanOrEqual for sub-ms mocks)
- Added TypeScript as dev dependency for build verification

## Verification

- 22 automated security verification tests in
  security-verification.test.ts covering all 10 user-facing scenarios
- All 5 packages type-check clean (0 errors)
- memory: 9/9 suites, 353/353 tests pass
- swarm: 4/4 suites, 172/172 tests pass
- security: 13/13 suites, 444/444 tests pass
- CLI help displays all 35 commands correctly with lazy loading

## New Files

- v3/@claude-flow/cli/src/commands/ruvector/pg-utils.ts
- v3/@claude-flow/cli/.eslintrc.json
- v3/@claude-flow/cli/__tests__/security-verification.test.ts
- v3/@claude-flow/memory/src/json-security.ts
- v3/@claude-flow/security/vitest.config.ts

Co-Authored-By: claude-flow <ruv@ruv.net>

* fix: address Sherlock review findings for PR #1558

Finding 2 (MUST FIX): Add formatEmbedding array-element validation
- Validate each embedding value is typeof number && Number.isFinite()
- Prevents SQL injection via crafted JSON arrays with string payloads
- Throws descriptive error with index for debugging

Finding 1: Reclassify CRIT-03 eval blocklist as defense-in-depth
- Add comment clarifying pattern blocklist is best-effort, not a sandbox
- Primary defense is the browser sandbox itself
- Update test description to reflect defense-in-depth classification

Finding 3: Add behavioral tests alongside source-guards
- Add formatEmbedding behavioral test with hostile inputs (NaN, Infinity, strings)
- Add CRIT-02 behavioral test verifying execFileSync array argument pattern
- Categorize existing tests as source-guard vs behavioral in comments

Finding 4: Flag HIGH-02 as behavior change
- Add comment explaining === true vs !== false semantic difference
- Documents that undefined/null no longer treated as "skip permissions"

Finding 6: Export BoundedSet, fix test semantics
- Export BoundedSet from gossip.ts for reuse
- Fix test to use FIFO semantics matching production (not LRU)
- Add FIFO-specific test: re-adding doesn't refresh position

Finding 7: Fix BoundedSet comment math
- Remove speculative throughput time estimate
- Use factual memory calculation: 100K × ~40B IDs ≈ 4MB

Finding 5: No change (false positive — Math.abs in manhattanDistance is correct)

Co-Authored-By: claude-flow <ruv@ruv.net>

---------

Co-authored-by: claude-flow <ruv@ruv.net>
2026-04-08 09:05:59 -04:00
rUv 75fe9f564f fix: address security audit findings from #1375 (#1383)
1. SQL injection: Convert all 9 string-interpolated queries in
   memory-initializer.ts to parameterized queries (db.prepare/bind)
   Closes #1030

2. Preinstall hook: Remove no-op preinstall script and package.json entry
   that triggered supply chain concern

3. SECURITY.md: Add vulnerability disclosure policy with supported
   versions, reporting process, and safe harbor statement

4. SafeExecutor: Remove npx from default command allowlist to prevent
   arbitrary package execution via safe executor

5. Cleanup command: Add `cleanup` command for removing project artifacts
   (.claude/, .swarm/, data/, etc.) with --dry-run default and --force
   to execute. Addresses uninstall documentation gap

Published as v3.5.40. All fixes verified in Docker.

Closes #1375
2026-03-19 11:25:54 -04:00
rUv e300bb55eb Checkpoint: File edits
Automatic checkpoint created by Claude Code
- Branch: v3
- Timestamp: 2026-01-07T19:04:42Z
- Changes: 19 file(s)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 19:04:42 +00:00
rUv 6ad7a378d0 fix(hooks): Fix checkpoint hooks to handle plain file paths
- Updated standard-checkpoint-hooks.sh to accept both JSON and plain paths
- Fixed pre-edit and post-edit functions to detect input format
- Fixed v3 CLI hook flags (-f -> --file, -c -> --command, etc.)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 02:54:48 +00:00
rUv bad2be3919 feat(claims): Complete ADR-016 claims module implementation
- Add @claude-flow/claims package with 161 passing tests
- Implement ClaimService, WorkStealingService, LoadBalancer
- Add domain types, events, rules per ADR-016 spec
- Create 17 MCP tools for claiming, stealing, load balancing
- Add CLI commands for issue management
- Fix type errors: ClaimStatus, status transitions, exports
- Enable auto-commit and auto-push in settings.json
- Update v3 packages and configurations

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 22:38:00 +00:00
rUv 451c7c3799 checkpoint: File edit:
🚀 Generated with [Claude Code](https://claude.com/claude-code)
📊 V3 Development Progress Checkpoint

Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
2026-01-05 22:31:04 +00:00
rUv 89672e5031 checkpoint: File edit:
🚀 Generated with [Claude Code](https://claude.com/claude-code)
📊 V3 Development Progress Checkpoint

Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
2026-01-05 22:30:58 +00:00
rUv e0098d926c checkpoint: File edit:
🚀 Generated with [Claude Code](https://claude.com/claude-code)
📊 V3 Development Progress Checkpoint

Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
2026-01-05 14:55:55 +00:00
rUv ff7c35be6f checkpoint: session completed - V3 development session completed
🚀 Generated with [Claude Code](https://claude.com/claude-code)
📊 V3 Development Progress Checkpoint

Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
2026-01-05 13:19:18 +00:00
rUv 04bcef037e checkpoint: File edit:
🚀 Generated with [Claude Code](https://claude.com/claude-code)
📊 V3 Development Progress Checkpoint

Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
2026-01-05 05:10:07 +00:00
rUv 7c811c1c96 v3: Major cleanup, benchmarking, and documentation
## Cleanup (~1000KB removed)
- Remove /implementation/ planning docs (no longer needed)
- Remove duplicate /coordination/, /core/, /shared/, /types/ folders
- Remove stale status/tracking MDs from @claude-flow modules
- Remove /docs/reports/ status documents

## Performance Benchmarking
- Add scripts/quick-benchmark.mjs for fast performance validation
- Add __tests__/setup.ts (required by vitest config)
- Add @claude-flow/memory/framework/benchmark.ts utilities
- All benchmarks passing targets:
  - Event Bus: 6ms for 100k events (<50ms target)
  - Map Lookup: 16ms for 100k gets (<20ms target)
  - O(n) to O(1) optimization: 978x speedup confirmed

## Documentation
- Complete rewrite of v3/README.md with:
  - Architecture overview (10 ADRs)
  - Module architecture diagram
  - Full directory structure
  - Usage examples for all 10 modules
  - Performance targets and achievements
  - Installation and testing instructions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 03:00:34 +00:00
rUv 8395c4749d checkpoint: File edit:
🚀 Generated with [Claude Code](https://claude.com/claude-code)
📊 V3 Development Progress Checkpoint

Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
2026-01-04 23:50:45 +00:00
rUv 31f38f3723 checkpoint: File edit:
🚀 Generated with [Claude Code](https://claude.com/claude-code)
📊 V3 Development Progress Checkpoint

Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
2026-01-04 20:24:17 +00:00
rUv 0ed58ca5b1 feat(v3): ADR-003 coordinator consolidation + security tests fixed
## ADR-003: Single Coordination Engine
- SwarmHub refactored as thin facade over UnifiedSwarmCoordinator
- ~600 lines of duplicate logic eliminated
- Full backward compatibility maintained
- Comprehensive migration guide created

## Security Tests
- All 444/444 tests passing (100%)
- Edge cases fixed: path traversal, command injection, input validation
- CVE-1, CVE-2, CVE-3 remediation verified

## Documentation
- ADR-003 implementation status and consolidation docs
- Swarm module README and migration guide
- Security edge cases documentation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 19:25:11 +00:00
rUv 98e419de44 checkpoint: File edit:
🚀 Generated with [Claude Code](https://claude.com/claude-code)
📊 V3 Development Progress Checkpoint

Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
2026-01-04 19:20:17 +00:00
rUv 5a70729bdc checkpoint: File edit:
🚀 Generated with [Claude Code](https://claude.com/claude-code)
📊 V3 Development Progress Checkpoint

Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
2026-01-04 17:48:23 +00:00
rUv 53cfd8a534 checkpoint: File edit:
🚀 Generated with [Claude Code](https://claude.com/claude-code)
📊 V3 Development Progress Checkpoint

Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
2026-01-04 17:40:48 +00:00