Trustabl rules v0.4.0
208 rules across 10 SDK categories (autogen, claude_sdk, claude_skill, crewai, google_adk, langchain, mcp, openai_sdk, pydantic_ai, vercel_ai) schema_version 15
Requires engine v0.1.X or newer — schema_version 15 adds predicates (repo_claude_options_permission_mode_is, repo_claude_options_disallowed_tools_missing, agent_uses_hosted_tool_class, agent_hosted_tool_kwarg_present, agent_run_call_max_turns_missing, agent_run_call_usage_limits_missing) that older engines cannot parse. Engines that predate schema_version 15 support will load the pack leniently but skip the 4 new rules in this release.
Consumed live by the engine via the signed production / staging channels (default: production — NOT this tag; promote separately via publish.yml). Pin this exact ruleset with: trustabl scan --rules-source git --rules-ref v0.4.0
Pre-1.0: breaking rule/schema changes may occur between 0.x releases.
New rules (4)
CSDK-205 · claude_sdk · repo scope · medium
Claude Agent SDK session auto-approves edits with no tool deny-list. Fires when a ClaudeAgentOptions sets permission_mode: "acceptEdits" and no construction in the project sets disallowed_tools. Without a deny-list, an auto-edit session has no static boundary on shell, network, or credential tools.
ADK-111 · google_adk · agent scope · high
Agent wires an MCPToolset with no tool_filter. Fires when an LlmAgent connects an MCPToolset without tool_filter=, giving the agent unrestricted access to whatever the remote MCP server currently exposes — a surface outside the codebase's control that can grow or change without any code change.
OAI-112 · openai_sdk · agent scope · low
OpenAI Agents SDK agent has no explicit max_turns limit. Fires when no Runner.run / run_sync / run_streamed call that executes this agent sets max_turns, leaving the loop bounded only by the SDK's implicit DEFAULT_MAX_TURNS, which can shift between SDK versions.
PYD-106 · pydantic_ai · agent scope · low
Pydantic AI agent has no explicit usage_limits set. Fires when no run / run_sync / run_stream call sets usage_limits, leaving token and cost spend unbounded — a bare UsageLimits() caps request count but not tokens.