Define the local evaluation task
A synthetic knowledge list supplies chunk ID and parent document ID for every hit. Keep the first encountered chunk for each parent, preserving list order, then take up to the supplied document-slot limit. Reject a negative or fractional limit. Do not deduplicate by matching chunk text.
- Read parent identity from each hit
- Keep each parent’s first chunk
- Apply document-slot limit afterwards
Missing parent associations must be repaired before using this collapse rule.
Use the filled cases
| Case | Supplied input | Expected structured output | Decision and reason |
|---|---|---|---|
| Repeated chunks dominate | {"limit":3,"hits":[{"id":"A1","parent":"A"},{"id":"A2","parent":"A"},{"id":"A3","parent":"A"},{"id":"B1","parent":"B"},{"id":"C1","parent":"C"}]} | {"kept":["A1","B1","C1"],"uniqueParents":3} | Three document slots represent three parents after collapse. |
| Only one document slot | {"limit":1,"hits":[{"id":"B2","parent":"B"},{"id":"A1","parent":"A"},{"id":"B1","parent":"B"}]} | {"kept":["B2"],"uniqueParents":2} | The first parent remains B; this rule does not re-sort by chunk name. |
| Two chunks lack parent identity | {"limit":2,"hits":[{"id":"A1"},{"id":"B1"}]} | {"error":"parent-association"} | Missing associations are rejected; two undefined parents must not collapse into one source. |
| Fractional slot limit | {"limit":1.5,"hits":[]} | {"error":"slot-limit"} | A list slot is indivisible; reject this limit instead of rounding it. |
Work the fractional-slots case. Which output is required, and why?
Show the worked answer
{"error":"slot-limit"} — A list slot is indivisible; reject this limit instead of rounding it.
Run the self-contained evaluator
import assert from 'node:assert/strict';
function evaluate(x){
if(!Number.isInteger(x.limit)||x.limit<0)return {error:'slot-limit'};
if(x.hits.some(h=>!h||typeof h.parent!=='string'||!h.parent.trim()))return {error:'parent-association'};
const seen=new Set(),kept=[];for(const h of x.hits)if(!seen.has(h.parent)){seen.add(h.parent);kept.push(h.id);}
return {kept:kept.slice(0,x.limit),uniqueParents:seen.size};
}
const cases = [
{
"id": "many-one-parent",
"input": {
"limit": 3,
"hits": [
{
"id": "A1",
"parent": "A"
},
{
"id": "A2",
"parent": "A"
},
{
"id": "A3",
"parent": "A"
},
{
"id": "B1",
"parent": "B"
},
{
"id": "C1",
"parent": "C"
}
]
},
"expected": {
"kept": [
"A1",
"B1",
"C1"
],
"uniqueParents": 3
}
},
{
"id": "one-slot",
"input": {
"limit": 1,
"hits": [
{
"id": "B2",
"parent": "B"
},
{
"id": "A1",
"parent": "A"
},
{
"id": "B1",
"parent": "B"
}
]
},
"expected": {
"kept": [
"B2"
],
"uniqueParents": 2
}
},
{
"id": "missing-parent-ids",
"input": {
"limit": 2,
"hits": [
{
"id": "A1"
},
{
"id": "B1"
}
]
},
"expected": {
"error": "parent-association"
}
},
{
"id": "fractional-slots",
"input": {
"limit": 1.5,
"hits": []
},
"expected": {
"error": "slot-limit"
}
}
];
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)}));
Store the original chunk list beside the collapsed list so staff can see which source slots were recovered. This is a diversity transform, not a judgement that every retained document is useful.