Skip to content

Add command risk engine, MCP trust registry, audit export and network mode#43

Merged
00PrabalK00 merged 1 commit into
mainfrom
feat/governance-safety
May 31, 2026
Merged

Add command risk engine, MCP trust registry, audit export and network mode#43
00PrabalK00 merged 1 commit into
mainfrom
feat/governance-safety

Conversation

@00PrabalK00
Copy link
Copy Markdown
Owner

Why

Strategy §Phase3 + §Gap5: productize security/governance (81% of devs cite security concern). Four self-contained, deterministic, stdlib-only features in one cohesive PR. Existing default behavior is unchanged (network absent/on, approval threshold high).

Features

1. Command risk engine (§Phase3.10) — continuum/command_risk.py

classify(command_str) returns {category, level, signal, command}. Categories: read_only, build, test, file_write, network, package_install, destructive, credential_access, unknown. Conservative ordered rules; prefers unknown/low over a wrong-confident guess. destructive/credential_access are always high.

  • CLI: continuum command classify "<cmd>" [--json] — exits non-zero when level==high so it can gate scripts.
  • Policy: new approval_required_risk (default high) + requires_approval(command, policy) helper.

2. MCP trust registry (§Phase3.11 / #33) — continuum/mcp_trust.py

.continuum/mcp_trust.json with entries {server, status, tool_allow, tool_deny, risk_score, last_changed}.

  • CLI: continuum mcp trust list|add|set|allow|deny|remove; every mutation audits mcp_trust_changed and stamps last_changed.
  • is_tool_allowed(registry, server, tool): deny > allow > status default; untrusted/blocked servers' tools denied unless explicitly allow-listed; unknown servers default-untrusted (MCP guidance).

3. Audit export (§Gap5) — continuum/audit_export.py

continuum audit export [--since <ISO|Nd>] [--format json|md] [--output <path>]. Default stdout. No secret values are stored or emitted (the scrubber only records counts/types).

4. Local-only / no-network mode (§Gap5)

Policy gains network: on | local_only | off (default on). ProviderManager refuses hosted providers (openrouter) under local_only/off, and local Ollama under off, with a policy_network_block audit event. Surfaced as a badge in continuum status and continuum doctor.

Real smoke output

F1:

$ continuum command classify "rm -rf /"
Category: destructive  Risk level: high  Matched signal: rm with recursive/force flag
Approval required: yes   (rc=1)
$ continuum command classify "git status"
Category: read_only  Risk level: low   Approval required: no   (rc=0)

F2:

$ continuum mcp trust add acme-tools; set --status trusted; deny delete_all; allow read_file; list
acme-tools: trusted risk=0  allow: read_file  deny: delete_all

F3:

$ continuum audit export --format md
| M2 | ... | mcp_trust_changed | {"action": "add", "server": "acme-tools", "status": "untrusted"} |

F4 (policy network=local_only):

$ continuum status   -> Network policy: local_only
$ continuum providers test openrouter
openrouter: unavailable (Network policy is `local_only`: hosted/remote provider `openrouter` is refused...)  (rc=1)
$ continuum doctor -> [INFO] Network policy: mode=local_only ; Doctor result: PASS (rc=0)
audit log policy_network_block count: 1

Tests

CI-mimic GIT_CONFIG_GLOBAL=/dev/null GIT_CONFIG_SYSTEM=/dev/null python -m unittest discover -s tests: 279 passed (246 + 33 new). New: tests/test_command_risk.py, tests/test_mcp_trust.py, tests/test_governance.py (audit export + network mode).

🤖 Generated with Claude Code

… mode

Productize four self-contained governance/safety features (Strategy
§Phase3 + §Gap5):

- Command risk engine (command_risk.py): deterministic classify() mapping a
  command to a category + risk level + matched signal; conservative rules
  prefer "unknown" over wrong-confident. CLI `continuum command classify`
  (human + --json) exits non-zero on high risk to gate scripts. Policy gains
  approval_required_risk (default "high") and requires_approval() helper.
- MCP trust registry (mcp_trust.py): .continuum/mcp_trust.json with per-server
  status/allow/deny/risk_score/last_changed. CLI `continuum mcp trust
  list|add|set|allow|deny|remove`; each mutation audits mcp_trust_changed.
  is_tool_allowed() precedence deny > allow > status default; unknown servers
  default-untrusted per MCP guidance.
- Audit export (audit_export.py): `continuum audit export [--since][--format
  json|md][--output]` exports the event log; no secret values are stored or
  emitted.
- Network mode: policy gains network on|local_only|off. ProviderManager
  refuses hosted providers under local_only/off (and local under off) with a
  policy_network_block audit event; surfaced in status and doctor.

279 tests pass (246 + 33 new).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@00PrabalK00 00PrabalK00 merged commit 15b9473 into main May 31, 2026
12 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.

1 participant