Files
ruflo/scripts
ruvnetandClaude Opus 5 f02759cd6d ci(guard): fail when a non-bundled @claude-flow/* leaf changes without a publish
Adds scripts/audit-leaf-package-publish.mjs, wired into v3-ci.yml's existing
audit job (semver is already installed there).

Only four @claude-flow/* components are bundled into the release tarballs —
INTERNAL_RUNTIME_PACKAGES in stage-internal-runtime-bundles.mjs: security,
codex, mcp, plugin-agent-federation. cli-core, neural, shared and memory
resolve from the REGISTRY at whatever v3/@claude-flow/cli/package.json pins, so
a merged source change in one of those does NOT ship with the three-package
train: the release silently carries the last published copy.

This has bitten twice. #3334 fixed RUFLO_INTELLIGENCE_MODE in
@claude-flow/memory; v3.42.1 shipped the train only and a fresh consumer
install had zero references to the fix (#3335). #3390's reasoningBank
activation spanned cli/src/memory/memory-bridge.ts AND
memory/src/controller-registry.ts — publishing only the train would have
shipped the bridge half and left the embedder half unreachable, leaving
reasoningBank exactly as inert as before. It was caught by hand and
memory@3.0.0-alpha.25 went out alongside v3.42.5.

What makes it easy to miss is that CI goes GREEN: the leaf's own package tests
run against workspace source, so the change looks verified while being
unshippable.

The audit asserts:
  1. every non-bundled leaf's workspace version is covered by the CLI's
     declared range (a miss means the release resolves to OLDER code than
     this repo's source);
  2. diff mode — if a leaf's publishable source changed vs the base ref but
     its version did not, fail with remediation.

It imports INTERNAL_RUNTIME_PACKAGES rather than restating it, so the bundled
and non-bundled sets cannot drift apart; exits non-zero if it inspects zero
leaves, so a broken classifier can't report clean; and reports a skipped diff
check as NOT EXERCISED rather than as a pass.

@claude-flow/shared is entered as a time-boxed accepted finding (expires
2026-10-21): the CLI pins 3.0.0-alpha.7 while the workspace is at
3.0.0-alpha.8, which IS published — stale, not unshippable. Raising the pin
edits v3/@claude-flow/cli deps and so forces a pnpm-lock.yaml regen in the same
change (#2540 -> #2552), which wants its own PR. An EXPIRED entry fails the
guard rather than muting it.

Negative-controlled, all four paths:
  - memory source changed, no bump      -> FAIL (replays #3390)
  - same change with a version bump     -> pass
  - test-only change in a leaf          -> pass (not publishable)
  - waiver expiry backdated             -> FAIL, "no longer honoured"

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-21 16:49:17 -04:00
..
2026-01-04 19:30:59 +00:00