Skip to content
Astera Technology

Retain independent grading dimensions without averaging a blocker

Good language quality compensates for a blocking task criterion.

Download complete case notes and answer keys ↓

Define the local evaluation task

A synthetic drafting rubric supplies Boolean outcomes per dimension and explicitly names the required dimensions. Every required dimension must exist and pass; other dimensions are retained but cannot compensate. A missing required dimension is unresolved. No numeric averaging or weighted compromise is defined.

  1. Retain independent dimension labels
  2. Select explicitly required dimensions
  3. Require complete passing required evidence

Absent or malformed required dimensions need rubric evidence before grading.

Use the filled cases

Original synthetic input and literal answer key
CaseSupplied inputExpected structured outputDecision and reason
Fluency cannot offset required format failure{"required":["content","format"],"outcomes":{"content":true,"format":false,"fluency":true}}{"missing":[],"failed":["format"],"invalid":[],"status":"fail"}The required format fails even though two dimensions pass.
Required pass, optional fail{"required":["content"],"outcomes":{"content":true,"style":false}}{"missing":[],"failed":[],"invalid":[],"status":"pass"}Style is retained but not required under this supplied rubric.
Required dimension missing{"required":["content","format"],"outcomes":{"content":true}}{"missing":["format"],"failed":[],"invalid":[],"status":"unresolved"}Missing format is not silently passed or failed.
Download editable CSV ↓

Work the missing-required case. Which output is required, and why?

Show the worked answer

{"missing":["format"],"failed":[],"invalid":[],"status":"unresolved"} — Missing format is not silently passed or failed.

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 missing=x.required.filter(k=>!Object.hasOwn(x.outcomes,k)),failed=x.required.filter(k=>Object.hasOwn(x.outcomes,k)&&x.outcomes[k]===false),invalid=x.required.filter(k=>Object.hasOwn(x.outcomes,k)&&typeof x.outcomes[k]!=='boolean');
 return {missing,failed,invalid,status:missing.length+invalid.length?'unresolved':failed.length?'fail':'pass'};
}

const cases = [
  {
    "id": "fluency-no-compensation",
    "input": {
      "required": [
        "content",
        "format"
      ],
      "outcomes": {
        "content": true,
        "format": false,
        "fluency": true
      }
    },
    "expected": {
      "missing": [],
      "failed": [
        "format"
      ],
      "invalid": [],
      "status": "fail"
    }
  },
  {
    "id": "required-pass-optional-fail",
    "input": {
      "required": [
        "content"
      ],
      "outcomes": {
        "content": true,
        "style": false
      }
    },
    "expected": {
      "missing": [],
      "failed": [],
      "invalid": [],
      "status": "pass"
    }
  },
  {
    "id": "missing-required",
    "input": {
      "required": [
        "content",
        "format"
      ],
      "outcomes": {
        "content": true
      }
    },
    "expected": {
      "missing": [
        "format"
      ],
      "failed": [],
      "invalid": [],
      "status": "unresolved"
    }
  }
];
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 the required-dimension list with each revision of the acceptance rubric. Changing a blocker is a policy change, not a harmless score formatting adjustment.

Related resources