panel-gate · integration
drop-in human-verification widget. one click per visitor; the answer doubles as preference data. public-pool units only — flagship LLMs can't reliably solve taste, so bots fail the gate.
1 · install
pick one. iframe is recommended for sites with strict CSP.
iframe (recommended)
<iframe
src="https://panel.goku.codes/embed?site_key=pk_demo_a"
width="420" height="320"
style="border:0;background:transparent"
title="panel verification"
></iframe>
<script>
window.addEventListener('message', e => {
if (e.origin !== 'https://panel.goku.codes') return;
if (e.data?.type === 'panel:solved') {
// attach e.data.token to your form / next API call
document.querySelector('input[name=panel_token]').value = e.data.token;
}
});
</script>direct widget route
<a href="https://panel.goku.codes/widget?site_key=pk_demo_a" target="_blank"> verify with panel → </a>
2 · verify the token server-side
on form submit, POST the token to /api/verify. response includes a probability score, trust tier, and behavioral flag. do this server-side — never trust the client copy.
curl
curl -s https://panel.goku.codes/api/verify \
-H 'content-type: application/json' \
-H 'X-Panel-Secret: sk_test_REPLACE' \
-d '{"token":"PANEL_TOKEN_FROM_CLIENT"}'
# {"ok": true, "score": 0.81, "trust": 0.74, "honeypot_failed": false}node (fetch)
const r = await fetch('https://panel.goku.codes/api/verify', {
method: 'POST',
headers: {
'content-type': 'application/json',
'X-Panel-Secret': process.env.PANEL_SECRET,
},
body: JSON.stringify({ token }),
});
const { ok, score, honeypot_failed } = await r.json();
if (!ok || honeypot_failed || score < 0.5) return res.status(403).end('blocked');tokens are single-use (jti ledger) and expire in ~10min. opaque scoring: the score may shift hours later as more humans rate the same unit.
3 · site keys
each origin gets a publishable pk_ key (client-side, lives in HTML) and a server sk_ secret (env var only). dev keys: pk_demo_a works against panel.goku.codes for testing — do not ship to prod.
- rotate secrets via the /operator console.
- per-key rate limit is enforced (token-bucket; see
middleware.ts). - compliance scrubbing happens upstream at
scrubber.goku.codesbefore any unit text reaches a rater.
4 · what raters see
poke around /demo/gate to see the visitor view. unit types in the public pool:
- taste_rank — pick the best of 3 (UI copy, slogans, error messages)
- sarcasm_detect / ai_vs_real — binary judgment
- dub_sync — short CC clip + binary judgment on a/v alignment
- drag_to_rank — reorder 4 items (motor-control bot gate)
- span_highlight — click first/last word to mark a span (motor-control bot gate)
technical units (code review, agent traces) never reach anonymous raters — they flow through the trusted-rater pool.
5 · compliance
panel collects only pseudonymous rater data. honest posture: we implement controls, we don't claim certifications. full breakdown lives in the vault under (600) Work/panel/compliance/.
- privacy policy — draft, lawyer review pending.
- terms of service — draft, lawyer review pending.
- data export (DSAR):
GET /api/me/export?rater_id=<id>— downloadable JSON of your judgments + profile. - data erasure:
POST /api/me/delete?rater_id=<id>— anonymizes your id; aggregate ML signal preserved per GDPR Recital 26. - audit log: append-only sqlite table; we record verify/me/key-rotation events. export available on operator request via support email.
GDPR: yes (legitimate interest for raters, contract for operators). KVKK: yes (below VERBIS threshold; cross-border consent UI planned). HIPAA: no — panel is not a covered entity by default; BAA available only after design-partner #3 + counsel review. do not send PHI without a signed BAA.