mirror of
https://github.com/ruvnet/ruflo.git
synced 2026-11-09 22:13:39 +09:00
* dream(security): #3138 opt-in MCP governance policy enforcement (evaluated, ACCEPT) .harness/mcp-policy.json declared auditLog/maxToolCallsPerTurn/dangerousPatterns but was only ever read by the offline metaharness mcp-scan linter -- the actual running claude-flow MCP server (mcp-server.ts) never consulted it, so any connected client could call every tool with no audit trail and no call budget. Adds an opt-in PolicyEnforcer (RUFLO_MCP_ENFORCE_POLICY=1, default off) wiring auditLog + maxToolCallsPerTurn into the real tools/call dispatch path. Default behavior is unconditionally unchanged. 16/16 new tests, 39/43 broader MCP regression sweep (4 failures traced to pre-existing unbuilt sibling packages, unrelated to this change). Independent adversarial critique found one real, disclosed limitation (maxToolCallsPerTurn is session-lifetime cumulative, not true per-turn) -- documented in the module, gist, and issue; not a blocker for landing opt-in/default-off. Full research, hypothesis, evaluation receipt, and witness: issue #3138 and docs/dream-cycle/dream-gist-2026-08-31.md. Co-Authored-By: RuFlo <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01QqhXjtDofNNJPX3CCVQyrk * dream(security): fail-closed on policy load/audit-log failure (review round 1) Addresses ruvnet's PR review on #3139: an enforcement feature that silently falls back to unrestricted execution when its own config is missing/malformed, or when a mandatory audit-log write fails, isn't real enforcement. - loadMcpPolicy() returning null (missing/malformed .harness/mcp-policy.json) now denies the call instead of falling through unconstrained. - A failed appendAuditLog() write, when policy.auditLog is true, now denies the call instead of silently proceeding unaudited. - New evaluateToolCall() is the single enforcement entry point combining fail-closed policy loading + budget + fail-closed audit logging; mcp-server.ts's tools/call wiring simplified to call it directly. - 8 new tests: fail-closed on null policy, fail-closed on malformed JSON on disk (server-integration level), fail-closed on unwritable audit log (server-integration level + unit level), concurrent-call budget accounting. 24/24 passing. Two of the review's five findings remain open by design, not silently dropped: the maxToolCallsPerTurn session-lifetime-vs-per-turn semantic gap (needs a real TTL/reset design) and the stdio-only enforcement scope (HTTP/ WS transport lives in a separate @claude-flow/mcp package) — both already documented in this module's own doc comment and flagged as follow-up in the PR/issue, not attempted here to keep this round's diff reviewable. Getting the repo's other currently-broken workflows (CI/CD Pipeline, CVE Audit Gate, Cross-Agent Integration Tests, V3 CI, Verification Pipeline) green is out of scope for this PR — confirmed pre-existing and base-branch- wide (see PR comment), unrelated to this diff. Co-Authored-By: RuFlo <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01QqhXjtDofNNJPX3CCVQyrk --------- Co-authored-by: Claude <noreply@anthropic.com>