Skip to content
Astera Technology

Stop a summary when its supplied tool result is truncated

A partial response with a sentinel is summarised as the entire result set.

Download complete case notes and answer keys ↓

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.

  1. Validate completeness channel
  2. Count supplied observed rows
  3. Retain unknown total and continuation for partial data

A contradictory sentinel blocks a complete-summary claim.

Use the filled cases

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

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

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

Keep the raw completeness marker with staff-facing summaries. This adapter does not traverse pages or certify a snapshot of a changing dataset.

Related resources