Shipped via PRs #810-#819 (v0.21 rule-candidates sprint: 9 new rules, 3 new validators, rule-bookkeeping automation, safe auto-fixes for Kiro toolSearch).
Changed
- Auto-fix for KR-SET-001/002/003 type coercion. The three Kiro settings rules now ship safe auto-fixes for the common case of "user wrote a string when the docs say bool/number". KR-SET-001 strips quotes + normalizes case on
"true"/"False"/"TRUE"→true/false; KR-SET-002/003 strip quotes on numeric strings (KR-SET-003 only accepts integer strings since minTokens must be whole). Fixes are markedsafe: true- Kiro rejects quoted booleans/numbers anyway, so unquoting preserves user intent exactly. Other paths (negative values, fractional tokens, non-bool-ambiguous strings like "yes") stay manual. Audit of all 9 rules from the sprint found only these 3 to be mechanically fixable - the others require user-specific values (API tokens, server names, URL templates) that can't be guessed. 19 new unit tests covering autofix paths +find_value_spanJSON-value-slicing helper. - Rule bookkeeping: extend automation to VALIDATION-RULES.md footer stats.
scripts/sync-rule-bookkeeping.jsnow also syncs the three derived lines at the end ofknowledge-base/VALIDATION-RULES.md: Total Coverage (N rules across M categories), Certainty (HIGH/MEDIUM/LOW counts), and Auto-Fixable (count + percentage). Previously these drifted whenever a rule was added or a rule'sautofixflag flipped - now they're derived from the rules.json source of truth on every sync run. - Rule bookkeeping automation (#129). Adding a rule previously meant hand-updating eight or so derived locations -
total_rulesandlast_updatedinknowledge-base/rules.json, thecrates/agnix-rules/rules.jsonmirror, the "N rules" / "N validators" phrases in CLAUDE.md/AGENTS.md/README.md, and the website docs regen. Newscripts/sync-rule-bookkeeping.jshandles them all from the single source of truth: run it after editingrules.json(optionally with--validators=Nif a new validator was registered) and it syncs every derived file. CI now runsnode scripts/sync-rule-bookkeeping.js --check --skip-docsin thetestjob so drift fails the build.
Added
- GM-AG-001: Validate
authblock in Gemini CLI agent MCP config (#809). Gemini CLI v0.39.0 added anauthblock tomcp_servers.*entries in local agent markdown frontmatter (.gemini/agents/*.md) - see google-gemini/gemini-cli#24770. Two variants:type: "google-credentials"(onlyscopesallowed) andtype: "oauth"(client_id,client_secret,scopes,authorization_url,token_url). GM-AG-001 enforces the discriminator, rejects unknown fields per variant, type-checks string/array values, and validates URL shape. IntroducesFileType::GeminiAgentfor.gemini/agents/*.mddetection + a newGeminiAgentValidatorwith its own frontmatter extraction + auth-block line scanner. 24 unit tests + valid/invalid fixtures. Newgemini-agentsrule category. Closes #809. - KR-SET-001 + KR-SET-002 + KR-SET-003: Validate Kiro Tool Search settings (#808). Kiro CLI 2.1 added the Tool Search feature configured via flat-key JSON in
.kiro/settings.json(or~/.kiro/settings.json):toolSearch.enabled(boolean master toggle, default false),toolSearch.minPct(number, default 5), andtoolSearch.minTokens(integer, default 50000). Docs at kiro.dev/docs/cli/mcp/tool-search/. Introduces a newFileType::KiroSettingsvariant + detection for files namedsettings.jsonwith a.kiroparent directory, a newKiroSettingsValidator, and three rules: KR-SET-001 (HIGH, non-booleantoolSearch.enabled), KR-SET-002 (MEDIUM, type/negative/>100 ontoolSearch.minPct), KR-SET-003 (MEDIUM, type/negative/fractional ontoolSearch.minTokens). 23 unit tests + valid/invalid fixtures. Newkiro-settingsrule category. Closes #808. - CC-HK-026 + CC-HK-027: Validate required fields on
type: "mcp_tool"hooks (#804). Claude Code v2.1.118 added themcp_toolhook action type; the docs at code.claude.com/docs/en/hooks#mcp-tool-hook-fields specifyserver(required string, names an already-connected MCP server) andtool(required string, names the tool to invoke), plus optionalinput(object for tool arguments with${path}substitution). CC-HK-026 flags missing/empty/non-stringserver; CC-HK-027 flags the same fortool. Both are HIGH severity (hook will fail at runtime), independently disableable. Also updated the typedHook::McpToolschema inschemas/hooks.rswith the correct shape (was a stub with wrong fields). 8 new tests + valid/invalid fixtures. Closes #804. - CC-SET-001: Validate
prUrlTemplatein.claude/settings.json(#803). Claude Code v2.1.119 addedprUrlTemplateas a top-level settings key that points the footer PR badge at a custom code-review URL instead of github.com. CC-SET-001 flags three misconfigurations: (a) non-string values (ERROR), (b) empty strings (ERROR, badge would never render), (c) strings with none of the documented placeholders{host},{owner},{repo},{number},{url}(WARNING, every PR would resolve to the same static URL). Ships with a newClaudeSettingsValidatorscoped to.claude/settings.json,.claude/settings.local.json, and.claude/managed-settings.jsonso sibling tools (.amp/settings.json, etc.) that share the Hooks FileType aren't false-positived. 19 unit tests + valid/invalid fixtures. Introduces a newclaude-settingsrule category to distinguish top-level settings rules from hooks, memory, skills, etc. Closes #803. - CDX-CFG-029: agents.max_threads incompatible with multi_agent_v2 (#806). In rust-v0.125.0 Codex rejects the config at load time with "agents.max_threads cannot be set when multi_agent_v2 is enabled" - the v2 agent lifecycle manages threading internally and accepting the legacy limit alongside creates conflicting semantics (openai/codex#19129). CDX-CFG-029 detects the feature in either shape Codex accepts (flat
[features] multi_agent_v2 = trueor table[features.multi_agent_v2] enabled = true) and errors when[agents] max_threadsis also set. Closes #806. - CDX-CFG-028: Reject unsupported inline MCP
bearer_tokenfield (#805). In rust-v0.125.0 Codex runtime rejectsmcp_servers.<name>.bearer_tokenand requiresbearer_token_env_varinstead; schemars generation also dropped the field (openai/codex#19294). agnix now emits a HIGH-severity diagnostic pointing users at the correct replacement, with a specific suggestion that keeps secrets out of the config file. Removedbearer_tokenfromKNOWN_MCP_SERVER_KEYSand suppressed it from the generic CDX-CFG-006 (nested unknown-key) path when CDX-CFG-028 is enabled, so users get one specific diagnostic rather than two. Disabling CDX-CFG-028 intentionally falls through to CDX-CFG-006 so the field is never silently accepted. Closes #805.
Changed
- MCP validator now accepts flat top-level server-map shape (#807). Codex rust-v0.123.0 made plugin MCP loading accept both
{ "mcpServers": {...} }(the MCP spec / Claude Code / Cursor shape) and a flat{ "serverName": {...}, ... }top-level map. Previously agnix'sextract_mcp_serverssilently returned empty whenmcpServerswas absent, so per-server rules (MCP-009..012, MCP-024) didn't fire on flat-form files. Now the extractor falls back to reading the root object as a server map when every top-level value looks like a server config (hascommandorurl). Guardrails: whenmcpServersis present it still wins (flat shape is fallback-only), and generic JSON-RPC payloads + partial typos are rejected conservatively so the heuristic doesn't misread non-server JSON as servers. 8 new unit tests cover both shapes plus the rejection guardrails. Closes #807. - Tool-release watcher triage (2026-04-25): full changelog review of 8 tracked tools against their validators. Bumped baselines in
.github/tool-release-baselines.jsonandLast Reviewedinknowledge-base/RESEARCH-TRACKING.mdfor Claude Code (v2.1.117 → v2.1.119), Codex CLI (rust-v0.122.0 → rust-v0.125.0), OpenCode (v1.14.20 → v1.14.25), Kiro CLI (2.0.1 → 2.1.1), Cline (v3.80.0 → v3.81.0), Cursor (3.1.17 → 3.2.11), Roo Code (v3.52.1 → v3.53.0), Gemini CLI (v0.38.2 → v0.39.1). No validator code changes — rule candidates surfaced (Claude CodeprUrlTemplate,type:"mcp_tool"hook action; Codex.mcp.jsondual-shape,agents.max_threads+multi_agent_v2conflict,bearer_tokenrejection; KirotoolSearch.enabled; Gemini agent MCPauthblock) are filed as separate follow-up issues so each gets a proper design pass against upstream docs. Closes #778, #779, #780, #781, #782, #795, #796, #797.