feat(rules): add side-effect bounds rules for OpenAI, Pydantic AI, MCP, LangChain (batch 1) - #231
Merged
Merged
Conversation
…P, LangChain (batch 1)
ivanpaghubasan
requested review from
ericksondelacruz,
jhumel-code and
sairenchristianbuerano
September 28, 2026 07:10
sairenchristianbuerano
approved these changes
Sep 28, 2026
ericksondelacruz
approved these changes
Sep 28, 2026
Resolves conflicts in CLAUDE.md and COVERAGE.md by combining Batch 1 side-effect-bounds work with main's agent-observability rules. Recounted rule total: 298 (293 on main + 5 from Batch 1).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a new rule family that flags tools letting the model choose the recipient or amount of a side effect (email, notify, refund, charge, payout) with no visible bound. This is batch 1 of 2, covering four SDKs and five rules:
Batch 2 (CrewAI, Google ADK, AutoGen, Vercel AI, Claude SDK TypeScript) will follow in a separate PR set once this one is reviewed.
Background
This comes from rank 12 of a competitive-analysis rule backlog (P0). The source framed it as a fix for the "3,400 duplicate notifications" failure mode and suggested critical severity. Verification against the current catalog showed those premises don't hold, so the rule was redesigned rather than implemented as written:
charge_customer(customer_id)with the amount set server-side stays silent.What changed
side_effect_bounds.yamltopic file in each of the four SDK packs undertestdata/rules-fixture/. A separate topic file was chosen over extendingidempotency.yamlbecause the concern is different (who receives the effect, or how much it moves, rather than duplicate execution).internal/rules/policies_test.gofor each rule, including a gate set toFalsestill firing.ARCHITECTURE.md,COVERAGE.md, and the rule count inCLAUDE.md.Design notes
le=,Field(le=…),.max(…),Literal[…]), a named cap, or an allow-list.needs_approval,requires_approval,interrupt(,elicit(). A gate explicitly set toFalsedoes not silence it.Known limitations
@tool("name", "desc", {"to": str})form records the parameter asargs, so parameter-name rules can't seetooramount. This is a discovery gap in the engine and is tracked separately.Verification
go build ./...andgo test ./...pass.RULES_REPO=../trustabl-rules scripts/check-rules-sync.shreports the fixture in sync with production (113 files compared).Related PRs
Merge order is engine, then rules, then rulebook. The paired PRs use the same branch name,
feat/p0-side-effect-bounds-batch1:Follow-ups (not in this PR)
@toolschema-dict keys intoParamNames. The same gap makes CSDK-006 fire on every mutating-named Claude tool, even when an idempotency key is present in the schema.notify_is not among the idempotency rule prefixes, so duplicatenotify_*sends are not covered there.