Rectify: Run-Cmd Path Capture Non-Empty Content Guard — PART A ONLY#3342
Merged
Trecek merged 8 commits intoMay 30, 2026
Merged
Conversation
…ation (Part A Phase 1) - 1a: test_extract_path_type_rejects_zero_byte_file — fails until _validate_capture_value checks st_size - 1b: test_extract_path_type_accepts_nonempty_file — regression guard for non-empty path acceptance - 1c: test_remediation_bridge_investigation_capture_is_path_typed — fails until capture uses type: path - 1d: test_remediation_bridge_investigation_cmd_has_nonempty_guard — fails until test -s added to cmd - 1e: test_recipe_step_shorthand_capture_parses_to_capture_entry_spec — fails until RecipeStep.capture unified to CaptureEntrySpec Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… (Part A Phase 2) - 2a: RecipeStep.capture/capture_list typed as dict[str, CaptureEntrySpec] (was dict[str, str]) - 2b: _parse_step loader calls _parse_capture_spec() for both capture and capture_list fields - 2c: 16 source sites updated to access .from_ on CaptureEntrySpec (rules_cmd, rules_dataflow, validator, rules_graph_output, rules_graph_review, rules_graph_routes, rules_verdict, rules_dataflow_handoff, rules_clone, _analysis_bfs, _analysis_detectors, rules_merge_context) - 2d: 9 test files updated to use .from_ accessor for capture value comparisons - 2f: _validate_capture_value raises CaptureValueTypeError for 0-byte path files (st_size == 0) - 2g: bridge_investigation capture upgraded to long-form type: path - 2h: bridge_investigation cmd adds test -s guard to fail on empty awk output - 2i: remediation.json recompiled, contract cards regenerated Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…_init__
Tests constructing RecipeStep with capture={"key": "string"} broke after
the type changed to dict[str, CaptureEntrySpec]. Add _coerce_capture_dict
in __post_init__ to auto-wrap raw strings. Also fix test assertions that
used 'in' operator on CaptureEntrySpec objects or compared against raw dicts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…(Part B) Adds defense layer 3: a new @semantic_rule that statically flags run_cmd steps echoing path-typed captures without a test -s or [ -s non-empty file guard in the cmd. Catches the 0-byte file pattern at recipe validation time during development. Includes 4 tests covering: missing guard → WARNING, test -s guard passes, string-typed capture not flagged, [ -s bracket guard passes.
- Return fresh empty dict instead of raw untyped input on falsy path - Add isinstance guard for CaptureEntrySpec in else branch - Raise TypeError for unexpected value types instead of silent pass-through Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The semantic rule now inspects both step.capture and step.capture_list for path-typed entries, preventing silent bypass when path captures are declared in capture_list. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace separate exists() + stat() syscalls with a single stat() call inside try/except. This atomically checks both existence and size, preventing unhandled FileNotFoundError when a file disappears between the two calls. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace weakened .from_-only assertions with full CaptureEntrySpec equality checks that also verify value_type defaults to 'string', matching the established pattern in test_io_parsing.py. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
44c2d1b to
3f30760
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
The
bridge_investigationstep inremediation.yamlemits success with a 0-byte file because awk exits 0 regardless of output, the>redirect always creates the file, and neither the recipe engine nor the semantic rule layer validates thatrun_cmdsteps producing file-path captures point to non-empty files.Part A delivers the infrastructure prerequisite and the direct fix: unifying
RecipeStep.capturewithCampaignDispatch.captureso both use typedCaptureEntrySpecobjects (enablingvalue_type="path"), strengthening_validate_capture_valueto reject 0-byte files, upgradingbridge_investigation's capture totype: path, and adding atest -sbash guard. Part B will cover the new semantic rulerun-cmd-path-capture-requires-nonempty-guard— implement as a separate task.Closes #3324
Implementation Plan
Plan file:
/home/talon/projects/autoskillit-runs/remediation-20260530-130305-956155/.autoskillit/temp/rectify/rectify_run_cmd_path_capture_guard_2026-05-30_130305_part_a.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