[Turnstile] Add Spin docs page#31195
Open
juleslemee wants to merge 8 commits into
Open
Conversation
Adds /turnstile/spin/ documenting the Turnstile Spin agent skill: how to invoke it, what it does end-to-end (widget create, Worker deploy, frontend snippets, validation), the full inlined SKILL.md prompt for paste-into-agent flows, recovery flow, edge cases, and migration from reCAPTCHA/hCaptcha. Companion to the skill PR at cloudflare/skills#58. Internal PRD: https://jira.cfdata.org/browse/NC-8209
Contributor
Review⏸️ Automatic reviews for this PR are paused. This PR has already received 2 automatic reviews. To run another review, a codeowner can comment
|
added 4 commits
June 3, 2026 11:23
Sync to the refactored skill bundle. The MDX page's inlined paste-into-agent prompt now consists of the (much shorter) SKILL.md orchestration + a bootstrap section that writes the 6 helper scripts under /tmp/turnstile-spin-scripts/. Total prompt length is comparable to before; the architecture is cleaner because the agent now branches on structured JSON output from deterministic scripts instead of inline bash interpretation. Companion to cloudflare/skills#58.
Per Marina's review feedback, add the Beta badge to the Spin landing page (matching the multi-cloud-networking pattern): - title gets the "(beta)" suffix - sidebar.badge.text set to "Beta"
Move spin/index.mdx to spin.mdx so the page is a flat sidebar sibling of Plans, Concepts, etc., instead of a collapsible group with a single child. Shorten sidebar.label from "Spin (one-shot setup)" to "Spin".
Addresses 5 findings from Miguel's review: 1. Resolved wrangler login contradiction. The skill prose said "don't use wrangler login because OAuth lacks Account.Turnstile:Edit" but the human walkthrough, the troubleshooting table, and the 403 recovery section all instructed the agent to run wrangler login. Replaced with token-creation guidance everywhere. 2. Fixed multi-account handling in auth-probe.sh. The script hardcoded .accounts[0].id and treated any user-set CLOUDFLARE_ACCOUNT_ID pointing at a non-first account as a mismatch. It now checks membership in the accounts array, emits a new multiple_accounts status when the token covers >1 accounts and the env var is unset, and only uses [0] when there is exactly one account. 3. Added a Workers scope probe. The script docstring claimed status:ok meant both Turnstile and Workers scope were present, but the code only hit GET /challenges/widgets. Added a second probe against /workers/scripts that emits missing_workers_scope when the token lacks Account.Workers Scripts:Edit, preventing widget creation followed by Worker deploy failure. 4. Fixed wrangler secret put without --name in the human walkthrough. The script uses --name correctly; the docs prose did not, so the secret would land on wrangler.toml's default worker name. Also reordered: deploy first (so the named Worker exists), then put the secret on it. Made set_secret failure fatal in worker-deploy.sh (was previously swallowed; the script could emit status:ok with no secret on the Worker). 5. Fixed jq shape mismatch in curl fallback. Was '.account.id' (singular, wrong); now '.accounts[0].id' (matches wrangler whoami --json output and the helper script).
migueldemoura
approved these changes
Jun 4, 2026
Member
|
Skill being checked elsewhere, else double-checked by @marinaelmore (probably needs to be added as a CO) |
added 3 commits
June 4, 2026 11:16
Two more findings from review:
1. The framework code examples (Vanilla HTML, Next.js App, Next.js Pages,
Astro, SvelteKit, Hugo) set form action / fetch directly to the Spin
Worker URL. The Worker is a siteverify proxy: it validates the token
and returns { success } but does not persist form data. Pointing the
form at the Worker means every signup or subscribe submission is
silently dropped. Rewrote all six tabs to gate-then-forward: POST the
token to the Worker, check success, then submit to the user's real
endpoint (/api/subscribe placeholder). Updated the prose at Step 6 to
call out the contract and the failure mode explicitly.
2. worker-deploy.sh captured only stderr from npx wrangler deploy
(2>"$deploy_log"), then grepped the file for the workers.dev URL.
Wrangler emits the success URL on stdout in current versions, so the
script could deploy successfully and still emit url_parse_failed.
Capture both streams (>"$deploy_log" 2>&1).
Comprehensive sweep before another reviewer round. Findings:
P1 — would fail at the shell or violate stated contracts:
1. Removed all references to `wrangler turnstile` subcommand (does
not exist in current wrangler; the recommended Step 4 path was
the API curl; Step 7c hostname check and recovery flow now also
use the API directly).
2. fetch-secret.sh now returns `clearance_level` and `domains` so
the recovery flow's pre-clearance scope check is actually
implementable.
3. Dropped the `?widget=<id>` URL trigger from the recovery flow —
nothing in the skill parsed it. Recovery now uses a verbal
trigger (user tells the agent they have an existing sitekey).
4. validate.sh hits `/health` (not `/`) so the diagnostic stops
lying about what was checked and breaks predictably if the
Worker template ever differentiates the two routes.
7. Rewrote Next.js (App + Pages) and SvelteKit examples so they
delegate to a clearly-marked `/* existing submit logic */`
placeholder instead of replacing the user's handler with a
hardcoded `fetch('/api/subscribe', ...)`. Updated the prose
contract to spell out both failure modes (don't replace the form
target, don't replace the existing handler).
P2 — clear customer impact:
5. worker-deploy.sh URL parser now falls back from the workers.dev
regex to a broader URL match (excluding cloudflare.com hosts) so
custom domains and Workers for Platforms don't return
url_parse_failed on a successful deploy.
6. auth-probe.sh reworded the Workers scope probe comment to be
honest about its best-effort nature (Custom Token UI does not
guarantee Read alongside Edit).
9. persist-skill.sh now installs the canonical bundle (SKILL.md +
scripts/ + references/) via degit from cloudflare/skills instead
of writing the inlined bootstrap version, so persisted skills can
re-run without falling back to the /tmp/ bootstrap path.
11. Wizard flow Step 5 documents the set_secret_failed recovery path
(was only in the conversation-flow Step 9).
12. validate.sh asserts the `_worker` metadata field is present in
the dummy-siteverify response (Step 7b promised this assertion
but the script never checked).
13. Standardised on `<worker_name from worker-deploy.sh output>` in
edge case tables; removed the $WORKER_NAME env var reference
that was never exported.
14. Migration substitutions: tell the agent to *delete* the manual
hidden input (Turnstile renders `cf-turnstile-response` itself),
not rename it. Documented that the Worker template now accepts
the reCAPTCHA-style `response` field name for drop-in backend
migration. "Hash suffix" reworded to "random suffix" with
`openssl rand -hex 3`.
16. worker-deploy.sh `set_secret` failure now captures wrangler's
stderr and includes a `detail` field in the error JSON instead
of swallowing it.
- Replaced the timestamp-tail Worker-name suffix with openssl rand (3 bytes hex = 6 chars), falling back to the timestamp tail if openssl is absent. Docs prose already said "hash"; the script body now matches. - Step 3 parallel-work hint now scopes itself to option 3 (paste in chat). Options 1 (export + relaunch) and 2 (save to file + relaunch) restart the agent session and lose any pre-fetched state, so the doc no longer tells the agent to do work that gets thrown away.
migueldemoura
approved these changes
Jun 5, 2026
punkeel
approved these changes
Jun 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds the canonical docs page for Turnstile Spin at
/turnstile/spin/.What's on the page
Also adds the matching plain-markdown copy at
public/turnstile/spin/index.mdso the agent's Step 8 (persist skill) can fetch it viacurl.Companion PRs
Internal context
Tier 3 launch tracked in NC-8209. PRD: https://jira.cfdata.org/browse/NC-8209
Validation: `pnpm run check` passes on the spin MDX. No type errors or broken internal links specific to this page.