| name | phpunit-test-adversarial-reviewing |
| version | 4.2.2 |
| description | Internal sub-skill. Do not auto-activate. Use only when explicitly invoked by name by another skill or agent. |
| user-invocable | false |
| allowed-tools | Glob, Grep, Read, mcp__plugin_test-writing_test-rules__get_rules |
PHPUnit Adversarial Test Review
Stress-test reviewer consensus for any test type (unit, integration, or migration): form independent judgment before exposure to findings, then challenge weak consensus, resurrect premature withdrawals, and discover missed violations.
Overview
Work a different cognitive model from the standard reviewer — instead of applying rules group-by-group:
- Read the code with fresh eyes (no rules framework)
- Receive the consensus (first exposure to reviewer reasoning)
- Compare independent impressions against consensus to find gaps
- Gather rule evidence only for substantiated challenges
- Scan for cross-file inconsistencies
Input: Consensus package (required) + optional pre-formed impressions from an earlier wave + optional {rules} (the pre-rendered rule catalog as text, provided in your prompt; when set, Phase 4 selects rules from it instead of calling get_rules).
Output: Structured challenges report per references/output-format.md.
Phase 1: Independent Intuitive Scan
Skip condition: If impressions input is provided (pre-formed in an earlier wave), skip this phase entirely and proceed to Phase 2.
Read each assigned test file and its source class (from #[CoversClass]). Do NOT use MCP rule tools (get_rules) in this phase.
Load references/intuitive-scan-guidance.md for heuristic lenses, then for each file:
- Read the test file completely
- Read the source class under test (from
#[CoversClass])
- Apply each heuristic lens from the guidance
- Record concerns as free-form observations with severity estimate
Output per file:
impressions:
- file_path: tests/unit/Path/To/ClassTest.php
concerns:
- area: "brief description of concern"
severity: high | medium | low
Phase 2: Receive Consensus Package
Parse the consensus package provided as input:
- Validate the package contains
consensus_findings, withdrawn_findings, and reconciliation_record per file
- This is the first exposure to reviewer reasoning — note your initial reactions before proceeding
The consensus package is provided in full in your input — consensus_findings, withdrawn_findings, and the reconciliation record per file.
Phase 3: Structured Comparison
Load references/comparison-strategies.md. For each file, contrast Phase 1 impressions against Phase 2 consensus:
-
Intuition-consensus gaps — Phase 1 concerns that no reviewer raised. These are the highest-value candidates for new findings. For each unmatched concern, note which area of the code it targets.
-
Weak consensus findings — for each consensus finding, apply the "would this survive harder pushback?" test:
- MAJORITY findings with thin reasoning in the reconciliation record
- Findings where the reconciliation record shows quick concession without evidence
- Findings that don't match your Phase 1 impressions at all
-
Premature withdrawals — for each withdrawn finding, check:
- Does the concession reason cite a specific detection algorithm? If not, flag it.
- Did your Phase 1 scan independently flag the same area? If yes, strong resurrection candidate.
- Did only one reviewer push back while others followed? Bandwagon pattern.
-
Assumption excavation — for each consensus finding, state the unstated premise:
- What must be true for this finding to be valid?
- What breaks if that premise is wrong?
Output: prioritized list of candidate challenges, resurrections, and new findings — not yet evidence-backed.
Phase 4: Evidence Gathering
For each candidate from Phase 3 (starting with highest-priority):
- Load applicable rules and detection algorithms: when
{rules} is set, the inline text is the full rule catalog for this file's test type — select the rules relevant to the candidate finding and your lens axis. For unit tests, select those whose Categories include the detected A–E category; integration and migration rules carry Categories: all, so select by rule area, not category. The text holds every rule, so NEVER read, open, search, or locate a rule file by any means (no Read/Grep/Glob, no get_rules); reading the test/source code is unaffected. Otherwise call mcp__plugin_test-writing_test-rules__get_rules(test_type={the file's test type}), adding test_category={category} only for unit tests.
- Apply the detection algorithm against the actual code
Promotion gate: promote a candidate to a formal challenge ONLY if a detection algorithm substantiates it. Drop candidates where the evidence doesn't hold up. This is the filter against contrarianism — intuition proposes, evidence disposes.
Endorsement: consensus findings that Phase 1 intuition independently confirmed AND that have strong detection algorithm support get endorsed. Endorsements are part of the output — they strengthen findings in the final report.
Phase 5: Cross-File Inconsistency Scan
Only applicable when reviewing multiple files. Compare patterns across all assigned files:
-
For each rule_id that appears in any file's consensus, check if the same pattern exists in other files:
- File A's consensus accepted a pattern that file B's consensus flagged -> high-value challenge
- All files share the same weakness but none flagged it -> systemic finding
-
Compare treatment of similar code patterns:
- setUp() strategies across files
- Mocking approaches (createMock vs createStub)
- Assertion styles
- Data provider usage
Cross-file inconsistencies use the same promotion gate as Phase 4 — cite the detection algorithm.
Phase 6: Generate Challenges Report
Load references/output-format.md. Assemble the structured output:
- Group all promoted challenges by file path
- Include all endorsements
- Include cross-file inconsistencies (from Phase 5)
- Set status:
CHALLENGES_RAISED if any challenges, resurrections, new findings, or cross-file inconsistencies
NO_CHALLENGES if only endorsements
FAILED if input validation or processing failed
Output Contract
status: CHALLENGES_RAISED | NO_CHALLENGES | FAILED
files:
- file_path: tests/unit/Path/To/ClassTest.php
challenges_to_consensus:
- rule_id: CONV-004
consensus_was: UNANIMOUS | MAJORITY
challenge: "Detection algorithm requires X but..."
verdict_sought: overturn | weaken
resurrections:
- rule_id: DESIGN-005
originally_reported_by: reviewer-1
resurrection_argument: "The concession was premature because..."
code_evidence: "ClassTest.php:72 — ..."
new_findings:
- rule_id: ISOLATION-002
enforce: must-fix
location: ClassTest.php:88
summary: "Description"
current: |
# code
suggested: |
# fix
detection_algorithm_citation: "ISOLATION-002 specifies..."
endorsements:
- rule_id: UNIT-003
reason: "Strong finding, correctly applied"
cross_file_inconsistencies:
- rule_id: CONV-004
this_file_status: accepted
other_file: tests/unit/Other/ClassTest.php
other_file_status: flagged
inconsistency: "Same pattern, divergent treatment"
reason: null
Troubleshooting
No Impressions Formed in Phase 1
If the test file or source class cannot be read:
- Return FAILED with the file path and error
- Do not proceed to comparison phases without impressions
MCP Tool Unavailability
If mcp__plugin_test-writing_test-rules__get_rules is unavailable:
- Report error: "test-rules MCP server not available — ensure the test-writing plugin is installed and Claude Code was restarted"
- Candidates from Phase 3 cannot be promoted without evidence — return NO_CHALLENGES with a note explaining the limitation
All Candidates Fail Promotion Gate
If Phase 4 drops all candidates (none substantiated by detection algorithms):
- This is a valid outcome — return NO_CHALLENGES
- Include endorsements for strong consensus findings
- The adversary adds value by confirming the consensus is robust