Rectify: Inline Content in Subagent Prompts#4292
Merged
Trecek merged 9 commits intoJul 19, 2026
Merged
Conversation
…placeholders
Add two new parser helpers to _skill_placeholder_parser.py:
- extract_blockquote_sections(content) yields (step_context, block_text)
tuples for contiguous blockquote runs of 3+ lines OR any blockquote
containing a {*_content} placeholder. Single-line stylistic callouts
(e.g., '> **Note:**') are excluded. Tracks the nearest '### Step N'
heading as step_context. Flushes trailing blockquotes at EOF.
- extract_blockquote_placeholders(text) returns the set of {*_content}
variable names found in a blockquote. The *_content naming convention
is the wrong-shape signal — subagent prompts must use *_path with the
subagent reading the file.
These helpers unblock the inline-content-in-subagent-prompt semantic rule
(#3636) which currently has no way to detect dangling {*_content}
variables in blockquoted subagent prompts.
Co-Authored-By: Claude <noreply@anthropic.com>
Add a new @semantic_rule that fires WARNING when a run_skill step's
SKILL.md has a blockquoted subagent prompt containing a banned
{*_content} placeholder. Detection follows the existing
_check_undefined_bash_placeholder resolution pattern: iterate recipe
steps, resolve skill_command to skill_name, read SKILL.md, then scan
for banned placeholders via the new extract_blockquote_sections and
extract_blockquote_placeholders helpers.
Banned placeholders (initial set):
- {annotated_diff_content}
- {diff_content}
- {section_diff_content}
These are wrong-shape: subagent prompts must reference content by PATH
(*_path) and instruct the subagent to Read the file, per the
inline-content-in-subagent-prompt architectural rule (PR #3651).
The existing xfail-strict test
test_inline_content_rule_fires_for_banned_var is un-xfailed; the rule
now exists and the test passes.
Also update recipe/AGENTS.md description of _skill_placeholder_parser.py
to include 'blockquote section extraction' alongside the existing
helpers.
Known side effect (intentional): the rule will fire WARNING on the
existing review-pr, review-research-pr, and audit-claims SKILL.md files
on run_semantic_rules(). Part B will migrate those SKILL.md files and
remove the rule's findings.
Co-Authored-By: Claude <noreply@anthropic.com>
…e numbers
filter_findings() previously crashed with TypeError on findings with
explicit 'line': None (None in valid_set or start <= None <= end), and
silently demoted them to 'filtered' in the validation-absent branch.
Two changes:
1. Early-return branch: partition findings with null/zero line to
unpostable before returning FilterResult. Null-line findings are
NEVER treated as postable, even when no validation data exists.
2. Loop body: change 'line_num = finding.get("line", 0)' to
'line_num = finding.get("line") or 0' and route line_num == 0
directly to unpostable. Avoids the None in valid_set / start <= None
comparison TypeError.
Tests cover:
- null line routes to unpostable (with valid_ranges)
- missing 'line' key routes to unpostable
- line: 0 routes to unpostable
- null line NOT in filtered when validation absent (early-return branch)
- null line against hunk-range branch does not raise TypeError
Co-Authored-By: Claude <noreply@anthropic.com>
…ipe maxima for inline-content rule warnings - tests/arch/test_subpackage_isolation.py: Add REQ-CNST-010-E11 exemption for rules_skill_content.py (1033 lines, just above 1000-line REQ-CNST-010 limit). The kitchen-sink semantic-rules file co-locates all SKILL.md content validators (placeholder, git, write, attribution, inline-content) to keep @semantic_rule registration a single import point. Splitting would fragment the discovery surface and break the test filter cascade. - tests/infra/test_pretty_output_recipe.py: Bump canonical maxima snapshot to reflect new inline-content-in-subagent-prompt rule findings (load_recipe 183585, open_kitchen 183644). New rule emits Severity.WARNING findings for review-pr, review-research-pr, and audit-claims SKILL.md files per plan Part B; the legitimate +826-byte growth is absorbed within RESPONSE_BACKSTOP ceilings (185000/186000).
…4289) Replace {annotated_diff_content} and {diff_content} placeholders in the Step 3 subagent prompts with path-based Read instructions targeting the {annotated_diff_path} and {diff_file_path} arguments. The annotated diff path is forwarded by the recipe from the optional annotate_pr_diff step; when unset or missing, the orchestrating agent falls back to evaluating the diff without [LNNN] anchors (mirroring the existing DISPATCH_AGENTS graceful-degradation fallback in Step 2.9). Also add a NEVER block prohibition against embedding diff content inline in subagent prompts, and update the Step 3 prose to reference the new path-based pattern. Closes the {annotated_diff_content} and {diff_content} dangling-variable findings for the review-pr skill.
…_diff_path (#4289) Replace the dangling {annotated_diff_content} placeholder in the Step 3 subagent prompt with a path-based Read instruction targeting the {annotated_diff_path} argument. When unset or missing, the orchestrating agent falls back to evaluating the diff without [LNNN] anchors. Add annotated_diff_path to the Arguments section (the recipe already forwards the variable from the optional annotate_pr_diff step in research-review.yaml, but the skill docs omitted it). Add a NEVER block prohibition against embedding diff content inline in subagent prompts. Closes the {annotated_diff_content} dangling-variable finding for the review-research-pr skill.
#4289) Phase 1 (claim extraction): insert a new instruction before the "Launch one subagent" line teaching the orchestrating agent to write each section's diff chunk to its own file at {{AUTOSKILLIT_TEMP}}/audit-claims/section_diff_{section_slug}_{pr_number}.txt and bind {section_diff_path} to that file path when building each subagent's prompt. Replace the dangling {section_diff_content} placeholder with a Read instruction. Phase 2 (evidence matching): replace {claims_json} with a Read from {claims_json_path} and replace {diff_content} with a Read from {diff_file_path} (both resolve to concrete paths already documented in this skill). Replace the dangling {evidence_rules_for_type} with inline referral to the static per-claim-type rules already enumerated in the skill above the template. Update the Temp File Layout section to enumerate the new section_diff intermediate files. Add a NEVER block prohibition against embedding diff content inline in subagent prompts. Closes the {section_diff_content}, {claims_json}, {diff_content}, and {evidence_rules_for_type} dangling-variable findings for the audit-claims skill.
… migration (#4289) Remove the six xfail(strict=True) markers and the three skipif(extract_blockquote_sections is None) guards that were bridging the Part A prerequisite gap. Convert the try/except ImportError fallback for extract_blockquote_sections to a direct import — the function now exists at the expected path. These contracts assert that the review-pr, review-research-pr, and audit-claims SKILL.md blockquote subagent prompts use *_path variables (instructing subagents to Read the content from disk) rather than inline *_content variables, and that each skill's NEVER block contains an explicit prohibition against inline diff embedding. The three SKILL.md migrations in this PR satisfy both predicates, so the xfail/bridge markers are no longer needed. Closes the contract-test gating for the Part B SKILL.md migrations.
Trecek
deleted the
review-pr-subagent-prompts-omit-annotated-diff-findings-retu/4289
branch
July 19, 2026 02:11
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
review-pr,review-research-pr, andaudit-claimsSKILL.md files contain dangling template variables ({annotated_diff_content},{diff_content},{section_diff_content}) in blockquoted subagent prompts that are never populated. The existing_skill_placeholder_parser.pyonly validates{placeholder}tokens inside bash fenced blocks — blockquote/prose regions where subagent prompts live are structurally invisible to validation. Theinline-content-in-subagent-promptsemantic rule was named and xfail-tested (#3636) but never implemented.This PR implements the parser extension, the semantic rule, and
filter_findings()null-safety (Part A), then migrates the three affected SKILL.md files to the architecturally correct*_pathpattern, updates NEVER blocks to prohibit inline diff embedding, and un-xfails the remaining contract tests (Part B). After these changes, subagent prompts reference diff content by file path and instruct subagents to Read, in line with the architectural rule from PR #3651.Individual Group Plans
Part A: Parser extension, semantic rule, and null-safety
Implements
extract_blockquote_sections()andextract_blockquote_placeholders()in_skill_placeholder_parser.py, adds theinline-content-in-subagent-promptsemantic rule inrules_skill_content.py, hardensfilter_findings()against null/zero/missinglinevalues (which currently crash withTypeErroronNone in valid_setandstart <= None <= endcomparisons), and un-xfails the gated semantic rule test.Part B: SKILL.md migration, NEVER blocks, and contract un-xfail
Migrates
review-pr,review-research-pr, andaudit-claimsSKILL.md files from dangling*_contentvariables to the*_pathpattern (subagent reads content from disk). Adds an explicit NEVER-block prohibition against inline diff embedding in all three skills. Adds the newsection_diff_pathfile-writing step inaudit-claimsPhase 1 and declaresannotated_diff_pathin thereview-research-prArguments section. Removes thetry/except ImportErrorfallback forextract_blockquote_sectionsand theskipifguards that Part A makes obsolete, un-xfailing the six contract tests gating on SKILL.md content.Closes #4289
Implementation Plan
Plan files:
/home/talon/projects/autoskillit-runs/remediation-20260718-171316-238004/.autoskillit/temp/rectify/rectify_inline_content_subagent_prompt_2026-07-18_172142_part_a.md/home/talon/projects/autoskillit-runs/remediation-20260718-171316-238004/.autoskillit/temp/rectify/rectify_inline_content_subagent_prompt_2026-07-18_172142_part_b.md🤖 Generated with Claude Code via AutoSkillit