{"id":"d077bced-dc19-4e8d-a317-2fe5b7bda2ac","org_id":"5b607c7a-3ba2-4077-b038-cdccd0ce7c34","project_id":"b18679c0-fffb-4308-82b6-9e91be23582f","parent_id":null,"identifier":"BEB-9181","number":9181,"title":"THE VERIFIER PASSES ANY PAGE — ~20 tickets marked done on 44 visible chars or 249 bytes of JSON","description":"Repo: alexrollin/abilifi-apps (dispatcher verifier)\nClass: CODE\nLane: BUILD\nFEATURE NAME: **VERIFY THE DELIVERABLE**\nPriority: P0.\n\n## MEASURED 2026-09-01\nRoughly twenty tickets were marked done in the last 18 hours. Two checked by hand:\n\n**BEB-207** — \"fix the Sove Android app, ship a production APK, test on a real device\". Marked done at 02:06 on this evidence, verbatim:\n  \"VERIFICATION PASSED — html-render class: browser-verified (44 visible chars, 0 errors)\"\nThe artefact is https://widgets.abilifi.net/orky-beb-207. Probed just now: 200, rendered_has_content FALSE, 44 visible characters, text \"Settings EID Type Name Status Refs Data Save\" — the generic shape template. There is no APK. There is no Android build. The ticket's own acceptance requires a real device.\n\n**BEB-408** — a strategy ticket about taking over a speeltuin from a stichting. No code deliverable at all. First attempt was caught by the template-identity gate (\"serves a body BYTE-IDENTICAL to BEB-2908\") and correctly rescinded. The SECOND attempt passed on:\n  \"json-parse class: valid JSON, HTTP 200, 249 bytes (char count not consulted)\"\nSo the fix for a caught template was to emit 249 bytes of JSON instead, and that counted.\n\n## WHAT IS ACTUALLY WRONG\nThe verifier grades WHETHER SOMETHING RENDERED, not whether the deliverable exists. Its classes — html-render, json-parse — can be satisfied by any page and any endpoint. The template-identity gate only catches a byte-for-byte repeat, so varying the bytes defeats it.\n\nThe result is worse than a stalled loop: the ticket record now says these are finished. Every count, every goal-progress read and every report built on top of it is wrong, and the work will never be picked up again because nothing is asking for it.\n\n## THE FIX\n1. A pass requires the TICKET'S OWN acceptance, checked clause by clause — not a generic render class. No contract, no pass: the lane blocks with NO_CONTRACT rather than completing.\n2. A ticket whose deliverable is not a web surface (a mobile build, a document, a business arrangement) can NEVER be satisfied by a URL. The verifier refuses those by class instead of inventing a page for them.\n3. The checker is a different model from the builder, per the checking rules.\n4. Audit the tickets closed this way, list them, and requeue each with the verdict quoted. That list goes on this ticket.\n\n## Acceptance (one call each)\n1. A deploy that renders a generic settings shell against a ticket asking for something else FAILS, naming the acceptance clause it does not satisfy.\n2. A ticket with no contract cannot reach done — proven by attempting it.\n3. The audit list of falsely-completed tickets is on this ticket with each one's verbatim pass line.\n\nRefs: BEB-9167 (builder does not mark its own work done), BEB-9168 (auditor), BEB-2348 (the ruling being applied), BEB-2436 (contracts).","status":"todo","priority":0,"assignee_id":null,"created_at":1788283084710,"updated_at":1788442615695,"completed_at":null,"due_date":null,"claimed_by":null,"claimed_until":null,"required_capabilities":null,"estimate":300,"cost_ceiling":600,"cancelled_at":null,"last_actor":"unverified:shared"}