Skip to content
Astera Technology

Compare grading with candidate order reversed

A staff decision changes with presentation order while case content remains fixed.

Download complete case notes and answer keys ↓

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.

  1. Match the same candidate IDs across rounds
  2. Ignore presentation positions for matching
  3. List changed labels for staff review

Unmatched or duplicated candidates invalidate the paired audit.

Use the filled cases

Original synthetic input and literal answer key
CaseSupplied inputExpected structured outputDecision 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.
Download editable CSV ↓

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

Save as .mjs and run with Node.js; supplied fixtures only
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)}));
Download runnable example ↓

Keep both presentation orders with the paired labels. Changed grades warrant rubric review, but these invented observations do not prove a presentation-order cause.

Related resources