PHPUnit Adversarial Test Review
Stress-test reviewer consensus: 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, andreconciliation_recordper 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, select from the inline text every rule whoseCategoriesinclude the detected category — the text holds every rule, so NEVER read, open, search, or locate a rule file by any means (noRead/Grep/Glob, noget_rules); reading the test/source code is unaffected. Otherwise callmcp__plugin_test-writing_test-rules__get_rules(test_type=unit, test_category={category}). - 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_RAISEDif any challenges, resurrections, new findings, or cross-file inconsistenciesNO_CHALLENGESif only endorsementsFAILEDif 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 # explanation if FAILED
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
Source: shopwareLabs/ai-coding-tools — distributed by TomeVault.