fix(subagent)!: reject unknown keys in nested tools/permissions frontmatter#6626
Merged
Merged
Conversation
bug-ops
enabled auto-merge (squash)
July 21, 2026 00:14
…matter RawToolPolicy and RawPermissions did not propagate RawSubAgentDef's deny_unknown_fields into their own nested structs, so a typo inside a sub-agent's tools: or permissions: section (e.g. pemission_mode:, alow:) was silently ignored and fell back to the section's fail-safe default instead of failing to load. Also adds a regression test that drives the real handle_scheduler_spawn_action wiring end-to-end (previously only the decomposed intersect_allowlists helper was tested directly), confirming the parent-permission floor and per-task allowlist are composed by true intersection. BREAKING CHANGE: a sub-agent frontmatter file with a misspelled key in its tools: or permissions: section now fails to load instead of silently falling back to defaults for that section. Closes #6583 Closes #6539
bug-ops
force-pushed
the
feat/issue-6583/subagent-deny-unknown-fields
branch
from
July 21, 2026 00:32
115b283 to
cd6b5e8
Compare
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
RawToolPolicyandRawPermissions(thetools:/permissions:nested sections of sub-agent frontmatter) did not propagateRawSubAgentDef's#[serde(deny_unknown_fields)]into their own structs, so a typo inside either section (e.g.pemission_mode:,alow:) was silently ignored and fell back to the section's fail-safe default instead of failing to load. Both structs now carrydeny_unknown_fieldsdirectly.handle_scheduler_spawn_action/intersect_task_tool_allowlistwiring end-to-end throughrun_scheduler_loop, asserting the tool definitions delivered to a spawned sub-agent's LLM are the true intersection of the parent-permission floor and the per-task planner-emitted allowlist. The existing composition test only exercised the decomposedzeph_subagent::intersect_allowlists/task_tool_allowlist_for_taskhelpers in isolation, never the actual call site.Breaking change
A sub-agent frontmatter file with a misspelled key inside its
tools:orpermissions:section now fails to load instead of silently falling back to defaults for that section. Not an exploitable privilege escalation (every existing default is already conservative/restrictive) — this closes a silent-misconfiguration trap where an operator's intended tool/permission restriction never took effect.Closes #6583
Closes #6539
Test plan
cargo +nightly fmt --checkcargo clippy --profile ci --workspace --all-targets --features "desktop,ide,server,chat,pdf,scheduler,testing" -- -D warningscargo nextest run --config-file .github/nextest.toml --workspace --features "desktop,ide,server,chat,pdf,scheduler" --lib --bins(2736/2736 in touched crates, full workspace clean)RUSTFLAGS="-D warnings" RUSTDOCFLAGS="--deny rustdoc::broken_intra_doc_links" cargo doc --no-deps --workspace --features "desktop,ide,server,chat,pdf,scheduler"gitleaks protect --staged --no-banner --redact#6583tests independently verified as genuine regression guards (temporarily removeddeny_unknown_fields, confirmed both new tests fail, restored)#6539test independently verified as a genuine regression guard (temporarily revertedintersect_allowliststo a naive overwrite, confirmed the test fails with the expected leaked-tool mismatch, restored)[Unreleased]/Fixedwith breaking-change note