Define the local evaluation task
A synthetic assistant receives an ordered list of indivisible evidence blocks with local size units. Its declared packer scans once and keeps any block fitting the remaining budget, skipping larger blocks without stopping. Required block IDs are supplied separately. Report the resulting pack, unused units and required IDs evicted by this exact trace. Sizes are fixture units, not provider tokens.
- Scan the supplied order
- Keep fitting blocks and update remaining units
- Compare packed IDs with required evidence
Invalid size units stop the packing trace.
Use the filled cases
| Case | Supplied input | Expected structured output | Decision and reason |
|---|---|---|---|
| Unrelated block enters first | {"budget":7,"blocks":[{"id":"A","size":4},{"id":"B","size":3},{"id":"C","size":2}],"required":["B","C"]} | {"kept":["A","B"],"remaining":0,"missing":["C"]} | Retrieval contained C, but this pack exhausted its seven units before C. |
| Skip a large block and continue | {"budget":3,"blocks":[{"id":"A","size":4},{"id":"C","size":2}],"required":["C"]} | {"kept":["C"],"remaining":1,"missing":[]} | Skipping A does not end the scan; C fits with one unit left. |
| Negative block size | {"budget":3,"blocks":[{"id":"C","size":-1}],"required":["C"]} | {"error":"size"} | Negative size would falsely increase remaining capacity, so reject it. |
Work the invalid-size case. Which output is required, and why?
Show the worked answer
{"error":"size"} — Negative size would falsely increase remaining capacity, so reject it.
Run the self-contained evaluator
import assert from 'node:assert/strict';
function evaluate(x){
if(!Number.isInteger(x.budget)||x.budget<0||x.blocks.some(b=>!Number.isInteger(b.size)||b.size<1))return {error:'size'};
let remaining=x.budget;const kept=[];for(const b of x.blocks)if(b.size<=remaining){remaining-=b.size;kept.push(b.id);}
return {kept,remaining,missing:x.required.filter(id=>!kept.includes(id)).sort()};
}
const cases = [
{
"id": "distractor-first",
"input": {
"budget": 7,
"blocks": [
{
"id": "A",
"size": 4
},
{
"id": "B",
"size": 3
},
{
"id": "C",
"size": 2
}
],
"required": [
"B",
"C"
]
},
"expected": {
"kept": [
"A",
"B"
],
"remaining": 0,
"missing": [
"C"
]
}
},
{
"id": "skip-large-continue",
"input": {
"budget": 3,
"blocks": [
{
"id": "A",
"size": 4
},
{
"id": "C",
"size": 2
}
],
"required": [
"C"
]
},
"expected": {
"kept": [
"C"
],
"remaining": 1,
"missing": []
}
},
{
"id": "invalid-size",
"input": {
"budget": 3,
"blocks": [
{
"id": "C",
"size": -1
}
],
"required": [
"C"
]
},
"expected": {
"error": "size"
}
}
];
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)}));
Use this trace to locate evidence lost after retrieval. Changing a packing policy requires a new declared rule and fixture; the example does not optimise which evidence is most valuable.