instar 1.3.413 → 1.3.415

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.
@@ -0,0 +1,58 @@
1
+ # Side-Effects Review — per-account email on the Subscription Pool
2
+
3
+ ## Scope of change
4
+
5
+ - `src/core/SubscriptionPool.ts` — add optional `email` to `SubscriptionAccount`,
6
+ `AddAccountInput`, `UpdateAccountInput`; `add()`/`update()` store/patch it.
7
+ - `src/core/QuotaPoller.ts` — new exported `readAccountEmail(configHome)` (reads the
8
+ PUBLIC `oauthAccount.emailAddress` from the config home's `.claude.json`); `pollAll()`
9
+ auto-populates `account.email` from it on each poll.
10
+ - `src/server/routes.ts` — POST/PATCH `/subscription-pool` pass `email` through.
11
+ - `dashboard/subscriptions.js` + `dashboard/index.html` — render the email under the
12
+ account nickname. Tests (unit + render assertion).
13
+
14
+ ## Why
15
+
16
+ Operator requirement (Justin, topic 20905): accounts must be identified by nickname
17
+ AND email — e.g. "SageMind - Justin" vs "SageMind - Adriana" vs "SageMind - Dawn"
18
+ are the same org, so the email is the disambiguator. The pool previously stored only
19
+ nickname + login location.
20
+
21
+ ## The safety property (load-bearing)
22
+
23
+ The email is **auto-populated from the account's own login record** (`oauthAccount.
24
+ emailAddress` in the config home), not just operator-typed. So the stored email
25
+ always reflects WHICH account actually authenticated under that config home — a
26
+ login into the wrong account *surfaces* (the email won't match the nickname's intent)
27
+ instead of hiding. This directly serves the operator's stated worry about mislabeling
28
+ accounts. The email is a PUBLIC identifier — never a token/secret.
29
+
30
+ ## What does NOT change
31
+
32
+ - Additive-optional everywhere: `email` is optional; existing accounts and existing
33
+ add/update calls (no email) behave exactly as before (`email` stays undefined).
34
+ - No new route, no new authority, no behavior change to selection/swap/poll beyond
35
+ writing one extra public field. The credential-field guard is unaffected (`email`
36
+ is not a forbidden field name).
37
+
38
+ ## Framework generality
39
+
40
+ `readAccountEmail` reads claude-code's `oauthAccount.emailAddress` (the Claude config
41
+ layout), matching the standard's Claude-first scope. The `email` field itself is
42
+ framework-agnostic (any provider's account can carry one); only the auto-populate
43
+ reader is claude-code-specific today. A non-claude account simply gets no auto-filled
44
+ email (operators can still set one via the route) — no behavior regression, and the
45
+ reader extends per-framework when those logins are wired.
46
+
47
+ ## Failure modes considered
48
+
49
+ - Config home has no `.claude.json` / no `oauthAccount` → `readAccountEmail` returns
50
+ null → poll leaves `email` unchanged (no throw).
51
+ - Operator passes `email` at add time → stored as-is; a later poll overwrites it with
52
+ the real logged-in email (reality wins — the safety property).
53
+ - `update({ email: '' })` clears the email (explicit unset).
54
+
55
+ ## Migration / parity
56
+
57
+ Additive-optional field on an existing store — no migration needed (old records load
58
+ with `email` undefined; the next poll fills it). Ships via dist.
@@ -0,0 +1,31 @@
1
+ # Side effects — transcript cleanup-period (cleanupPeriodDays)
2
+
3
+ ## Change
4
+
5
+ Sets `cleanupPeriodDays: 14` in `.claude/settings.json` — for new agents (init.ts) and
6
+ existing agents (`PostUpdateMigrator.migrateSettings()`, set-if-unset).
7
+
8
+ ## Behavioral surface
9
+
10
+ - **New behavior**: Claude Code now prunes chat transcripts under `~/.claude/projects`
11
+ older than 14 days (was the unset default of 30). Caps the per-fleet transcript pile-up.
12
+ - **What does NOT change**: nothing about runtime sessions, hooks, MCP, or the server. This
13
+ is a Claude Code client setting only. Recent transcripts (≤14d) are untouched, so active
14
+ and recently-idle sessions keep full `--resume` support.
15
+
16
+ ## Migration / compatibility
17
+
18
+ - Migration is **set-if-unset** (`settings.cleanupPeriodDays === undefined`) — an operator's
19
+ explicit value (including `0` = no cleanup) is never overwritten. Idempotent.
20
+ - No config-schema change, no API, no state. Reversible by editing settings.json.
21
+
22
+ ## Risk
23
+
24
+ Low. Worst case: a conversation left idle 14–30 days loses its Claude `--resume` transcript;
25
+ instar's CONTINUATION mechanism reconstructs context across such gaps, so the conversation
26
+ still resumes. Tunable up per-agent if any agent needs longer retention.
27
+
28
+ ## Tests
29
+
30
+ `tests/unit/PostUpdateMigrator-cleanupPeriodDays.test.ts` (4/4): set-when-absent, no-override-7,
31
+ respect-explicit-0, idempotent. Adjacent migrateSettings suites green (27/27). `tsc` clean.