{"record":{"id":"e10d24305715a1c4","repo":"affaan-m/ECC","slug":"trusted-reconciliation-evidence-is-required","errorCode":null,"errorMessage":"trusted reconciliation evidence is required","messagePattern":"trusted reconciliation evidence is required","errorType":"validation","errorClass":"ClaimError","httpStatus":null,"severity":"error","filePath":"skills/operator-approval-loop/references/approval_claims.py","lineNumber":170,"sourceCode":"                             (row['obligation_id'],)).rowcount\n        if changed != 1:\n            raise ClaimError('obligation completion failed')\n    return True\n\n\ndef complete(db, token, coordinate, *, now):\n    \"\"\"Atomically record a confirmed result; identical duplicate completion is a no-op.\"\"\"\n    return _finish(db, token, coordinate, now, None)\n\n\ndef reconcile(db, token, coordinate, evidence, *, now):\n    \"\"\"Trusted caller supplies verified outcome evidence; this does not verify it.\n\n    No cancellation/retry of unknown claims is provided: a paused original\n    executor could still act. Operator authentication is outside this reference.\n    \"\"\"\n    if not isinstance(evidence, str) or not evidence.strip():\n        raise ClaimError('trusted reconciliation evidence is required')\n    return _finish(db, token, coordinate, now, evidence)\n","sourceCodeStart":152,"sourceCodeEnd":172,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/operator-approval-loop/references/approval_claims.py#L152-L172","documentation":"reconcile() raises this ClaimError when the evidence argument is not a nonempty string. The module is a reference implementation that never verifies outcomes itself; it therefore demands the trusted caller supply explicit, nonempty outcome evidence that is stored on the claim (reconciliation_evidence) as an audit record.","triggerScenarios":"reconcile(db, token, coordinate, None, now=...), reconcile(db, token, coordinate, \"\", now=...), or evidence as whitespace/bytes/other non-str type.","commonSituations":"An operator pipeline that has no evidence variable populated; passing a boolean or an ID object instead of an evidence string; wiring reconcile into automation before the evidence-capture step exists.","solutions":["Supply a nonempty string describing the verified outcome (e.g. transport receipt ID, operator attestation reference).","Validate before calling: isinstance(evidence, str) and evidence.strip().","Capture evidence at the point of verification (from the transport layer's response) rather than passing a placeholder.","If no trusted evidence exists, do not reconcile — leave the claim 'unknown'; there is deliberately no path to resolve unknowns without evidence."],"exampleFix":"// before\nclaims.reconcile(db, token, coordinate, True, now=ts)  # non-string evidence\n\n// after\nevidence = f\"transport_receipt:{receipt.id}\"\nif not (isinstance(evidence, str) and evidence.strip()):\n    raise ValueError(\"reconciliation evidence required\")\nclaims.reconcile(db, token, coordinate, evidence, now=ts)","handlingStrategy":"validation","validationCode":"def validate_evidence(evidence):\n    return isinstance(evidence, str) and bool(evidence.strip())\n\nif not validate_evidence(evidence):\n    raise ValueError(\"reconcile requires nonempty trusted evidence\")","typeGuard":"def is_nonempty_str(value):\n    return isinstance(value, str) and value.strip() != \"\"","tryCatchPattern":"try:\n    claims.reconcile(db, token, coordinate, evidence, now=ts)\nexcept claims.ClaimError:\n    log.error(\"reconciliation refused; evidence missing or empty\")","preventionTips":["Capture evidence from the transport response at verification time","Coerce evidence objects to descriptive strings before reconciling","Leave claims 'unknown' when no trusted evidence exists — never pass placeholders"],"tags":["validation","audit","required-field","api-misuse"],"backgroundTag":"missing-required-argument","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}