mirror of
https://github.com/ruvnet/ruflo.git
synced 2026-09-14 14:01:28 +08:00
402b701a9d
* 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>
@claude-flow/deployment
Release management, CI/CD, and versioning module for Claude Flow v3.
Features
- Version Bumping: Automatic version management (major, minor, patch, prerelease)
- Changelog Generation: Generate changelogs from conventional commits
- Git Integration: Automatic tagging and committing
- NPM Publishing: Publish packages with tag support (alpha, beta, latest)
- Pre-Release Validation: Lint, test, build, and dependency checks
- Dry Run Mode: Test releases without making changes
Installation
npm install @claude-flow/deployment
Quick Start
Prepare a Release
import { prepareRelease } from '@claude-flow/deployment';
// Bump patch version and generate changelog
const result = await prepareRelease({
bumpType: 'patch',
generateChangelog: true,
createTag: true,
commit: true
});
console.log(`Released ${result.newVersion}`);
Publish to NPM
import { publishToNpm } from '@claude-flow/deployment';
// Publish with 'latest' tag
const result = await publishToNpm({
tag: 'latest',
access: 'public'
});
console.log(`Published ${result.packageName}@${result.version}`);
Validate Package
import { validate } from '@claude-flow/deployment';
// Run all validation checks
const result = await validate({
lint: true,
test: true,
build: true,
checkDependencies: true
});
if (!result.valid) {
console.error('Validation failed:', result.errors);
}
API Reference
ReleaseManager
import { ReleaseManager } from '@claude-flow/deployment';
const manager = new ReleaseManager();
// Prepare release with options
const result = await manager.prepareRelease({
bumpType: 'minor', // major | minor | patch | prerelease
version: '2.0.0', // Override version
channel: 'beta', // alpha | beta | rc | latest
generateChangelog: true, // Generate CHANGELOG.md
createTag: true, // Create git tag
commit: true, // Commit changes
dryRun: false, // Test without changes
skipValidation: false, // Skip validation checks
tagPrefix: 'v', // Tag prefix (v2.0.0)
changelogPath: 'CHANGELOG.md' // Changelog file path
});
Version Bumping
// Bump patch: 1.0.0 -> 1.0.1
await manager.prepareRelease({ bumpType: 'patch' });
// Bump minor: 1.0.0 -> 1.1.0
await manager.prepareRelease({ bumpType: 'minor' });
// Bump major: 1.0.0 -> 2.0.0
await manager.prepareRelease({ bumpType: 'major' });
// Bump prerelease: 1.0.0 -> 1.0.0-alpha.1
await manager.prepareRelease({ bumpType: 'prerelease', channel: 'alpha' });
// Increment prerelease: 1.0.0-alpha.1 -> 1.0.0-alpha.2
await manager.prepareRelease({ bumpType: 'prerelease', channel: 'alpha' });
Changelog Generation
Generates changelog from conventional commits:
# Commit format: type(scope): message
git commit -m "feat(api): add new endpoint"
git commit -m "fix(auth): resolve login issue"
git commit -m "feat(ui): update design BREAKING CHANGE: new layout"
Generated changelog:
## [2.0.0] - 2026-01-04
### BREAKING CHANGES
- **ui**: update design BREAKING CHANGE: new layout
### Features
- **api**: add new endpoint
- **ui**: update design
### Bug Fixes
- **auth**: resolve login issue
Publisher
import { Publisher } from '@claude-flow/deployment';
const publisher = new Publisher();
// Publish to npm
const result = await publisher.publishToNpm({
tag: 'latest', // npm tag (alpha, beta, latest)
access: 'public', // public | restricted
dryRun: false, // Test publish without actual publish
registry: 'https://registry.npmjs.org/',
otp: '123456', // 2FA OTP code
skipBuild: false, // Skip build step
buildCommand: 'npm run build' // Custom build command
});
// Check if version exists
const exists = await publisher.checkVersionExists('my-package', '1.0.0');
// Get latest version
const latest = await publisher.getLatestVersion('my-package', 'latest');
// Verify npm authentication
const authenticated = await publisher.verifyAuth();
// Pack to tarball
const tarball = await publisher.pack('./dist');
Validator
import { Validator } from '@claude-flow/deployment';
const validator = new Validator();
// Validate package
const result = await validator.validate({
lint: true, // Run linter
test: true, // Run tests
build: true, // Run build
checkDependencies: true, // Check dependencies
checkGitStatus: true, // Check uncommitted changes
lintCommand: 'npm run lint',
testCommand: 'npm test',
buildCommand: 'npm run build'
});
console.log('Valid:', result.valid);
console.log('Errors:', result.errors);
console.log('Warnings:', result.warnings);
console.log('Checks:', result.checks);
Complete Release Workflow
import { Validator, ReleaseManager, Publisher } from '@claude-flow/deployment';
async function release(version: string, tag: string) {
// 1. Validate package
console.log('Validating package...');
const validator = new Validator();
const validation = await validator.validate();
if (!validation.valid) {
console.error('Validation failed:', validation.errors);
process.exit(1);
}
// 2. Prepare release
console.log('Preparing release...');
const manager = new ReleaseManager();
const release = await manager.prepareRelease({
version,
generateChangelog: true,
createTag: true,
commit: true
});
if (!release.success) {
console.error('Release preparation failed:', release.error);
process.exit(1);
}
// 3. Publish to npm
console.log('Publishing to npm...');
const publisher = new Publisher();
const publish = await publisher.publishToNpm({
tag,
access: 'public'
});
if (!publish.success) {
console.error('Publish failed:', publish.error);
process.exit(1);
}
console.log(`Successfully released ${publish.packageName}@${publish.version}`);
}
// Run release
release('2.0.0', 'latest');
CLI Usage
# Prepare release
npx @claude-flow/deployment release --version 2.0.0 --changelog --tag
# Publish to npm
npx @claude-flow/deployment publish --tag latest --access public
# Validate package
npx @claude-flow/deployment validate
Dry Run Mode
Test releases without making changes:
// Test release preparation
await prepareRelease({
bumpType: 'minor',
dryRun: true
});
// Test npm publish
await publishToNpm({
tag: 'beta',
dryRun: true
});
Channel/Tag Strategy
alpha: Early development versions (1.0.0-alpha.1)beta: Feature complete, testing (1.0.0-beta.1)rc: Release candidate (1.0.0-rc.1)latest: Stable production release (1.0.0)
// Prerelease workflow
await prepareRelease({ bumpType: 'prerelease', channel: 'alpha' }); // 1.0.0-alpha.1
await publishToNpm({ tag: 'alpha' });
await prepareRelease({ bumpType: 'prerelease', channel: 'beta' }); // 1.0.0-beta.1
await publishToNpm({ tag: 'beta' });
await prepareRelease({ bumpType: 'patch' }); // 1.0.0
await publishToNpm({ tag: 'latest' });
Environment Variables
# NPM authentication
export NPM_TOKEN="your-token"
# Custom registry
export NPM_CONFIG_REGISTRY="https://registry.npmjs.org/"
Error Handling
try {
const result = await prepareRelease({ bumpType: 'minor' });
if (!result.success) {
console.error('Release failed:', result.error);
console.warn('Warnings:', result.warnings);
}
} catch (error) {
console.error('Unexpected error:', error);
}
License
MIT