Skip to content

Record the device bucket for every captcha type, not only PoW - #3619

Merged
forgetso merged 4 commits into
mainfrom
feat/fingerprint-summary-every-captcha
Oct 26, 2026
Merged

forgetso merged 4 commits into
mainfrom
feat/fingerprint-summary-every-captcha

Conversation

@forgetso

Copy link
Copy Markdown
Member

What changed

The widget now sends its proof of fingerprint with the frictionless request, the first request every session makes. The provider checks it, stores the summary (including the device bucket) on the session, and copies it onto the PoW, puzzle or image record the session leads to.

Why

Until now only the PoW widget built the proof, and only a PoW submission read it. Sessions served a puzzle or an image never got a device bucket. In 24 hours of puzzle drags, only 44% could be given one, and only by finding a PoW the same account had solved.

Effect

  • Every new session records its fingerprint summary, whatever captcha it is served.
  • PoW, puzzle and image records carry the summary, so the bucket can be read straight off any captcha record.
  • Escalated sessions (PoW, then puzzle or image) inherit it. A proof submitted with a PoW still replaces the frictionless one.
  • Building the proof is best-effort and capped at 1 second. If it fails or is slow, the request goes out without it, so the captcha is never held up.
  • Routing behaviour is unchanged. The summary is recorded at the frictionless step but not given to the routing machine there, so deviceBucket counter rules still fire only where they did before. Feeding it to the rules earlier should be its own decision.

Old widgets that don't send the proof work as before: their sessions just have no summary.

Test coverage

  • Schemas: the summary survives the session, image-commitment, puzzle and PoW schemas, plus their central-store copies (8 cases). Checked by removing the field from one schema, which fails its two cases.
  • Frictionless handler: a valid proof puts the summary and bucket on the session; an invalid or missing proof puts nothing.
  • Session creation stores it, and leaves it off when there's none.
  • Escalation takes the PoW proof's summary, falling back to the session's.
  • Origin fallback fills it for escalations and keeps an escalation's own.
  • Image commitment and puzzle record copy it from the session.
  • Widget: sends the proof on both the detector and no-detector paths, and leaves it off when it fails or takes over a second.
  • Not covered by a unit test: the one-argument change in the PoW challenge handler, which has no unit test for normal issuance. It is type-checked.

Local runs: provider unit 1,985 passed; types 292; types-database 110; procaptcha-frictionless 171; build:tsc clean for 76 tasks.

🤖 Generated with Claude Code

forgetso and others added 2 commits October 26, 2026 12:48
The proof of fingerprint was only generated by the PoW widget and only read on PoW
submit, so puzzle and image records never carried the device bucket. The client
now sends the proof with the frictionless request, the provider stores its
summary on the session, and the PoW, puzzle and image records copy it from there.
Escalation sessions inherit it; a proof submitted with a PoW still wins.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@forgetso
forgetso enabled auto-merge (squash) October 26, 2026 13:26
@forgetso
forgetso merged commit 78107d9 into main Oct 26, 2026
20 checks passed
@forgetso
forgetso deleted the feat/fingerprint-summary-every-captcha branch October 26, 2026 13:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant