Define the local evaluation task
A synthetic staff grading audit presents the same candidate/case pairs in two rounds with reversed presentation order. Pair results by stable candidate ID, not position, and compare Boolean labels. Both rounds must have one result for each same ID. Changed labels are unstable review observations; this checker does not infer psychological causation.
- Match the same candidate IDs across rounds
- Ignore presentation positions for matching
- List changed labels for staff review
Unmatched or duplicated candidates invalidate the paired audit.
Use the filled cases
| Case | Supplied input | Expected structured output | Decision and reason |
|---|---|---|---|
| One grade changes | {"first":[{"id":"A","pass":true},{"id":"B","pass":false}],"second":[{"id":"B","pass":false},{"id":"A","pass":false}]} | {"changed":["A"]} | A changes from pass to fail while B remains failed. |
| Only display order changes | {"first":[{"id":"A","pass":true},{"id":"B","pass":false}],"second":[{"id":"B","pass":false},{"id":"A","pass":true}]} | {"changed":[]} | Stable IDs show no grading change despite reversed positions. |
| Second round candidate missing | {"first":[{"id":"A","pass":true},{"id":"B","pass":false}],"second":[{"id":"A","pass":true}]} | {"error":"matched-review-input"} | A missing B prevents a matched order-effect audit. |
Work the unmatched-candidate case. Which output is required, and why?
Show the worked answer
{"error":"matched-review-input"} — A missing B prevents a matched order-effect audit.
Run the self-contained evaluator
import assert from 'node:assert/strict';
function evaluate(x){
const ids=x.first.map(r=>r.id).sort(),secondIds=x.second.map(r=>r.id).sort();if(new Set(ids).size!==ids.length||new Set(secondIds).size!==secondIds.length||JSON.stringify(ids)!==JSON.stringify(secondIds)||[...x.first,...x.second].some(r=>typeof r.pass!=='boolean'))return {error:'matched-review-input'};
return {changed:ids.filter(id=>x.first.find(r=>r.id===id).pass!==x.second.find(r=>r.id===id).pass)};
}
const cases = [
{
"id": "one-label-changes",
"input": {
"first": [
{
"id": "A",
"pass": true
},
{
"id": "B",
"pass": false
}
],
"second": [
{
"id": "B",
"pass": false
},
{
"id": "A",
"pass": false
}
]
},
"expected": {
"changed": [
"A"
]
}
},
{
"id": "order-only-change",
"input": {
"first": [
{
"id": "A",
"pass": true
},
{
"id": "B",
"pass": false
}
],
"second": [
{
"id": "B",
"pass": false
},
{
"id": "A",
"pass": true
}
]
},
"expected": {
"changed": []
}
},
{
"id": "unmatched-candidate",
"input": {
"first": [
{
"id": "A",
"pass": true
},
{
"id": "B",
"pass": false
}
],
"second": [
{
"id": "A",
"pass": true
}
]
},
"expected": {
"error": "matched-review-input"
}
}
];
for (const c of cases) assert.deepEqual(evaluate(c.input), c.expected, c.id);
console.log(JSON.stringify({checked:cases.length,caseIds:cases.map(c=>c.id)}));
Keep both presentation orders with the paired labels. Changed grades warrant rubric review, but these invented observations do not prove a presentation-order cause.