Implementation Plan: T5-P5-A3-WP1 Server-Side Recipe-Read Prohibition & Write-Target Boundary#4105
Merged
Trecek merged 5 commits intoJun 13, 2026
Conversation
…ry guards Add defense-in-depth guards to server/_guards.py that replicate the recipe-read prohibition currently enforced only by the recipe_read_guard PreToolUse hook, and add write-target boundary checking for run_cmd. This makes both prohibitions HARD-enforced inside the MCP tool layer, backend-agnostic (works for Claude Code, Codex, and any future backend), and independent of hook scripts. - _check_recipe_read_prohibition(): denies reads of recipe/skill/agent files (cmd path) and autoskillit.recipe.* callables (callable path) in headless sessions - _check_write_target_boundary(): denies run_cmd writes outside the configured allowed write prefixes (fail-open when unset) - _derive_run_cmd_write_prefixes(): resolves the env-var precedence (PREFIXES plural takes precedence over PREFIX singular) - Wire guards into run_cmd and run_python after _require_enabled() - Parity test for RECIPE_READ_DENY_TRIGGER in tests/hooks/test_hook_sync.py - New invariant test suites for run_cmd and run_python - Smoke importability tests in tests/server/test_guards_module.py Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Inline _derive_run_cmd_write_prefixes() into guard call to satisfy _has_toplevel_except_exception arch check (assignment before try block violated the structural contract) - Add AUTOSKILLIT_SESSION_TYPE=orchestrator to _headless fixtures so _require_orchestrator_or_higher passes before reaching new guards - Bump tools_execution.py line limit exemption from 1130→1150 - Add 'server' to bash_write_targets cascade map (_guards.py now imports extract_bash_write_targets from core) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ards.py _RECIPE_READ_CALLABLE_PATTERN has a `^` prefix anchor, so .match() is the idiomatic method (implicitly anchors at start); using .search() with `^` is semantically equivalent but misleading. Remove the now-redundant `^` from the pattern definition and switch the call site to .match(). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When AUTOSKILLIT_ALLOWED_WRITE_PREFIXES is unset, _check_write_target_boundary silently returns None. Add a logger.debug() call so silent misconfiguration is diagnosable in production logs without changing guard behavior. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rs scope The debug log must emit within the bound_contextvars(tool="run_cmd") block so it carries the run_cmd context. Calling logger.debug() in _guards.py fires before that scope is entered, breaking the observability contract tested by test_run_cmd_binds_tool_contextvar_and_calls_ctx_info. Move the log to tools_execution.py inside the try/bound_contextvars block, calling _derive_run_cmd_write_prefixes() once more to check (acceptable overhead for a debug log path). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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
Add server-side defense-in-depth guards to
_guards.pythat replicate the recipe-read prohibition currently enforced only by therecipe_read_guard.pyPreToolUse hook, and add write-target boundary checking forrun_cmd. This makes both prohibitions HARD-enforced inside the MCP tool layer, backend-agnostic (works for Claude Code, Codex, and any future backend), and independent of hook scripts.Closes #4034
Implementation Plan
Plan file:
/home/talon/projects/autoskillit-runs/impl-20260613-020615-380722/.autoskillit/temp/make-plan/t5-p5-a3-wp1-server-side-recipe-read-guard_plan_2026-06-13_021500.md🤖 Generated with Claude Code via AutoSkillit
Token Usage Summary
* Step used a non-Anthropic provider; caching behavior may differ.
Token Efficiency
Model Usage Breakdown