Skip to content

dev → main#86

Merged
node9ai merged 25 commits intomainfrom
dev
Apr 13, 2026
Merged

dev → main#86
node9ai merged 25 commits intomainfrom
dev

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

Changes on dev

Tests: ✗ failing


PR opened automatically by node9 CI agent

github-actions bot and others added 25 commits April 9, 2026 18:38
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Automatically hashes MCP server tool definitions (name, description,
inputSchema) on first connection and blocks if they change on subsequent
connections. This defends against "rug pull" attacks where a trusted MCP
server silently modifies tool descriptions to inject malicious instructions.

- Replace child.stdout.pipe() with readline interceptor in MCP gateway
  to inspect tools/list responses before forwarding to the agent
- SHA-256 hash of canonicalized tool definitions, sorted by name
- Pin storage at ~/.node9/mcp-pins.json (atomic writes, mode 0o600)
- On mismatch: return JSON-RPC -32000 error with clear remediation steps
- CLI: node9 mcp pin list/update/reset for pin management
- 20 unit tests (hashing, storage, pin lifecycle)
- 5 integration tests (first pin, match, rug pull block, re-pin, transparency)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… review-and-approve update

Addresses adversarial review findings:

1. Pin file reads fail closed: corrupt/unreadable pin files now throw
   instead of silently returning empty (which re-trusted the upstream).
   Only ENOENT is treated as "no pin exists."

2. Session quarantine: tools/call is blocked until a tools/list pin check
   passes. Mismatch or corrupt pin state permanently quarantines the
   session — no tool calls forwarded until the operator resolves it.

3. Pin update is now a review flow: `mcp pin update` spawns the upstream,
   fetches current tools, diffs old vs new definitions, and requires
   explicit operator confirmation before re-pinning.

4. README updated with MCP tool pinning section explaining the rug pull
   defense and CLI commands.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Revert mcp pin update to simple delete-and-repin. The review-and-approve
flow (upstream fetch, diff display, confirmation prompt) adds ~170 lines
and is a UX enhancement — not a security fix. Moving to a follow-up PR
to keep this one focused on the two security hardening changes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- pin list: uses readMcpPinsSafe() to show friendly error on corrupt file
- pin update: catches corrupt file with recovery instructions
- pin reset: works on corrupt files (clears without reading first)
- README: fix stale comment about pin update reviewing diffs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
node9_rule_add only accepts block/review verdicts — allow is explicitly
rejected at both schema and runtime levels to prevent AI from bypassing
node9 security policies.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Chained commands like `git add . && git commit && git push` were
bypassing git push/destructive/force-push rules because ^ only matched
when git was at the start of the command. Replaced with \b word boundary.

Same fix applied to review-sudo.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two bugs fixed:

1. mcp-pin.unit.test.ts Windows home dir mock:
   Set USERPROFILE alongside HOME — os.homedir() on Windows reads
   USERPROFILE, not HOME, so the temp dir mock was ignored and all
   pin file operations read from the real home directory.
   Skip 0o600 permission test on Windows (Unix file modes not supported).

2. mcp-gateway/index.ts ERR_USE_AFTER_CLOSE crash:
   When drainPendingToolCalls() replays queued tool calls after stdin
   has already closed, agentIn is in a closed state. Calling pause()
   on a closed readline interface throws ERR_USE_AFTER_CLOSE.
   Guard with !deferredStdinEnd — if stdin already closed, the stream
   is done and there is nothing to pause.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: andreykh89 <andreykh89@users.noreply.github.com>
- Add optional description field to SmartRule interface
- Pass ruleDescription through policy → orchestrator → check.ts
- Show description in /dev/tty review/block card for human-readable context
- Add descriptions to all DEFAULT_CONFIG built-in rules and ADVISORY_SMART_RULES
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
LICENSE file and package.json already declared Apache-2.0; the README
badge was incorrect.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- README: adds Flight Recorder & HUD section showing the 3-line statusline
  (security state, context/rate limits, environment counts)
- config-schema: adds `description` field to SmartRuleSchema alongside `reason`
- policy: falls back to `reason` when `description` is absent so friendly
  messages always render in the approval popup

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
node9 init is the correct command for initial setup; node9 setup is
the targeted per-agent alias (setup claude, setup hud, etc.)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor Author

🔍 node9 Code Review

Review

The AI applied no changes (empty diff). This is correct behavior here.

The original diff is purely a documentation change — renaming node9 setup to node9 init in three places in README.md. There are no security issues, logic errors, or correctness problems to fix in documentation-only changes.

The test failures are unrelated to this diff; they stem from the test runner rejecting the command string npm run build 2>&1 && npm test 2>&1 due to shell metacharacters (&&, 2>&1), which existed both before and after and have nothing to do with the README edits.

No issues with the AI's decision to make no changes.


Automated review by node9

@github-actions
Copy link
Copy Markdown
Contributor Author

🔒 node9 Security Review

✅ No security issues found.


Automated security review by node9

@node9ai node9ai marked this pull request as ready for review April 13, 2026 10:03
@node9ai node9ai merged commit 6c98c96 into main Apr 13, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants