Define the local evaluation task
A synthetic result adapter permits either raw payload text or exactly one outer csv code fence with no preceding or trailing lines. The fence opening and closing occupy their own lines. Any other fence occurrence is malformed. Unfenced notes remain payload text; they are not silently removed. Return payload and line count, not CSV semantic validation.
- Identify the complete outer wrapper
- Remove only the permitted opening and closing lines
- Retain payload text exactly
Malformed wrappers are held; the adapter does not guess where the payload starts.
Use the filled cases
| Case | Supplied input | Expected structured output | Decision and reason |
|---|---|---|---|
| One complete outer fence | {"text":"```csv\na,b\n1,2\n```"} | {"payload":"a,b\n1,2","lines":2} | Only the declared outer fence is removed; both data lines remain. |
| Note outside any fence | {"text":"Note\na,b\n1,2"} | {"payload":"Note\na,b\n1,2","lines":3} | Note is retained as input text; later payload validation must decide its admissibility. |
| Extra line after closing fence | {"text":"```csv\na,b\n```\nNote"} | {"error":"wrapper"} | The complete input is not one permitted outer fence. |
Work the trailing-note case. Which output is required, and why?
Show the worked answer
{"error":"wrapper"} — The complete input is not one permitted outer fence.
Run the self-contained evaluator
import assert from 'node:assert/strict';
function evaluate(x){
const fence=String.fromCharCode(96).repeat(3),lines=x.text.split('\n');if(lines[0]===fence+'csv'&&lines.at(-1)===fence&&lines.slice(1,-1).every(l=>!l.includes(fence))){const payload=lines.slice(1,-1).join('\n');return {payload,lines:payload?lines.length-2:0};}
if(x.text.includes(fence))return {error:'wrapper'};return {payload:x.text,lines:x.text?lines.length:0};
}
const cases = [
{
"id": "one-outer-fence",
"input": {
"text": "```csv\na,b\n1,2\n```"
},
"expected": {
"payload": "a,b\n1,2",
"lines": 2
}
},
{
"id": "unfenced-note",
"input": {
"text": "Note\na,b\n1,2"
},
"expected": {
"payload": "Note\na,b\n1,2",
"lines": 3
}
},
{
"id": "trailing-note",
"input": {
"text": "```csv\na,b\n```\nNote"
},
"expected": {
"error": "wrapper"
}
}
];
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 raw and unwrapped outputs together when debugging an import adapter. The literal csv fence label is a fixture grammar; the code does not parse or certify CSV contents.