From 2d68753b99723f2feeec937b90fc63d087e22f79 Mon Sep 17 00:00:00 2001 From: Andy Boutte Date: Wed, 30 Sep 2026 07:48:09 -0500 Subject: [PATCH] docs: soften email requirement messaging in run.sh and docs The license server now accepts consumer domains (gmail, icloud, yahoo) alongside business addresses. Only privacy-relay and known-spam/disposable domains are rejected, so the "work address only / personal domains are not accepted" wording is no longer accurate. - run.sh: retry prompt is now `Email address:` instead of `Work email:`, and the non-interactive/give-up errors describe the real rule - README, quickstart, install, prerequisites, configuration, faq, cli-reference, troubleshooting, hackday guide: same softening The server's own rejection message is still echoed verbatim first; the devkit wording is only the follow-on hint. Co-Authored-By: Claude Opus 5 (1M context) --- README.md | 4 ++-- docs/cli-reference.md | 2 +- docs/configuration.md | 3 ++- docs/faq.md | 9 +++++---- docs/getting-started/install.md | 8 ++++---- docs/getting-started/prerequisites.md | 5 +++-- docs/quickstart.md | 4 ++-- docs/troubleshooting.md | 5 +++-- hackday/Installing DevKit.md | 5 +++-- run.sh | 10 +++++----- 10 files changed, 30 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 7591daa..0146e1a 100644 --- a/README.md +++ b/README.md @@ -28,8 +28,8 @@ git clone https://github.com/duplocloud/devkit my-agent && cd my-agent ./run.sh ``` -First run asks for an admin **email** — use your **work address**, personal domains (gmail.com, …) are not -accepted — and DuploCloud emails you a **verification link**. Click it and the run continues on its own, then +First run asks for an admin **email** — a work or personal address you can read right now (privacy-relay +and disposable domains are not accepted) — and DuploCloud emails you a **verification link**. Click it and the run continues on its own, then asks for a **password** and an **LLM provider** and brings the stack up, registering your chosen provider's model as the **System default LLM**. Sign in at ****. diff --git a/docs/cli-reference.md b/docs/cli-reference.md index e706a21..6ec95ef 100644 --- a/docs/cli-reference.md +++ b/docs/cli-reference.md @@ -34,7 +34,7 @@ On an EC2 host the provider prompt first probes whether the instance role can ac | `--reset-license` | Forget the license as well: the JWT and both ids it can be re-fetched from. Prints the JWT to stderr first, because DuploCloud will not issue a second one for your address. Refused when the run cannot prompt (`-y`, or no tty) and no `--license` replaces it. | | `--license ` | Use a license JWT you already have. No licensing call is made. | | `--non-interactive`, `-y` | Never prompt. A missing required value is an error instead: `Missing — pass its flag (non-interactive).` | -| `--email ` | Admin email (your UI login, and the address the license is issued to). Must be a **work** address; personal domains are rejected by the license server. | +| `--email ` | Admin email (your UI login, and the address the license is issued to). Work or personal addresses both work; privacy-relay and disposable domains are rejected by the license server. | | `--password ` | Admin password. | | `--model <1\|2\|3\|4\|5\|anthropic\|bedrock\|gateway\|bedrock-instance-role\|subscription>` | LLM provider. `1` is anthropic, `2` is bedrock, `3` is gateway, `4` is bedrock-instance-role, `5` is subscription. Option `4` is only offered at the prompt when the probe proves the role can invoke Bedrock, but `--model bedrock-instance-role` can be passed directly — it then probes and **fails** rather than falling back, since you asked for it explicitly. | | `--anthropic-key ` | Anthropic API key. | diff --git a/docs/configuration.md b/docs/configuration.md index 30c5f2a..f046e05 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -34,7 +34,8 @@ run: it requests a **trial license** for your admin email (the company is derive DuploCloud emails that address a verification link, and the run waits up to 2 minutes for you to click it before picking the license up and writing it to `Licensing__Token`. -Use a **work address** — the license server rejects personal domains — and note that it issues exactly +Use an address you can receive mail at — work or personal is fine, but the license server rejects +privacy-relay and disposable domains — and note that it issues exactly **one license per email address**. There is no second trial for the same address, so `run.sh` is built to never need one: a license it already has is reused, an interrupted verification resumes, and an address the server already knows is **recovered** (the server emails a confirmation link that releases the same license diff --git a/docs/faq.md b/docs/faq.md index d9dbc0b..e5b66ed 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -39,15 +39,16 @@ Improvements to the *framework* are welcome. Your own extensions belong in your ### Do I need a DuploCloud account? No account, but three things: the ability to pull `quay.io/duplocloud/*` (run `docker login quay.io` if the -pull is denied), an LLM key for the agent — Anthropic, Azure AI Foundry, or AWS Bedrock — and a **work email -address**, because the stack is licensed. On an EC2 instance whose IAM role can already invoke Bedrock, +pull is denied), an LLM key for the agent — Anthropic, Azure AI Foundry, or AWS Bedrock — and an **email +address you can receive mail at**, because the stack is licensed. On an EC2 instance whose IAM role can already invoke Bedrock, `run.sh` offers a keyless option and you need no LLM key at all. ### Do I need a license key, and where does it come from? Yes, and `./run.sh` gets it for you. On first run it requests a trial license for the admin email you enter and writes the JWT into `.env` as `Licensing__Token`; the studio reads it from there. You have to click a -verification link emailed to that address, so use a work address — personal domains are rejected — and expect +verification link emailed to that address, so use one you can read right now — work or personal is fine, but +privacy-relay and disposable domains are rejected — and expect one interactive moment on a first install. The server issues **one license per address** and never a second, so `run.sh` is built never to need one: it @@ -72,7 +73,7 @@ Yes. Set `DUPLO_TARGET=remote` with `DUPLO_HOST` and `DUPLO_TOKEN` (an Administr ### What are the prerequisites? -Docker with Compose v2, `python3`, an LLM key, and a work email address you can receive mail at (the license +Docker with Compose v2, `python3`, an LLM key, and an email address you can receive mail at (the license verification link goes there). That is the whole list — building an extension needs nothing extra on your machine, because the build runs in a container. See [Prerequisites](getting-started/prerequisites.md). diff --git a/docs/getting-started/install.md b/docs/getting-started/install.md index b9fd8c5..8500f95 100644 --- a/docs/getting-started/install.md +++ b/docs/getting-started/install.md @@ -3,8 +3,8 @@ **What you'll do:** Clone the dev kit, adopt it as your own repo, bring the platform up with `./run.sh`, verify your email, and sign in. -**What you need first:** [0. Prerequisites](prerequisites.md) — Docker with Compose v2, Python 3, LLM access, and a -work email address you can read right now. +**What you need first:** [0. Prerequisites](prerequisites.md) — Docker with Compose v2, Python 3, LLM access, and an +email address you can read right now. --- @@ -88,7 +88,7 @@ pulls from the official dev-kit URL, whatever you re-point your remote to in the ./run.sh ``` - The first prompt is your admin email. Use the work address from + The first prompt is your admin email. Use the address from [0.4](prerequisites.md#04-an-email-address-you-can-read): it is both your portal login and the address the verification link is sent to. @@ -100,7 +100,7 @@ pulls from the official dev-kit URL, whatever you re-point your remote to in the ## 1.4 Verify your email address -Setup requires a **verified business email address**. `./run.sh` emails you a verification link and +Setup requires a **verified email address** — work or personal. `./run.sh` emails you a verification link and **the run blocks here until you click it** — then it continues on its own. 1. Watch for this, and go read your inbox: diff --git a/docs/getting-started/prerequisites.md b/docs/getting-started/prerequisites.md index e086dc2..3393bc2 100644 --- a/docs/getting-started/prerequisites.md +++ b/docs/getting-started/prerequisites.md @@ -72,8 +72,9 @@ verification link, and the run waits for you to click it before carrying on. So: - **Use an address you can read right now.** The install blocks until that email arrives and you click the link. -- **Use a work address.** Personal domains are not accepted — you get - `Re-run with --email — personal domains are not accepted.` and a chance to retype. +- **Work or personal is fine.** Privacy-relay and disposable domains are not accepted — you get + `Re-run with --email — most work and personal addresses are accepted; privacy-relay and disposable + domains are not.` and a chance to retype. The same address becomes your portal login on the next page. diff --git a/docs/quickstart.md b/docs/quickstart.md index 8a16c06..bffb62a 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -13,7 +13,7 @@ Kubernetes and extension-authoring pages, the full ## 1. Prerequisites You need Docker with Compose v2, `python3` on your `PATH`, an LLM key (an Anthropic `sk-ant-…` key, or AWS credentials with -access to Bedrock), and a **work email address**. +access to Bedrock), and an **email address you can receive mail at**. ```bash docker --version && docker compose version @@ -41,7 +41,7 @@ docker --version && docker compose version ./run.sh ``` - `./run.sh` prompts for `Admin email:` — use the work address. It then **blocks**: DuploCloud emails a + `./run.sh` prompts for `Admin email:` — use an address you can read right now. It then **blocks**: DuploCloud emails a verification link, and the run waits (up to 2 minutes) for you to click it before continuing on its own. If the wait times out nothing is lost — click the link, re-run `./run.sh`, and it resumes the same request without sending a second email. diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 92b89cd..f9fa47b 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -159,8 +159,9 @@ If you already hold the JWT, skip the round trip entirely with `./run.sh --licen ### The license server rejected my email -Personal domains are not accepted. Re-run with a work address — `./run.sh --email you@yourcompany.com`. -A rejected address is not spent, so this is safe to correct. +Work and personal addresses are both accepted; privacy-relay and disposable domains are not. Re-run with a +different address — `./run.sh --email you@example.com`. A rejected address is not spent, so this is safe to +correct. ### The license is for the wrong address diff --git a/hackday/Installing DevKit.md b/hackday/Installing DevKit.md index e7b27e5..19e3fd5 100644 --- a/hackday/Installing DevKit.md +++ b/hackday/Installing DevKit.md @@ -28,7 +28,7 @@ running platform with no restart. You describe what you want in plain language a | **Python 3** on your `PATH` | `run.sh` uses it as its `.env` editor and JSON parser | | **Claude Code** | This is how you build the agent — `/duplo-extension` lives in the repo's `.claude/` | | **An LLM key** | An Anthropic `sk-ant-…` key, **or** AWS credentials with Bedrock access, **or** an Anthropic-compatible gateway (OpenRouter, Bifrost, LiteLLM) | -| **A work email address** | Personal domains (gmail.com, outlook.com, …) are **rejected** — see the callout in step 2 | +| **An email address you can read** | Work or personal both work; privacy-relay and disposable domains are **rejected** — see the callout in step 2 | | **Five free ports** | `4210`, `60031`, `8010`, `27018`, `6061`, plus `6333` for Qdrant | Verify the first two in one line: @@ -63,7 +63,8 @@ extension directory — do it now so your Hack Day work has somewhere to live. > ### ⚠️ The email step will block you — read this first > -> `run.sh` prompts for `Admin email:`. **Use your work address** — personal domains are not accepted. +> `run.sh` prompts for `Admin email:`. **Use an address you can read right now** — work or personal is fine, +> but privacy-relay and disposable domains are not accepted. > > DuploCloud then emails that address a **verification link**, and **the run stops and waits** for you to > click it, for up to 2 minutes. Click it and the run continues on its own. diff --git a/run.sh b/run.sh index 410fab3..dea4e69 100755 --- a/run.sh +++ b/run.sh @@ -224,7 +224,7 @@ license_warn_expiry() { # ISSUED one trial per email — already used. is set when # the server says that trial is recoverable; recover it rather than asking # the user for a JWT they may never have been sent. -# EMAIL email rejected (personal domain, malformed, …) +# EMAIL email rejected (privacy-relay or disposable domain, malformed, …) # ERR anything else, including transport failure license_request() { # email api-url E="$1" U="$2" python3 - <<'PY' @@ -790,12 +790,12 @@ if [ -z "$LIC" ]; then break ;; EMAIL) echo " ✖ $MSG" >&2 - [ "$NONINTERACTIVE" = 1 ] && { echo " Re-run with --email — personal domains are not accepted." >&2; exit 1; } - [ "$TRIES" -ge 3 ] && { echo "Giving up after $TRIES attempts — re-run with --email ." >&2; exit 1; } - read -r -p 'Work email: ' EMAIL || { echo "No work email provided — re-run with --email ." >&2; exit 1; } + [ "$NONINTERACTIVE" = 1 ] && { echo " Re-run with --email — most work and personal addresses are accepted; privacy-relay and disposable domains are not." >&2; exit 1; } + [ "$TRIES" -ge 3 ] && { echo "Giving up after $TRIES attempts — re-run with --email ." >&2; exit 1; } + read -r -p 'Email address: ' EMAIL || { echo "No email provided — re-run with --email ." >&2; exit 1; } while ! email_valid "$EMAIL"; do echo "Invalid email address: '${EMAIL:-}' (expected name@example.com)." >&2 - read -r -p 'Work email: ' EMAIL || { echo "No work email provided — re-run with --email ." >&2; exit 1; } + read -r -p 'Email address: ' EMAIL || { echo "No email provided — re-run with --email ." >&2; exit 1; } done ;; ISSUED) # The address already has a trial. When the server can recover it this is not an error the user has