instar 1.3.428 → 1.3.429
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dashboard/subscriptions.js +5 -0
- package/dist/core/EnrollmentWizard.d.ts +11 -0
- package/dist/core/EnrollmentWizard.d.ts.map +1 -1
- package/dist/core/EnrollmentWizard.js +19 -0
- package/dist/core/EnrollmentWizard.js.map +1 -1
- package/dist/core/PendingLoginStore.d.ts +6 -0
- package/dist/core/PendingLoginStore.d.ts.map +1 -1
- package/dist/core/PendingLoginStore.js +1 -0
- package/dist/core/PendingLoginStore.js.map +1 -1
- package/dist/core/PostUpdateMigrator.js +1 -1
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +20 -20
- package/src/templates/scripts/convergence-check.sh +1 -1
- package/upgrades/1.3.429.md +81 -0
- package/upgrades/side-effects/claude-com-url-allowlist.md +41 -0
- package/upgrades/side-effects/enroll-two-code-warning.md +42 -0
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "./builtin-manifest.schema.json",
|
|
3
3
|
"schemaVersion": 1,
|
|
4
|
-
"generatedAt": "2026-06-08T06:
|
|
5
|
-
"instarVersion": "1.3.
|
|
4
|
+
"generatedAt": "2026-06-08T06:55:11.189Z",
|
|
5
|
+
"instarVersion": "1.3.429",
|
|
6
6
|
"entryCount": 199,
|
|
7
7
|
"entries": {
|
|
8
8
|
"hook:session-start": {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"domain": "identity",
|
|
12
12
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
13
13
|
"installedPath": ".instar/hooks/instar/session-start.sh",
|
|
14
|
-
"contentHash": "
|
|
14
|
+
"contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
|
|
15
15
|
"since": "2025-01-01"
|
|
16
16
|
},
|
|
17
17
|
"hook:dangerous-command-guard": {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"domain": "safety",
|
|
21
21
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
22
22
|
"installedPath": ".instar/hooks/instar/dangerous-command-guard.sh",
|
|
23
|
-
"contentHash": "
|
|
23
|
+
"contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
|
|
24
24
|
"since": "2025-01-01"
|
|
25
25
|
},
|
|
26
26
|
"hook:grounding-before-messaging": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"domain": "safety",
|
|
30
30
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
31
31
|
"installedPath": ".instar/hooks/instar/grounding-before-messaging.sh",
|
|
32
|
-
"contentHash": "
|
|
32
|
+
"contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
|
|
33
33
|
"since": "2025-01-01"
|
|
34
34
|
},
|
|
35
35
|
"hook:compaction-recovery": {
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"domain": "identity",
|
|
39
39
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
40
40
|
"installedPath": ".instar/hooks/instar/compaction-recovery.sh",
|
|
41
|
-
"contentHash": "
|
|
41
|
+
"contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
|
|
42
42
|
"since": "2025-01-01"
|
|
43
43
|
},
|
|
44
44
|
"hook:external-operation-gate": {
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"domain": "safety",
|
|
48
48
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
49
49
|
"installedPath": ".instar/hooks/instar/external-operation-gate.js",
|
|
50
|
-
"contentHash": "
|
|
50
|
+
"contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
|
|
51
51
|
"since": "2025-01-01"
|
|
52
52
|
},
|
|
53
53
|
"hook:deferral-detector": {
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"domain": "safety",
|
|
57
57
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
58
58
|
"installedPath": ".instar/hooks/instar/deferral-detector.js",
|
|
59
|
-
"contentHash": "
|
|
59
|
+
"contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
|
|
60
60
|
"since": "2025-01-01"
|
|
61
61
|
},
|
|
62
62
|
"hook:self-stop-guard": {
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"domain": "coherence",
|
|
66
66
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
67
67
|
"installedPath": ".instar/hooks/instar/self-stop-guard.js",
|
|
68
|
-
"contentHash": "
|
|
68
|
+
"contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
|
|
69
69
|
"since": "2025-01-01"
|
|
70
70
|
},
|
|
71
71
|
"hook:post-action-reflection": {
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"domain": "evolution",
|
|
75
75
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
76
76
|
"installedPath": ".instar/hooks/instar/post-action-reflection.js",
|
|
77
|
-
"contentHash": "
|
|
77
|
+
"contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
|
|
78
78
|
"since": "2025-01-01"
|
|
79
79
|
},
|
|
80
80
|
"hook:external-communication-guard": {
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
"domain": "safety",
|
|
84
84
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
85
85
|
"installedPath": ".instar/hooks/instar/external-communication-guard.js",
|
|
86
|
-
"contentHash": "
|
|
86
|
+
"contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
|
|
87
87
|
"since": "2025-01-01"
|
|
88
88
|
},
|
|
89
89
|
"hook:scope-coherence-collector": {
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
"domain": "coherence",
|
|
93
93
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
94
94
|
"installedPath": ".instar/hooks/instar/scope-coherence-collector.js",
|
|
95
|
-
"contentHash": "
|
|
95
|
+
"contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
|
|
96
96
|
"since": "2025-01-01"
|
|
97
97
|
},
|
|
98
98
|
"hook:scope-coherence-checkpoint": {
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
"domain": "coherence",
|
|
102
102
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
103
103
|
"installedPath": ".instar/hooks/instar/scope-coherence-checkpoint.js",
|
|
104
|
-
"contentHash": "
|
|
104
|
+
"contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
|
|
105
105
|
"since": "2025-01-01"
|
|
106
106
|
},
|
|
107
107
|
"hook:free-text-guard": {
|
|
@@ -110,7 +110,7 @@
|
|
|
110
110
|
"domain": "safety",
|
|
111
111
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
112
112
|
"installedPath": ".instar/hooks/instar/free-text-guard.sh",
|
|
113
|
-
"contentHash": "
|
|
113
|
+
"contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
|
|
114
114
|
"since": "2025-01-01"
|
|
115
115
|
},
|
|
116
116
|
"hook:claim-intercept": {
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
"domain": "coherence",
|
|
120
120
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
121
121
|
"installedPath": ".instar/hooks/instar/claim-intercept.js",
|
|
122
|
-
"contentHash": "
|
|
122
|
+
"contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
|
|
123
123
|
"since": "2025-01-01"
|
|
124
124
|
},
|
|
125
125
|
"hook:claim-intercept-response": {
|
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
"domain": "coherence",
|
|
129
129
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
130
130
|
"installedPath": ".instar/hooks/instar/claim-intercept-response.js",
|
|
131
|
-
"contentHash": "
|
|
131
|
+
"contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
|
|
132
132
|
"since": "2025-01-01"
|
|
133
133
|
},
|
|
134
134
|
"hook:stop-gate-router": {
|
|
@@ -137,7 +137,7 @@
|
|
|
137
137
|
"domain": "safety",
|
|
138
138
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
139
139
|
"installedPath": ".instar/hooks/instar/stop-gate-router.js",
|
|
140
|
-
"contentHash": "
|
|
140
|
+
"contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
|
|
141
141
|
"since": "2025-01-01"
|
|
142
142
|
},
|
|
143
143
|
"hook:auto-approve-permissions": {
|
|
@@ -146,7 +146,7 @@
|
|
|
146
146
|
"domain": "safety",
|
|
147
147
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
148
148
|
"installedPath": ".instar/hooks/instar/auto-approve-permissions.js",
|
|
149
|
-
"contentHash": "
|
|
149
|
+
"contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
|
|
150
150
|
"since": "2025-01-01"
|
|
151
151
|
},
|
|
152
152
|
"job:health-check": {
|
|
@@ -1122,7 +1122,7 @@
|
|
|
1122
1122
|
"type": "template",
|
|
1123
1123
|
"domain": "operations",
|
|
1124
1124
|
"sourcePath": "src/templates/scripts/convergence-check.sh",
|
|
1125
|
-
"contentHash": "
|
|
1125
|
+
"contentHash": "4c67cf4d7dc23ac21a1b658e8acf3d3f925c1610afab9291d2cff8d48920fc33",
|
|
1126
1126
|
"since": "2025-01-01"
|
|
1127
1127
|
},
|
|
1128
1128
|
"template:emit-session-clock.sh": {
|
|
@@ -1538,7 +1538,7 @@
|
|
|
1538
1538
|
"type": "subsystem",
|
|
1539
1539
|
"domain": "updates",
|
|
1540
1540
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
1541
|
-
"contentHash": "
|
|
1541
|
+
"contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
|
|
1542
1542
|
"since": "2025-01-01"
|
|
1543
1543
|
},
|
|
1544
1544
|
"subsystem:scheduler": {
|
|
@@ -132,7 +132,7 @@ PY
|
|
|
132
132
|
continue
|
|
133
133
|
fi
|
|
134
134
|
# Skip well-known service domains + common agent tunnel domains.
|
|
135
|
-
if echo "$url" | grep -qE '(github\.com|vercel\.app|vercel\.com|netlify\.app|netlify\.com|npmjs\.com|npmjs\.org|cloudflare\.com|google\.com|twitter\.com|x\.com|youtube\.com|reddit\.com|discord\.com|discord\.gg|telegram\.org|t\.me|localhost|127\.0\.0\.1|stackoverflow\.com|developer\.mozilla\.org|docs\.anthropic\.com|anthropic\.com|openai\.com|claude\.ai|notion\.so|linear\.app|fly\.io|render\.com|railway\.app|heroku\.com|amazonaws\.com|azure\.com|gitlab\.com|bitbucket\.org|docker\.com|hub\.docker\.com|pypi\.org|crates\.io|rubygems\.org|pkg\.go\.dev|wikipedia\.org|medium\.com|substack\.com|circle\.so|ghost\.io|telegraph\.ph)'; then
|
|
135
|
+
if echo "$url" | grep -qE '(github\.com|vercel\.app|vercel\.com|netlify\.app|netlify\.com|npmjs\.com|npmjs\.org|cloudflare\.com|google\.com|twitter\.com|x\.com|youtube\.com|reddit\.com|discord\.com|discord\.gg|telegram\.org|t\.me|localhost|127\.0\.0\.1|stackoverflow\.com|developer\.mozilla\.org|docs\.anthropic\.com|anthropic\.com|openai\.com|claude\.ai|claude\.com|notion\.so|linear\.app|fly\.io|render\.com|railway\.app|heroku\.com|amazonaws\.com|azure\.com|gitlab\.com|bitbucket\.org|docker\.com|hub\.docker\.com|pypi\.org|crates\.io|rubygems\.org|pkg\.go\.dev|wikipedia\.org|medium\.com|substack\.com|circle\.so|ghost\.io|telegraph\.ph)'; then
|
|
136
136
|
continue
|
|
137
137
|
fi
|
|
138
138
|
UNFAMILIAR_URLS="$UNFAMILIAR_URLS $url\n"
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Upgrade Guide — vNEXT
|
|
2
|
+
|
|
3
|
+
<!-- assembled-by: assemble-next-md -->
|
|
4
|
+
<!-- bump: patch -->
|
|
5
|
+
|
|
6
|
+
## What Changed
|
|
7
|
+
|
|
8
|
+
The pre-messaging convergence check's `url_provenance` allowlist now trusts
|
|
9
|
+
`claude.com` alongside the already-listed `claude.ai`, `anthropic.com`, and
|
|
10
|
+
`docs.anthropic.com`. The same domain was added to both copies that must agree:
|
|
11
|
+
the primary script (`src/templates/scripts/convergence-check.sh`) and the
|
|
12
|
+
can't-find-template fallback in `PostUpdateMigrator.getConvergenceCheckInline()`.
|
|
13
|
+
This stops the grounding-before-messaging hook from false-flagging Claude
|
|
14
|
+
subscription OAuth login links (which live on `claude.com`) as possibly-fabricated.
|
|
15
|
+
|
|
16
|
+
The enrollment wizard now attaches an operator-facing heads-up to a pending Claude
|
|
17
|
+
login, warning that a brand-new Claude account login asks for TWO codes in sequence
|
|
18
|
+
— an email-verification code first, then the sign-in code. `PendingLogin` gains an
|
|
19
|
+
optional `notice` field; `EnrollmentWizard.flowNotice(kind)` produces the warning
|
|
20
|
+
for the `url-code-paste` (Claude) flow and nothing for `device-code` (Codex); the
|
|
21
|
+
dashboard's Pending Logins panel renders it above the code. Codex enrollment is
|
|
22
|
+
unchanged.
|
|
23
|
+
|
|
24
|
+
## What to Tell Your User
|
|
25
|
+
|
|
26
|
+
When I send you a Claude sign-in link to enroll a subscription account, it now goes
|
|
27
|
+
to you directly. Before, my own link-safety check mistook the official claude.com
|
|
28
|
+
sign-in page for a possibly-made-up address and made me wrap it in a private page
|
|
29
|
+
first — that false alarm is gone.
|
|
30
|
+
|
|
31
|
+
When I set up a new Claude account for you, the login card now warns you up front
|
|
32
|
+
that Claude will ask for two codes in a row — the email-verification code first,
|
|
33
|
+
then the sign-in code. No more being surprised by the second prompt.
|
|
34
|
+
|
|
35
|
+
## Summary of New Capabilities
|
|
36
|
+
|
|
37
|
+
- **claude.com is a trusted domain** in the pre-messaging link-safety check — Claude
|
|
38
|
+
OAuth login links deliver directly instead of being flagged as unfamiliar.
|
|
39
|
+
- Existing agents get it automatically (the updater re-writes the deployed script
|
|
40
|
+
from the template on every update); no separate migration.
|
|
41
|
+
|
|
42
|
+
- **Two-code heads-up on Claude enrollment** — the pending-login card explains the
|
|
43
|
+
email-code-then-sign-in-code sequence before you start.
|
|
44
|
+
- **`PendingLogin.notice`** — an optional, sanitized, operator-facing flow heads-up
|
|
45
|
+
(extensible to other flow quirks later); Codex/device-code flows carry none.
|
|
46
|
+
- Ships with the normal instar update (server + dashboard); no migration needed.
|
|
47
|
+
|
|
48
|
+
## Evidence
|
|
49
|
+
|
|
50
|
+
Found during live subscription enrollment (topic 20905): driving a fresh Claude
|
|
51
|
+
login produces a sign-in URL on `claude.com`, and delivering it tripped the
|
|
52
|
+
`URL_PROVENANCE` gate because `claude.com` was absent from the allowlist while its
|
|
53
|
+
sibling `claude.ai` was present.
|
|
54
|
+
|
|
55
|
+
Reproduction — pipe an outbound message containing a `claude.com` link through the
|
|
56
|
+
gate:
|
|
57
|
+
- **Before:** `echo 'Sign in: https://claude.com/oauth/authorize?code=abc' | bash
|
|
58
|
+
.instar/scripts/convergence-check.sh` → exit 1, output contains `URL_PROVENANCE`
|
|
59
|
+
(so the link had to be wrapped in a private view to be sent).
|
|
60
|
+
- **After:** same input → exit 0, no `URL_PROVENANCE` flag.
|
|
61
|
+
|
|
62
|
+
A sibling test still proves a genuinely fabricated domain (`fabricated-domain.xyz`)
|
|
63
|
+
is flagged, so only this one first-party domain was loosened. Locked in by a new
|
|
64
|
+
`convergence-check.test.ts` case.
|
|
65
|
+
|
|
66
|
+
Found during live enrollment (topic 20905): enrolling a fresh Claude account, the
|
|
67
|
+
operator was asked for an email-verification code first and then a separate sign-in
|
|
68
|
+
code, with nothing explaining the second prompt — reported as confusing.
|
|
69
|
+
|
|
70
|
+
Reproduction / before-after:
|
|
71
|
+
- **Before:** starting a `url-code-paste` enrollment produced a pending login with
|
|
72
|
+
only a code + URL; the two-code sequence was undocumented, so the operator hit an
|
|
73
|
+
unexplained second code prompt.
|
|
74
|
+
- **After:** the same enrollment produces a pending login whose `notice` reads
|
|
75
|
+
"a brand-new Claude login often asks for TWO codes in order — first an
|
|
76
|
+
email-verification code … then the sign-in code …", shown on the dashboard card.
|
|
77
|
+
A `device-code` (Codex) enrollment still carries no notice.
|
|
78
|
+
|
|
79
|
+
Locked in by new `enrollment-wizard.test.ts`, `pending-login-store.test.ts`, and
|
|
80
|
+
`subscriptions-render.test.ts` cases (notice present for Claude / absent for Codex;
|
|
81
|
+
rendered when present / element omitted when not).
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Side-effects review — claude.com in the URL-provenance allowlist
|
|
2
|
+
|
|
3
|
+
## Change
|
|
4
|
+
|
|
5
|
+
Adds `claude.com` to the `url_provenance` allowlist of the pre-messaging
|
|
6
|
+
convergence check, in BOTH copies that must stay in sync:
|
|
7
|
+
- `src/templates/scripts/convergence-check.sh` (the primary script, read at runtime)
|
|
8
|
+
- `src/core/PostUpdateMigrator.ts` → `getConvergenceCheckInline()` (the fallback
|
|
9
|
+
emitted only when the template file can't be found)
|
|
10
|
+
|
|
11
|
+
It sits next to the already-present `claude.ai` and `anthropic.com` entries.
|
|
12
|
+
|
|
13
|
+
## Why
|
|
14
|
+
|
|
15
|
+
The Claude subscription OAuth login link lives on `claude.com` (Anthropic
|
|
16
|
+
consolidated the sign-in surface there; `claude.ai` is the sibling already on the
|
|
17
|
+
list). During live enrollment testing (topic 20905) the grounding-before-messaging
|
|
18
|
+
hook false-flagged the login link as `URL_PROVENANCE` (a possibly-fabricated
|
|
19
|
+
domain), which forced wrapping every OAuth link in a private view before it could
|
|
20
|
+
be sent to the operator. Allowlisting `claude.com` lets enrollment links be
|
|
21
|
+
delivered directly.
|
|
22
|
+
|
|
23
|
+
## Side effects considered
|
|
24
|
+
|
|
25
|
+
- **Weakens the provenance gate for claude.com?** Marginally and acceptably:
|
|
26
|
+
`claude.com` is Anthropic's official first-party domain (same trust class as the
|
|
27
|
+
already-listed `claude.ai`, `anthropic.com`, `docs.anthropic.com`). The allowlist
|
|
28
|
+
exists precisely to stop second-guessing well-known service domains. The gate
|
|
29
|
+
still flags every genuinely unfamiliar/fabricated domain — the regression test
|
|
30
|
+
keeps `fabricated-domain.xyz` flagged.
|
|
31
|
+
- **Drift between the two copies.** Both are edited identically in this change. The
|
|
32
|
+
template is authoritative; the inline is a can't-find-template fallback. No new
|
|
33
|
+
divergence introduced.
|
|
34
|
+
- **Migration parity.** Existing agents receive the updated allowlist because
|
|
35
|
+
`PostUpdateMigrator` re-writes `.instar/scripts/convergence-check.sh` from the
|
|
36
|
+
template on every update run (built-in script, always overwritten) — no separate
|
|
37
|
+
migration needed; the edit to the template IS the migration path.
|
|
38
|
+
- **No API, config, schema, or route surface touched.** Behavior-only change to a
|
|
39
|
+
heuristic gate. No new dependencies. Idempotent.
|
|
40
|
+
- **Blast radius:** one extra alternation in one regex, in two places. Reversible
|
|
41
|
+
by removing the `claude\.com` token.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Side-effects review — enrollment two-code heads-up
|
|
2
|
+
|
|
3
|
+
## Change
|
|
4
|
+
|
|
5
|
+
Surfaces an operator-facing heads-up on a pending login about the Claude
|
|
6
|
+
url-code-paste flow's two-code sequence (email-verification code first, then the
|
|
7
|
+
sign-in code). Three pieces:
|
|
8
|
+
- `PendingLoginStore`: new optional `notice?: string` on `PendingLogin` +
|
|
9
|
+
`IssueLoginInput`; `issue()` persists it when present (omitted otherwise).
|
|
10
|
+
- `EnrollmentWizard`: new `static flowNotice(kind)` returns the two-code warning
|
|
11
|
+
for `url-code-paste` and `undefined` for `device-code`; `start()` attaches it.
|
|
12
|
+
- `dashboard/subscriptions.js`: `renderPendingLogins` shows a `sub-pending-notice`
|
|
13
|
+
row (sanitized text) when a notice is present.
|
|
14
|
+
|
|
15
|
+
## Why
|
|
16
|
+
|
|
17
|
+
Live enrollment testing (topic 20905): enrolling a fresh Claude account makes
|
|
18
|
+
Anthropic ask for TWO codes in sequence — an email-verification code, then the
|
|
19
|
+
sign-in code — and the operator found the unexplained second prompt confusing. The
|
|
20
|
+
wizard now tells them what to expect up front.
|
|
21
|
+
|
|
22
|
+
## Side effects considered
|
|
23
|
+
|
|
24
|
+
- **Backward compatibility / persistence.** `notice` is optional and omitted when
|
|
25
|
+
absent, so existing pending-login JSON records (written before this change) load
|
|
26
|
+
unchanged — no migration. `issue()` only adds the key when a non-empty notice is
|
|
27
|
+
passed, matching the file's existing `...(x ? {x} : {})` style.
|
|
28
|
+
- **Not a secret.** The notice is static guidance text — never a credential, code,
|
|
29
|
+
or URL. It passes the store's `assertNoCredentialFields` (it's a fixed string set
|
|
30
|
+
by the wizard, not derived from login input).
|
|
31
|
+
- **XSS / display safety.** Rendered through the existing `sanitizeForDisplay`
|
|
32
|
+
(NFKC + control/bidi strip + grapheme cap) as inert text in a `div` — never an
|
|
33
|
+
href or innerHTML. Covered by the render tests (notice present → shown; absent →
|
|
34
|
+
element omitted) alongside the existing javascript:-URL inertness test.
|
|
35
|
+
- **device-code (Codex) flows are unchanged** — `flowNotice('device-code')` is
|
|
36
|
+
undefined, so no notice is attached and the row renders exactly as before.
|
|
37
|
+
- **Reach to existing agents.** Server code (PendingLoginStore/EnrollmentWizard)
|
|
38
|
+
and the dashboard asset ship with the instar package, so agents get this on the
|
|
39
|
+
normal package update — no `.instar/`-copied file and no PostUpdateMigrator entry
|
|
40
|
+
required.
|
|
41
|
+
- **Blast radius:** one optional field + one pure static method + one conditional
|
|
42
|
+
render row. Reversible by dropping the field.
|