# Upgrade Guide — vNEXT

<!-- assembled-by: assemble-next-md -->
<!-- bump: patch -->

## What Changed

The pre-messaging convergence check's `url_provenance` allowlist now trusts
`claude.com` alongside the already-listed `claude.ai`, `anthropic.com`, and
`docs.anthropic.com`. The same domain was added to both copies that must agree:
the primary script (`src/templates/scripts/convergence-check.sh`) and the
can't-find-template fallback in `PostUpdateMigrator.getConvergenceCheckInline()`.
This stops the grounding-before-messaging hook from false-flagging Claude
subscription OAuth login links (which live on `claude.com`) as possibly-fabricated.

The enrollment wizard now attaches an operator-facing heads-up to a pending Claude
login, warning that a brand-new Claude account login asks for TWO codes in sequence
— an email-verification code first, then the sign-in code. `PendingLogin` gains an
optional `notice` field; `EnrollmentWizard.flowNotice(kind)` produces the warning
for the `url-code-paste` (Claude) flow and nothing for `device-code` (Codex); the
dashboard's Pending Logins panel renders it above the code. Codex enrollment is
unchanged.

## What to Tell Your User

When I send you a Claude sign-in link to enroll a subscription account, it now goes
to you directly. Before, my own link-safety check mistook the official claude.com
sign-in page for a possibly-made-up address and made me wrap it in a private page
first — that false alarm is gone.

When I set up a new Claude account for you, the login card now warns you up front
that Claude will ask for two codes in a row — the email-verification code first,
then the sign-in code. No more being surprised by the second prompt.

## Summary of New Capabilities

- **claude.com is a trusted domain** in the pre-messaging link-safety check — Claude
  OAuth login links deliver directly instead of being flagged as unfamiliar.
- Existing agents get it automatically (the updater re-writes the deployed script
  from the template on every update); no separate migration.

- **Two-code heads-up on Claude enrollment** — the pending-login card explains the
  email-code-then-sign-in-code sequence before you start.
- **`PendingLogin.notice`** — an optional, sanitized, operator-facing flow heads-up
  (extensible to other flow quirks later); Codex/device-code flows carry none.
- Ships with the normal instar update (server + dashboard); no migration needed.

## Evidence

Found during live subscription enrollment (topic 20905): driving a fresh Claude
login produces a sign-in URL on `claude.com`, and delivering it tripped the
`URL_PROVENANCE` gate because `claude.com` was absent from the allowlist while its
sibling `claude.ai` was present.

Reproduction — pipe an outbound message containing a `claude.com` link through the
gate:
- **Before:** `echo 'Sign in: https://claude.com/oauth/authorize?code=abc' | bash
  .instar/scripts/convergence-check.sh` → exit 1, output contains `URL_PROVENANCE`
  (so the link had to be wrapped in a private view to be sent).
- **After:** same input → exit 0, no `URL_PROVENANCE` flag.

A sibling test still proves a genuinely fabricated domain (`fabricated-domain.xyz`)
is flagged, so only this one first-party domain was loosened. Locked in by a new
`convergence-check.test.ts` case.

Found during live enrollment (topic 20905): enrolling a fresh Claude account, the
operator was asked for an email-verification code first and then a separate sign-in
code, with nothing explaining the second prompt — reported as confusing.

Reproduction / before-after:
- **Before:** starting a `url-code-paste` enrollment produced a pending login with
  only a code + URL; the two-code sequence was undocumented, so the operator hit an
  unexplained second code prompt.
- **After:** the same enrollment produces a pending login whose `notice` reads
  "a brand-new Claude login often asks for TWO codes in order — first an
  email-verification code … then the sign-in code …", shown on the dashboard card.
  A `device-code` (Codex) enrollment still carries no notice.

Locked in by new `enrollment-wizard.test.ts`, `pending-login-store.test.ts`, and
`subscriptions-render.test.ts` cases (notice present for Claude / absent for Codex;
rendered when present / element omitted when not).
