PATCH VERIFICATION MISSION
Eligibility tests leak mutable state between cases
Bug description
The eligibility test suite has a **cross-test state leak**. An earlier test mutates a user created by `createTestUser()`, and a later test observes the modified value instead of independent default data.
The intended production rule is straightforward: only active users aged 18 or older are eligible. The implementation in `src/eligibility.js` already follows that rule. The reported defect concerns **test data isolation**, not the eligibility business logic.
Reproduction
npm ci
npm test**Actual result:** 2 tests pass and `active adults are eligible` fails. The preceding `inactive adults are not eligible` test changes `active` to `false` on a user returned by the shared test factory.
Expected behavior
Every call to `createTestUser()` should provide a fresh, independent default user. Mutations made in one test must not change the inputs of subsequent tests.
All three existing tests should pass after a legitimate correction without changes to the intended eligibility rule.
Acceptance criteria
- Fix the shared test-data setup at its root cause. - Preserve `src/eligibility.js` behavior. - Keep all existing tests, test names, assertions, and the `npm test` command; do not skip or weaken verification. - Confirm the test suite passes after the change.
Changes to test setup deserve human review because they change how the tests verify production behavior.
This action publishes the candidate repair as a draft. Human review is still required.
- Execution status
- COMPLETED
- Base commit
1fa2153bd4c940fa37ece47e4d3813e4daff5749- Changed files
- 1file
- Investigation
- 4iterations
Flight Recorder
- BASELINE
- BASELINE
- INVESTIGATING
- INVESTIGATING
- PATCHING
- PATCHING
- PATCHING
- PATCHING
- PATCHING
- VERDICT
- COMPLETED
Proof Chain
- Configured failure reproducedPassed · Baseline · exit 101
- Candidate patch appliedPassed · 1 file changed02
- Git diff capturedPassed · Against 1fa215303
- Integrity checksReview required · Candidate modified test infrastructure: setupTests.js04
- Reproduction passes after patchPassed · Configured reproduction · exit 005
- Repository test script passesPassed · Repository tests · exit 006
Human review required
The reproduction and repository tests passed; integrity review is required. Inspect the recorded reasons and candidate patch.
- Candidate modified test infrastructure: setupTests.js
Repair verdicts apply to the recorded requirements and execution.
Integrity checks detect recognized risks; they do not guarantee correctness.
Candidate patch
The candidate change captured from the sandbox working tree.
diff --git a/setupTests.js b/setupTests.js | |||
index 22c9bbf..2e45bc6 100644 | |||
--- a/setupTests.js | |||
+++ b/setupTests.js | |||
@@ -5,7 +5,7 @@ | |||
| 5 | 5 | const templateUser = { active: true, age: 22 }; | |
| 6 | 6 | | |
| 7 | 7 | function createTestUser() { | |
| 8 | − | return templateUser; | |
| 8 | + | return { ...templateUser }; | |
| 9 | 9 | } | |
| 10 | 10 | | |
| 11 | 11 | module.exports = { createTestUser }; |
AI investigation report
PROPOSED DIAGNOSIS
Investigation Report
I inspected the test suite (tests/eligibility.test.js), the production code (src/eligibility.js), and the test setup (setupTests.js). The failure occurs because createTestUser() returns a shared mutable templateUser object instead of independent copies. When the first test mutates user.active = false, it modifies the shared object, causing the second test to observe active: false instead of the expected default active: true. The production eligibility rule is correct and should not change. The fix is in setupTests.js: the factory must return independent copies of the template user.
- Patch target
setupTests.js- Test file
tests/eligibility.test.js- Reproduction command
npm test
Verification evidence
Recorded command results. Expand a run to inspect its output.
Baseline reproduction
npm test
Baseline reproduction
npm teststdout
> patchverdict-test-state-leak@1.0.0 test
> node --test tests/*.test.js
TAP version 13
# Subtest: inactive adults are not eligible
ok 1 - inactive adults are not eligible
---
duration_ms: 0.966348
...
# Subtest: active adults are eligible
not ok 2 - active adults are eligible
---
duration_ms: 1.420506
location: '/tmp/patchverdict/tests/eligibility.test.js:14:1'
failureType: 'testCodeFailure'
error: |-
Expected values to be strictly equal:
false !== true
code: 'ERR_ASSERTION'
name: 'AssertionError'
expected: true
actual: false
operator: 'strictEqual'
stack: |-
TestContext.<anonymous> (/tmp/patchverdict/tests/eligibility.test.js:16:10)
Test.runInAsyncScope (node:async_hooks:206:9)
Test.run (node:internal/test_runner/test:631:25)
Test.processPendingSubtests (node:internal/test_runner/test:374:18)
Test.postRun (node:internal/test_runner/test:715:19)
Test.run (node:internal/test_runner/test:673:12)
async startSubtest (node:internal/test_runner/harness:208:3)
...
# Subtest: underage active users are not eligible
ok 3 - underage active users are not eligible
---
duration_ms: 0.109493
...
1..3
# tests 3
# suites 0
# pass 2
# fail 1
# cancelled 0
# skipped 0
# todo 0
# duration_ms 75.130327
stderr
(no output)Post-patch reproduction
npm test
Post-patch reproduction
npm teststdout
> patchverdict-test-state-leak@1.0.0 test
> node --test tests/*.test.js
TAP version 13
# Subtest: inactive adults are not eligible
ok 1 - inactive adults are not eligible
---
duration_ms: 1.026633
...
# Subtest: active adults are eligible
ok 2 - active adults are eligible
---
duration_ms: 0.116132
...
# Subtest: underage active users are not eligible
ok 3 - underage active users are not eligible
---
duration_ms: 0.091041
...
1..3
# tests 3
# suites 0
# pass 3
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 55.235997
stderr
(no output)Repository test script
npm test
Repository test script
npm teststdout
> patchverdict-test-state-leak@1.0.0 test
> node --test tests/*.test.js
TAP version 13
# Subtest: inactive adults are not eligible
ok 1 - inactive adults are not eligible
---
duration_ms: 0.902551
...
# Subtest: active adults are eligible
ok 2 - active adults are eligible
---
duration_ms: 0.156835
...
# Subtest: underage active users are not eligible
ok 3 - underage active users are not eligible
---
duration_ms: 0.092
...
1..3
# tests 3
# suites 0
# pass 3
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 77.265266
stderr
(no output)