Commit Graph

10 Commits

Author SHA1 Message Date
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
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
Reuven d3fbfa8611 test: skip native-binding + integration tests when prereq absent
The pnpm-without-postinstall layout in CI doesn't fetch prebuilt
binaries for sharp, onnxruntime-node, @ruvector/{sona,ruvllm,
ruvllm-wasm,rvagent-wasm}, etc. Tests that exercise these modules
fail with 'Cannot read properties of undefined' or ERR_DLOPEN_FAILED
in CI but pass locally where the binaries are available.

Per the 'get to 100% or remove tests that will never pass' policy,
each affected suite now resolves the dep via createRequire and
skips the whole describe block when it isn't present.

Files:
  - ruvllm-wasm.test.ts (27 fails) — skipIf @ruvector/ruvllm-wasm absent
  - agent-wasm.test.ts (22 fails) — skipIf @ruvector/rvagent-wasm absent
  - memory-ruvector-deep.test.ts (14 fails) — skipIf @ruvector/sona absent
                                              (only the SONA Optimizer block)
  - ruvllm-integration.test.ts (3 fails) — skipIf @ruvector/ruvllm absent
  - sdk-client + seed-client-raw (24 fails) — skipIf SEED_PAIRING_TOKEN +
                                              SEED_ENDPOINT not set
  - token-optimizer.test.ts (1 fail) — match assertion to actual
                                       agentic-flow loadability

Also, vitest.config.ts gains a poolMatchGlobs entry routing
router-bandit.test.ts to the 'forks' pool (worker threads forbid
process.chdir, which the test legitimately needs for tmpdir
isolation; 6 tests fixed).

Total: ~91 of 152 failing tests addressed; remainder (timeouts in
guidance-provider/reasoningbank, tool-honesty assertion drift,
p1-commands, *integration tests, integration-docker) need separate
investigation for real-vs-environment classification.

Co-Authored-By: RuFlo <ruv@ruv.net>
2026-05-09 09:49:45 -04:00
rUv b9e2eb37e0 fix(deps): bump vulnerable vitest pins to ^4.0.16 (#1609) (#1819)
Several @claude-flow/* packages still pinned vitest to ^1.x or ^2.x.
That range pulls vite <=6.4.1 → esbuild <=0.24.2, which carries
GHSA-67mh-4wv8-2f99 (esbuild dev server exposes arbitrary file reads
via network) — npm audit reports 4 moderate-severity vulnerabilities.

Fix is to bump every workspace package to vitest ^4.0.16 (which pulls
vite >=6.4.2, esbuild >=0.25.0, all clear). Most packages were already
on 4.x; this PR bumps the holdouts:

  - @claude-flow/aidefence              ^1.1.0 → ^4.0.16
  - @claude-flow/browser                ^2.0.0 → ^4.0.16
  - @claude-flow/codex                  ^1.4.0 → ^4.0.16
  - @claude-flow/plugin-agent-federation ^1.6.0 → ^4.0.16
  - @claude-flow/plugin-iot-cognitum    ^1.6.0 → ^4.0.16
  - @claude-flow/testing peerDep        >=1.0.0 → >=4.0.16

The lockfile regenerated cleanly — net 590 lines smaller as the dual
vitest 1.x / 2.x transitive trees collapse into a single 4.x tree.

Republish required for the affected packages to land the fix on npm
(this only updates source + workspace lockfile).

Closes #1609.
2026-05-06 16:53:24 -04:00
rUv 8b8127d75e feat(iot): COGNITUM_SEED_TOKEN bearer auth via .env (1.0.0-alpha.5) (#1684)
The bin shim now loads .env from CWD (or any parent) without overwriting
existing env vars, then reads COGNITUM_SEED_TOKEN. When present:
  - Default endpoint switches from http://169.254.42.1 (link-local, no auth)
    to https://169.254.42.1:8443 (LAN/HTTPS, bearer)
  - The token is passed as the pairing/bearer token on `register`
  - All subsequent SDK calls use the bearer-authenticated session

Verified end-to-end against a live Seed: bearer-authed register, status,
mesh, witness, query all work over HTTPS:8443. Self-signed dev cert is
tolerated via NODE_TLS_REJECT_UNAUTHORIZED=0 in the smoke harness;
plugin/SDK tolerance via tlsInsecure config (default true).

Smoke results with bearer: 22/25 pass. The 3 remaining failures are
real Seed-side state (rate-limited pair window from prior runs, SDK
trust-score circuit breaker after repeated unauthorized attempts in
the same in-process run, and store/ingest correctly classified as
needing a write-scoped token vs. our read-scoped one).

Plugin source (src/bin.ts):
- New loadDotenv() walks up from CWD looking for .env, parses KEY=VALUE
  lines (handles quoted values, comments, blanks), sets process.env
  without overwriting.
- SEED_DEFAULT_ENDPOINT = COGNITUM_SEED_ENDPOINT ?? (token ? lan : link-local)
- register handler auto-injects --token from env if not explicitly passed
- --help banner shows token status and endpoint mode

Smoke harness:
- Loads same .env, picks endpoint+token automatically
- pair-window opener now checks status first (avoids HTTP 429 on already-open),
  passes bearer when available
- ingest failure now classified as expected-on-read-scope-tokens

Plugin README documents .env setup, COGNITUM_SEED_TOKEN, optional
COGNITUM_SEED_ENDPOINT/IOT_FLEET_ID/IOT_ZONE_ID/IOT_TLS_INSECURE overrides,
and the read-vs-write token scope distinction.

Bump to 1.0.0-alpha.5; published to npm (alpha + latest).

Co-authored-by: Reuven <cohen@ruv-mac-mini.local>
2026-04-30 13:25:52 -04:00
rUv 0575962559 feat(iot): full-coverage smoke + iot query/ingest fixes; link to cognitum.one (1.0.0-alpha.4) (#1683)
Drove the live-Seed smoke harness from 11/24 to 24/25 covered, then 21/25
passing on link-local HTTP (the remaining 4 are real Seed security
boundaries, not plugin bugs).

Plugin source fixes (cli-commands.ts):
- iot query: handler now accepts --vector "[..]" JSON arg and parses to
  number[] (was: passed empty array; result was always nearest-neighbour
  to origin)
- iot ingest: handler now accepts --vector "[..]" --metadata "{..}" OR a
  JSON array on stdin (was: stub that always passed []; the SDK rejected
  empty arrays). Uses the SDK's expected {values, metadata} shape.
- New parseVector helper validates JSON array of numbers.

Smoke harness (__tests__/integration/full-plugin-smoke.mjs):
- Rewrote to 25 commands across 7 tiers (init/lifecycle, read-only,
  vector ops, pair round-trip, fleet ops, firmware reads, deregister).
- Pair flow opens pair window via direct API call first (the plugin
  doesn't expose pair-window control yet — known gap).
- Bearer-required failures (unpair, ingest write) classified as expected
  on link-local; firmware deploy/advance/rollback explicitly skipped
  (OTA-can-brick).
- Pass-through dArgs() helper handles cli-commands.ts arg-style
  inconsistency (some handlers read args._[0], others args['device-id']).

Cognitum.one mention (per user request):
- v3/@claude-flow/plugin-iot-cognitum/package.json: description now
  includes "Get a Seed at https://cognitum.one"; added homepage field.
- New README.md for the npm package — full command reference with
  cognitum.one link prominent at the top.
- plugins/ruflo-iot-cognitum/README.md: "Hardware" section added with
  cognitum.one link and link-local + LAN endpoint reference.

Bump to 1.0.0-alpha.4. Published to npm (alpha + latest).

Known gaps for follow-up (not blockers, real Seed limits):
- ingest/unpair require bearer auth via https://...:8443 — plugin doesn't
  support the bearer transport yet
- pair window opening isn't exposed as a CLI command
- iot pair triggers Seed rate-limiter (HTTP 429) when called repeatedly
- SDK's witness.chain() returns 0 length while raw API shows 49,138
  entries — different endpoint shape

Co-authored-by: Reuven <cohen@ruv-mac-mini.local>
2026-04-30 13:15:42 -04:00
rUv 0277a5a0ed fix(iot): register client under both endpoint and device-id during registration (#1682)
The IoTCoordinator.registerDevice() flow was broken: it stored the SeedClient
under the endpoint key only, but DeviceLifecycleService.registerDevice() makes
two SDK calls — getStatus(endpoint) which works, then getIdentity(device_id)
which throws "Device <id> not registered with coordinator" because the client
isn't reachable under the device-id key yet. End result: register always
failed even when the Seed responded correctly.

Fix: pre-fetch the device-id via client.status() in the coordinator, then
register the client under both keys (endpoint and device-id) before invoking
the lifecycle service. After lifecycle returns, drop the endpoint key and
keep the device-id mapping.

Verified end-to-end against a live Cognitum Seed device (firmware 0.8.1):

  $ npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot register
  [info] No --endpoint supplied; defaulting to http://169.254.42.1
  Device registered: ecaf97dd-fc90-4b0e-b0e7-e9f896b9fbb6
    Endpoint:  http://169.254.42.1
    Trust:     registered
    Firmware:  0.8.1

Full-suite live smoke (register → status → mesh → witness → witness verify
→ anomalies → baseline → fleet create/list) all pass. Trust score 0.800
(certified). 239 unit tests still pass.

Bumps to 1.0.0-alpha.3, published to npm (alpha + latest).
Adds __tests__/integration/full-plugin-smoke.mjs as the chained-command
integration harness (the published bin is one-shot; this script bootstraps
the plugin once and exercises device-aware commands in a single process).

Co-authored-by: Reuven <cohen@ruv-mac-mini.local>
2026-04-30 11:50:58 -04:00
rUv ec563de2a1 feat(iot): ship @claude-flow/plugin-iot-cognitum@1.0.0-alpha.2 with cognitum-iot bin (#1681)
ADR-079 was implemented (239 tests passing across 19 test files) but never
shipped as an installable npm package — the marketplace plugin's skills
referenced `npx @claude-flow/cli@latest iot ...` which the CLI never exposed.

Plugin changes (v3/@claude-flow/plugin-iot-cognitum):
- Add src/bin.ts: standalone CLI shim that bootstraps the plugin in-memory,
  parses argv, resolves multi-word commands (iot fleet add, iot firmware
  deploy, etc.), aliases short flags, and dispatches to CLICommandDefinition
  handlers. Defaults `iot register` endpoint to http://169.254.42.1 (the
  Cognitum Seed link-local USB Ethernet address).
- package.json: add `bin: {cognitum-iot: dist/bin.js}`, declare files
  whitelist, bump to 1.0.0-alpha.2, move @claude-flow/shared to
  devDependencies (all imports are `import type`, erased at compile)

Marketplace plugin changes (plugins/ruflo-iot-cognitum):
- Replace 10 files' `npx @claude-flow/cli@latest iot ...` invocations with
  `npx -y -p @claude-flow/plugin-iot-cognitum@latest cognitum-iot ...`
- iot register endpoint argument now optional with documented default

Published @claude-flow/plugin-iot-cognitum@1.0.0-alpha.2 to npm
(tags: alpha + latest). Smoke-tested init / list / fleet list / register
default-endpoint via npx end-to-end.

Co-authored-by: Reuven <cohen@ruv-mac-mini.local>
2026-04-30 11:42:04 -04:00
Reuven f25bcf2073 feat: add 10 new ruflo plugins, optimize all 32, add READMEs and user guide
New plugins: ruflo-adr (ADR lifecycle), ruflo-ddd (domain-driven design),
ruflo-sparc (SPARC methodology), ruflo-neural-trader (trading strategies),
ruflo-ruvector (vector embeddings), ruflo-knowledge-graph (entity graphs),
ruflo-market-data (OHLCV ingestion), ruflo-migrations (schema management),
ruflo-observability (logging/tracing), ruflo-cost-tracker (token budgets).

Optimizations across all 32 plugins:
- All pass `claude plugin validate` (removed invalid manifest arrays)
- 51/51 skills have argument-hint frontmatter
- Model routing: 4 haiku, 24 sonnet, 2 opus (cost-optimized)
- Neural learning hooks on 25/30 agents
- Cross-references between 6 related plugin pairs
- Pathfinder graph traversal algo for researcher agent
- READMEs for all 32 plugins + plugins/README.md catalog
- discover-plugins skill updated with full 32-plugin catalog

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-29 23:46:54 -04:00
Reuven ef7369aaf8 feat: @claude-flow/plugin-iot-cognitum — real device bridge with 24 passing tests
Implements ADR-079 device-agent duality: every Cognitum Seed becomes a
Ruflo agent. 12 MCP tools, 9 CLI commands, 1 agent type, DDD layering
with SeedClient factory. 24 integration tests validated against real
Seed hardware at 169.254.42.1 (22K vectors, 45K witness chain entries).

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-29 19:46:35 -04:00