panel · v0 hosted preview · statusfree tier open · paid tiers in DP onboarding
panel/docs
operator docs · v0 · 5-min skim

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.codes before 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.