Define the local evaluation task
A synthetic answer adapter receives rows, a Boolean complete flag and a next reference that is either text or null. Complete true requires no next reference; otherwise the response is contradictory. Incomplete responses expose only observed row count, keep total null and retain the next reference. The checker never follows it.
- Validate completeness channel
- Count supplied observed rows
- Retain unknown total and continuation for partial data
A contradictory sentinel blocks a complete-summary claim.
Use the filled cases
| Case | Supplied input | Expected structured output | Decision and reason |
|---|---|---|---|
| Two observed rows in partial result | {"rows":["A","B"],"complete":false,"next":"T"} | {"partial":true,"observed":2,"total":null,"next":"T"} | Two observed rows do not establish the complete result count. |
| Complete empty result | {"rows":[],"complete":true,"next":null} | {"partial":false,"observed":0,"total":0,"next":null} | A declared complete empty result establishes zero rows. |
| Continuation reference is numeric | {"rows":["A"],"complete":false,"next":42} | {"error":"completeness-contract"} | The supplied reference channel accepts text or null, not a numeric value. |
| Contradictory complete marker | {"rows":["A"],"complete":true,"next":"T"} | {"error":"completeness-contract"} | The local contract cannot simultaneously end the result and retain a continuation. |
Work the complete-with-next case. Which output is required, and why?
Show the worked answer
{"error":"completeness-contract"} — The local contract cannot simultaneously end the result and retain a continuation.
Run the self-contained evaluator
import assert from 'node:assert/strict';
function evaluate(x){
if(typeof x.complete!=='boolean'||(x.next!==null&&typeof x.next!=='string')||(x.complete&&x.next!==null))return {error:'completeness-contract'};
return {partial:!x.complete,observed:x.rows.length,total:x.complete?x.rows.length:null,next:x.next};
}
const cases = [
{
"id": "partial-two-rows",
"input": {
"rows": [
"A",
"B"
],
"complete": false,
"next": "T"
},
"expected": {
"partial": true,
"observed": 2,
"total": null,
"next": "T"
}
},
{
"id": "complete-empty",
"input": {
"rows": [],
"complete": true,
"next": null
},
"expected": {
"partial": false,
"observed": 0,
"total": 0,
"next": null
}
},
{
"id": "nontext-reference",
"input": {
"rows": [
"A"
],
"complete": false,
"next": 42
},
"expected": {
"error": "completeness-contract"
}
},
{
"id": "complete-with-next",
"input": {
"rows": [
"A"
],
"complete": true,
"next": "T"
},
"expected": {
"error": "completeness-contract"
}
}
];
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 the raw completeness marker with staff-facing summaries. This adapter does not traverse pages or certify a snapshot of a changing dataset.