instar 1.3.400 → 1.3.402
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/index.html +48 -18
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +59 -1
- package/dist/commands/server.js.map +1 -1
- package/dist/core/EnrollmentWizard.d.ts +84 -0
- package/dist/core/EnrollmentWizard.d.ts.map +1 -0
- package/dist/core/EnrollmentWizard.js +107 -0
- package/dist/core/EnrollmentWizard.js.map +1 -0
- package/dist/core/FrameworkLoginDriver.d.ts +85 -0
- package/dist/core/FrameworkLoginDriver.d.ts.map +1 -0
- package/dist/core/FrameworkLoginDriver.js +110 -0
- package/dist/core/FrameworkLoginDriver.js.map +1 -0
- package/dist/core/PendingLoginStore.d.ts +118 -0
- package/dist/core/PendingLoginStore.d.ts.map +1 -0
- package/dist/core/PendingLoginStore.js +201 -0
- package/dist/core/PendingLoginStore.js.map +1 -0
- package/dist/core/types.d.ts +8 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/scaffold/templates.d.ts.map +1 -1
- package/dist/scaffold/templates.js +1 -0
- package/dist/scaffold/templates.js.map +1 -1
- package/dist/server/AgentServer.d.ts +1 -0
- package/dist/server/AgentServer.d.ts.map +1 -1
- package/dist/server/AgentServer.js +1 -0
- package/dist/server/AgentServer.js.map +1 -1
- package/dist/server/routes.d.ts +2 -0
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +59 -0
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +47 -47
- package/src/scaffold/templates.ts +1 -0
- package/upgrades/1.3.401.md +30 -0
- package/upgrades/1.3.402.md +64 -0
- package/upgrades/side-effects/dashboard-stream-phase3-ui.md +58 -0
- package/upgrades/side-effects/subscription-auth-enrollment.md +91 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Side-Effects Review — Mobile-first enrollment wizard (P2.1)
|
|
2
|
+
|
|
3
|
+
## Scope of change
|
|
4
|
+
|
|
5
|
+
- `src/core/PendingLoginStore.ts` (new) — durable ledger of in-flight logins (public artifacts only).
|
|
6
|
+
- `src/core/EnrollmentWizard.ts` (new) — orchestration: start + auto-reissue-on-expiry + complete.
|
|
7
|
+
- `src/core/FrameworkLoginDriver.ts` (new) — concrete LoginDriver: spawn framework login under the account's config home, scrape the public code/URL.
|
|
8
|
+
- `src/server/routes.ts` — RouteContext `enrollmentWizard` + 4 routes under `/subscription-pool`.
|
|
9
|
+
- `src/server/AgentServer.ts` — `enrollmentWizard?` option + private field + RouteContext plumbing.
|
|
10
|
+
- `src/commands/server.ts` — instantiate the store + driver + wizard; pass to AgentServer; background reissue tick (unref'd).
|
|
11
|
+
- tests (unit + integration + e2e) + api.md.
|
|
12
|
+
|
|
13
|
+
## The concern: a wizard that spawns a login process + writes a durable store
|
|
14
|
+
|
|
15
|
+
The new authority here is (a) spawning a framework login command, and (b) writing
|
|
16
|
+
a durable store. The safety design:
|
|
17
|
+
|
|
18
|
+
- **Spawning is injected + scoped.** The interactive leg (driving the login CLI)
|
|
19
|
+
is the injected `LoginDriver`. The concrete `FrameworkLoginDriver` spawns the
|
|
20
|
+
framework's OWN login command under a per-account `CLAUDE_CONFIG_DIR` — it does
|
|
21
|
+
not extract, read, or transmit any credential. The credential is written by the
|
|
22
|
+
framework's own client into that config home; instar only reads the PUBLIC
|
|
23
|
+
artifact (verification URL + short code) the provider prints to be typed into
|
|
24
|
+
its own page.
|
|
25
|
+
- **No secret can enter the store by construction.** `PendingLoginStore`'s record
|
|
26
|
+
type has no token/secret field. There is nothing to smuggle a credential into —
|
|
27
|
+
the same structural guarantee P1.1 enforces for the account registry. The
|
|
28
|
+
integration test asserts no token-like field ever appears in a response body.
|
|
29
|
+
- **Dark + operator/internal.** The routes nest under `/subscription-pool`
|
|
30
|
+
(already INTERNAL, not surfaced in /capabilities until graduation) and do
|
|
31
|
+
nothing until an operator starts an enrollment. No live-session path is touched.
|
|
32
|
+
- **The background tick is inert + bounded.** The reissue sweep only re-drives
|
|
33
|
+
logins that are already EXPIRED; with no pending logins it is a no-op. The timer
|
|
34
|
+
is `unref()`'d so it never holds the process open.
|
|
35
|
+
|
|
36
|
+
## Authority / autonomy analysis
|
|
37
|
+
|
|
38
|
+
- **Tier-2 by association** (spawns a process, writes a store) but ships dark +
|
|
39
|
+
operator-gated. The driving spec (`subscription-auth-p2.1-enrollment.md`) is
|
|
40
|
+
converged + `approved: true` (Justin, Telegram topic 20905, 2026-06-07 — blanket
|
|
41
|
+
approval of the remaining phases under the autonomy directive).
|
|
42
|
+
- **No autonomous credential handling.** The agent never holds a token; the
|
|
43
|
+
operator approves at the provider's own page. The wizard's only autonomy is
|
|
44
|
+
re-issuing an EXPIRED public code — which carries no secret and strands nothing.
|
|
45
|
+
- **Honest failure.** A driver failure during a reissue is logged + the login is
|
|
46
|
+
left expired for the next sweep (no false "reissued" claim); a scrape timeout
|
|
47
|
+
throws and the login is left for the operator (no fabricated artifact).
|
|
48
|
+
|
|
49
|
+
## Failure modes considered
|
|
50
|
+
|
|
51
|
+
- Login code expires before the operator acts → auto-reissued on the next sweep (the headline fix).
|
|
52
|
+
- Driver/scrape failure → logged, login left expired, sweep continues (one bad login can't abort it).
|
|
53
|
+
- Server restart mid-enrollment → the pending login persisted to disk; it reloads and stays on the surface.
|
|
54
|
+
- Wizard unwired (dark) → list/sweep routes answer 200 `{ enabled:false }`, never 503.
|
|
55
|
+
- No pending logins → the background sweep is a no-op; the timer is unref'd.
|
|
56
|
+
|
|
57
|
+
## Blast radius
|
|
58
|
+
|
|
59
|
+
Contained by the dark/operator-gated rollout + the credential-safety-by-construction
|
|
60
|
+
store. With no enrollment started (the default), none of this code executes beyond
|
|
61
|
+
an inert sweep over an empty store. The risk surface is the spawn-+-scrape path,
|
|
62
|
+
exercised only when an operator explicitly starts an enrollment.
|
|
63
|
+
|
|
64
|
+
## Framework generality
|
|
65
|
+
|
|
66
|
+
The wizard is framework-agnostic in shape, framework-specific in effect:
|
|
67
|
+
|
|
68
|
+
- `EnrollmentWizard` + `PendingLoginStore` are fully generic — they carry
|
|
69
|
+
`provider` + `framework` fields and treat the login artifact uniformly. The
|
|
70
|
+
per-provider default flow kind (`defaultKind`) encodes the only branch: Codex/
|
|
71
|
+
OpenAI = device-code (its endorsed flow); everyone else = url-code-paste (the
|
|
72
|
+
phone-friendly Claude path). Adding a framework is a one-line default + a driver
|
|
73
|
+
case, not a structural change.
|
|
74
|
+
- `FrameworkLoginDriver` is where framework specificity lives, and it is honest
|
|
75
|
+
about it: the spawn command + the scrape patterns are per-flow (device-code vs
|
|
76
|
+
url-code-paste), and the pure `parseArtifact` handles both. The two real flows
|
|
77
|
+
(Codex device-code, Claude URL-paste) are implemented; gemini-cli / pi-cli slot
|
|
78
|
+
into the same `framework` union and reuse the same scrape patterns when their
|
|
79
|
+
login flows are wired — no Claude-only assumption is baked into the abstraction.
|
|
80
|
+
- Per the constitution's "Framework-Agnostic — and Framework-Optimizing": the
|
|
81
|
+
store + wizard stay neutral across providers; the optimization (which login flow,
|
|
82
|
+
what to scrape) is per-framework in the driver. This matches the standard's
|
|
83
|
+
Claude-first scope (Justin's decision 3) without foreclosing the others.
|
|
84
|
+
|
|
85
|
+
## Migration / parity
|
|
86
|
+
|
|
87
|
+
All three new classes are additive (new files; the store is created lazily on
|
|
88
|
+
first enrollment). Routes stay under the already-classified `/subscription-pool`
|
|
89
|
+
INTERNAL prefix (no CapabilityIndex change until graduation). An optional
|
|
90
|
+
`subscriptionPool.enrollment` config block tunes TTL/sweep cadence; absent, shipped
|
|
91
|
+
defaults apply. No existing behaviour changes. Ships via dist.
|