Commit Graph

7 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 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 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