Skip to content

Rectify: Inline Content in Subagent Prompts#4292

Merged
Trecek merged 9 commits into
developfrom
review-pr-subagent-prompts-omit-annotated-diff-findings-retu/4289
Jul 19, 2026
Merged

Rectify: Inline Content in Subagent Prompts#4292
Trecek merged 9 commits into
developfrom
review-pr-subagent-prompts-omit-annotated-diff-findings-retu/4289

Conversation

@Trecek

@Trecek Trecek commented Jul 19, 2026

Copy link
Copy Markdown
Collaborator

Summary

The review-pr, review-research-pr, and audit-claims SKILL.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.py only validates {placeholder} tokens inside bash fenced blocks — blockquote/prose regions where subagent prompts live are structurally invisible to validation. The inline-content-in-subagent-prompt semantic 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 *_path pattern, 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() and extract_blockquote_placeholders() in _skill_placeholder_parser.py, adds the inline-content-in-subagent-prompt semantic rule in rules_skill_content.py, hardens filter_findings() against null/zero/missing line values (which currently crash with TypeError on None in valid_set and start <= None <= end comparisons), 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, and audit-claims SKILL.md files from dangling *_content variables to the *_path pattern (subagent reads content from disk). Adds an explicit NEVER-block prohibition against inline diff embedding in all three skills. Adds the new section_diff_path file-writing step in audit-claims Phase 1 and declares annotated_diff_path in the review-research-pr Arguments section. Removes the try/except ImportError fallback for extract_blockquote_sections and the skipif guards 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

Trecek and others added 9 commits July 18, 2026 17:50
…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
Trecek added this pull request to the merge queue Jul 19, 2026
Merged via the queue into develop with commit 0c4b2be Jul 19, 2026
3 checks passed
@Trecek
Trecek deleted the review-pr-subagent-prompts-omit-annotated-diff-findings-retu/4289 branch July 19, 2026 02:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant