instar 1.3.609 → 1.3.610
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/dist/core/QuotaAwareScheduler.d.ts +4 -2
- package/dist/core/QuotaAwareScheduler.d.ts.map +1 -1
- package/dist/core/QuotaAwareScheduler.js +7 -8
- package/dist/core/QuotaAwareScheduler.js.map +1 -1
- package/dist/core/SubscriptionPool.d.ts +20 -0
- package/dist/core/SubscriptionPool.d.ts.map +1 -1
- package/dist/core/SubscriptionPool.js +26 -0
- package/dist/core/SubscriptionPool.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +2 -2
- package/upgrades/1.3.610.md +24 -0
- package/upgrades/side-effects/ws52-account-follow-me-locally-executable.md +69 -0
|
@@ -57,9 +57,11 @@ export declare function selectAccount(accounts: SubscriptionAccount[], opts?: Se
|
|
|
57
57
|
* "accepted as marginal" with real evidence that it materially under-delivered.)
|
|
58
58
|
*
|
|
59
59
|
* Crucially it shares the EXACT eligibility predicate `selectAccount` uses
|
|
60
|
-
* (`
|
|
60
|
+
* (`isLocallyExecutable` + binding utilization below the soft threshold), so
|
|
61
61
|
* `placeable` here ⟺ `selectAccount(...) !== null` — the never-loop invariant
|
|
62
|
-
* holds (the throttle never allows when placement can place nothing).
|
|
62
|
+
* holds (the throttle never allows when placement can place nothing). A
|
|
63
|
+
* credential-less meta account (WS5.2 §6.2) is excluded from BOTH by the shared
|
|
64
|
+
* predicate, so the invariant is preserved. Percentages
|
|
63
65
|
* are clamped to [0,100]; `degraded:true` when the best account has no trustworthy
|
|
64
66
|
* live reading, so the throttle applies its bounded degraded cap instead of a
|
|
65
67
|
* phantom "0% fresh".
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QuotaAwareScheduler.d.ts","sourceRoot":"","sources":["../../src/core/QuotaAwareScheduler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EACV,mBAAmB,EAEpB,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"QuotaAwareScheduler.d.ts","sourceRoot":"","sources":["../../src/core/QuotaAwareScheduler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EACV,mBAAmB,EAEpB,MAAM,uBAAuB,CAAC;AAG/B,iFAAiF;AACjF,MAAM,WAAW,gBAAgB;IAC/B;sFACkF;IAClF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAiCD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,mBAAmB,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAU1E;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,mBAAmB,EAAE,EAC/B,IAAI,GAAE,gBAAqB,EAC3B,SAAS,CAAC,EAAE,MAAM,GACjB,mBAAmB,GAAG,IAAI,CAa5B;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,mBAAmB,EAAE,EAC/B,IAAI,GAAE,gBAAqB,GAC1B;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAkBzG;AAED,iFAAiF;AACjF,wBAAgB,iBAAiB,CAC/B,CAAC,EAAE,mBAAmB,EACtB,gBAAgB,SAAyB,GACxC,OAAO,CAET;AAID,2EAA2E;AAC3E,MAAM,MAAM,SAAS,GAAG,CAAC,IAAI,EAAE;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,0EAA0E;IAC1E,UAAU,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,SAAS,EAAE,MAAM,CAAC;CACnB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAEvB,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,wEAAwE;IACxE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,yBAAyB;IACxC,kEAAkE;IAClE,YAAY,EAAE,MAAM,mBAAmB,EAAE,CAAC;IAC1C,+EAA+E;IAC/E,SAAS,EAAE,SAAS,CAAC;IACrB,+EAA+E;IAC/E,aAAa,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE;QAAE,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;QAAC,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,CAAC;CAClE;AAED,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA4B;gBACpC,GAAG,EAAE,yBAAyB;IAI1C,qEAAqE;IACrE,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI;IAO1D;;;;;;OAMG;IACG,eAAe,CAAC,IAAI,EAAE;QAC1B,WAAW,EAAE,MAAM,CAAC;QACpB,kBAAkB,EAAE,MAAM,CAAC;QAC3B,KAAK,EAAE,MAAM,CAAC;KACf,GAAG,OAAO,CAAC,UAAU,CAAC;CA+BxB"}
|
|
@@ -22,11 +22,8 @@
|
|
|
22
22
|
* hermetically testable (no session lifecycle, no network). The orchestration
|
|
23
23
|
* that actually restarts a session is injected (`refreshFn`) so tests stay pure.
|
|
24
24
|
*/
|
|
25
|
+
import { isLocallyExecutable } from './SubscriptionPool.js';
|
|
25
26
|
const DEFAULT_SOFT_THRESHOLD = 90;
|
|
26
|
-
/** An account is selectable only in these statuses. */
|
|
27
|
-
function isEligibleStatus(a) {
|
|
28
|
-
return a.status === 'active' || a.status === 'warming';
|
|
29
|
-
}
|
|
30
27
|
/**
|
|
31
28
|
* Most-constrained-window utilization: the MAX across the account's known
|
|
32
29
|
* windows (5-hour AND weekly). Taking the max means EITHER window crossing the
|
|
@@ -85,7 +82,7 @@ export function scoreAccount(a, nowMs) {
|
|
|
85
82
|
export function selectAccount(accounts, opts = {}, excludeId) {
|
|
86
83
|
const soft = opts.softThresholdPct ?? DEFAULT_SOFT_THRESHOLD;
|
|
87
84
|
const nowMs = opts.nowMs ?? Date.parse('2026-01-01T00:00:00Z'); // tests pass nowMs; prod callers always set it
|
|
88
|
-
const eligible = accounts.filter((a) =>
|
|
85
|
+
const eligible = accounts.filter((a) => isLocallyExecutable(a) &&
|
|
89
86
|
a.id !== excludeId &&
|
|
90
87
|
bindingUtilization(a.lastQuota) < soft);
|
|
91
88
|
if (eligible.length === 0)
|
|
@@ -106,16 +103,18 @@ export function selectAccount(accounts, opts = {}, excludeId) {
|
|
|
106
103
|
* "accepted as marginal" with real evidence that it materially under-delivered.)
|
|
107
104
|
*
|
|
108
105
|
* Crucially it shares the EXACT eligibility predicate `selectAccount` uses
|
|
109
|
-
* (`
|
|
106
|
+
* (`isLocallyExecutable` + binding utilization below the soft threshold), so
|
|
110
107
|
* `placeable` here ⟺ `selectAccount(...) !== null` — the never-loop invariant
|
|
111
|
-
* holds (the throttle never allows when placement can place nothing).
|
|
108
|
+
* holds (the throttle never allows when placement can place nothing). A
|
|
109
|
+
* credential-less meta account (WS5.2 §6.2) is excluded from BOTH by the shared
|
|
110
|
+
* predicate, so the invariant is preserved. Percentages
|
|
112
111
|
* are clamped to [0,100]; `degraded:true` when the best account has no trustworthy
|
|
113
112
|
* live reading, so the throttle applies its bounded degraded cap instead of a
|
|
114
113
|
* phantom "0% fresh".
|
|
115
114
|
*/
|
|
116
115
|
export function poolHeadroom(accounts, opts = {}) {
|
|
117
116
|
const soft = opts.softThresholdPct ?? DEFAULT_SOFT_THRESHOLD;
|
|
118
|
-
const eligible = accounts.filter((a) =>
|
|
117
|
+
const eligible = accounts.filter((a) => isLocallyExecutable(a) && bindingUtilization(a.lastQuota) < soft);
|
|
119
118
|
if (eligible.length === 0) {
|
|
120
119
|
return { placeable: false, weeklyPercent: null, fiveHourPercent: null, degraded: false };
|
|
121
120
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QuotaAwareScheduler.js","sourceRoot":"","sources":["../../src/core/QuotaAwareScheduler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;
|
|
1
|
+
{"version":3,"file":"QuotaAwareScheduler.js","sourceRoot":"","sources":["../../src/core/QuotaAwareScheduler.ts"],"names":[],"mappings":"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"}
|
|
@@ -110,6 +110,20 @@ export interface SubscriptionAccount {
|
|
|
110
110
|
/** Monotonic version for optimistic CAS in update(). */
|
|
111
111
|
version: number;
|
|
112
112
|
}
|
|
113
|
+
/**
|
|
114
|
+
* WS5.2 §6.2 — "locally executable" predicate. An account is executable on THIS
|
|
115
|
+
* machine iff this machine holds it with a real local `configHome` AND a valid
|
|
116
|
+
* login (status active/warming, never needs-reauth/disabled/rate-limited). A
|
|
117
|
+
* meta-only account replicated in from a peer (no local credential, empty
|
|
118
|
+
* `configHome`) is NOT locally executable and must be invisible to every
|
|
119
|
+
* account-selection / swap-target / placement path — closing the force-mode
|
|
120
|
+
* "use an account I have metadata for but no credential" hole at SELECTION time.
|
|
121
|
+
*
|
|
122
|
+
* This is a pure tightening: every real pool account today carries a non-empty
|
|
123
|
+
* `configHome` (required by `add()`), so this only ever excludes a credential-less
|
|
124
|
+
* meta projection — it never changes selection among genuinely-held accounts.
|
|
125
|
+
*/
|
|
126
|
+
export declare function isLocallyExecutable(a: SubscriptionAccount): boolean;
|
|
113
127
|
export interface SubscriptionPoolConfig {
|
|
114
128
|
/** Agent stateDir (e.g. `.instar`). The store lives at <stateDir>/subscription-pool.json. */
|
|
115
129
|
stateDir: string;
|
|
@@ -156,6 +170,12 @@ export declare class SubscriptionPool {
|
|
|
156
170
|
list(): SubscriptionAccount[];
|
|
157
171
|
/** One account by id, or null. */
|
|
158
172
|
get(id: string): SubscriptionAccount | null;
|
|
173
|
+
/**
|
|
174
|
+
* WS5.2 §6.2 — accounts THIS machine can actually execute against (real local
|
|
175
|
+
* `configHome` + a valid login). The canonical selectable set for the router and
|
|
176
|
+
* every swap/placement path; a credential-less meta projection is excluded.
|
|
177
|
+
*/
|
|
178
|
+
locallyExecutable(): SubscriptionAccount[];
|
|
159
179
|
/** Count of accounts. A pool of 0 is the dark/no-op default. */
|
|
160
180
|
size(): number;
|
|
161
181
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SubscriptionPool.d.ts","sourceRoot":"","sources":["../../src/core/SubscriptionPool.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SubscriptionPool.d.ts","sourceRoot":"","sources":["../../src/core/SubscriptionPool.ts"],"names":[],"mappings":"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"}
|
|
@@ -36,6 +36,24 @@
|
|
|
36
36
|
*/
|
|
37
37
|
import fs from 'node:fs';
|
|
38
38
|
import path from 'node:path';
|
|
39
|
+
/**
|
|
40
|
+
* WS5.2 §6.2 — "locally executable" predicate. An account is executable on THIS
|
|
41
|
+
* machine iff this machine holds it with a real local `configHome` AND a valid
|
|
42
|
+
* login (status active/warming, never needs-reauth/disabled/rate-limited). A
|
|
43
|
+
* meta-only account replicated in from a peer (no local credential, empty
|
|
44
|
+
* `configHome`) is NOT locally executable and must be invisible to every
|
|
45
|
+
* account-selection / swap-target / placement path — closing the force-mode
|
|
46
|
+
* "use an account I have metadata for but no credential" hole at SELECTION time.
|
|
47
|
+
*
|
|
48
|
+
* This is a pure tightening: every real pool account today carries a non-empty
|
|
49
|
+
* `configHome` (required by `add()`), so this only ever excludes a credential-less
|
|
50
|
+
* meta projection — it never changes selection among genuinely-held accounts.
|
|
51
|
+
*/
|
|
52
|
+
export function isLocallyExecutable(a) {
|
|
53
|
+
return (typeof a.configHome === 'string' &&
|
|
54
|
+
a.configHome.trim().length > 0 &&
|
|
55
|
+
(a.status === 'active' || a.status === 'warming'));
|
|
56
|
+
}
|
|
39
57
|
const ID_RE = /^[a-z0-9-]+$/;
|
|
40
58
|
const PROVIDERS = [
|
|
41
59
|
'anthropic',
|
|
@@ -108,6 +126,14 @@ export class SubscriptionPool {
|
|
|
108
126
|
const found = this.store.accounts.find((a) => a.id === id);
|
|
109
127
|
return found ? { ...found } : null;
|
|
110
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* WS5.2 §6.2 — accounts THIS machine can actually execute against (real local
|
|
131
|
+
* `configHome` + a valid login). The canonical selectable set for the router and
|
|
132
|
+
* every swap/placement path; a credential-less meta projection is excluded.
|
|
133
|
+
*/
|
|
134
|
+
locallyExecutable() {
|
|
135
|
+
return this.store.accounts.filter(isLocallyExecutable).map((a) => ({ ...a }));
|
|
136
|
+
}
|
|
111
137
|
/** Count of accounts. A pool of 0 is the dark/no-op default. */
|
|
112
138
|
size() {
|
|
113
139
|
return this.store.accounts.length;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SubscriptionPool.js","sourceRoot":"","sources":["../../src/core/SubscriptionPool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"SubscriptionPool.js","sourceRoot":"","sources":["../../src/core/SubscriptionPool.ts"],"names":[],"mappings":"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"}
|
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-17T11:
|
|
5
|
-
"instarVersion": "1.3.
|
|
4
|
+
"generatedAt": "2026-06-17T11:44:29.710Z",
|
|
5
|
+
"instarVersion": "1.3.610",
|
|
6
6
|
"entryCount": 201,
|
|
7
7
|
"entries": {
|
|
8
8
|
"hook:session-start": {
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Upgrade Guide — vNEXT
|
|
2
|
+
|
|
3
|
+
<!-- assembled-by: assemble-next-md -->
|
|
4
|
+
<!-- bump: patch -->
|
|
5
|
+
|
|
6
|
+
## What Changed
|
|
7
|
+
|
|
8
|
+
WS5.2 Account Follow-Me, §6.2 — the `locallyExecutable` account-selection gate. A new shared predicate `isLocallyExecutable(account)` (an account is executable on THIS machine iff it holds a real local `configHome` AND a valid login — active/warming) now gates account selection at its chokepoint: both `QuotaAwareScheduler.selectAccount()` (placement + swap-target selection) and `poolHeadroom()` (the quota throttle) filter on it, preserving the documented never-loop invariant `placeable ⟺ selectAccount(...) !== null`. A credential-less meta-only account replicated in from a peer (empty `configHome`) is now structurally unselectable — closing the force-mode "use an account I have metadata for but no credential" hole at SELECTION time. Adds `SubscriptionPool.locallyExecutable()` as the canonical machine-executable account set.
|
|
9
|
+
|
|
10
|
+
This is a pure tightening: every real pool account already carries a non-empty `configHome` (required by `add()`), so among genuinely-held accounts the predicate is a no-op — it only ever excludes a credential-less peer projection. The structural guard that lets the later enrollment-execution PRs add accounts without any path ever selecting a peer's credential-less account.
|
|
11
|
+
|
|
12
|
+
## What to Tell Your User
|
|
13
|
+
|
|
14
|
+
Nothing to do — this is an internal selection-safety guard, shipped off by default as part of the multi-machine account-sharing groundwork. It guarantees this machine can only ever pick an account it actually holds a login for, never a peer's account it merely knows about. No user-facing surface in this release.
|
|
15
|
+
|
|
16
|
+
## Summary of New Capabilities
|
|
17
|
+
|
|
18
|
+
Internal: a `locallyExecutable` account-selection gate so a credential-less peer account projection can never be selected for execution, placement, or swap on this machine. Defense-in-depth groundwork for the WS5.2 enrollment-execution path. No user-facing surface.
|
|
19
|
+
|
|
20
|
+
## Evidence
|
|
21
|
+
|
|
22
|
+
- 9 unit tests (`tests/unit/account-follow-me-locally-executable.test.ts`): both boundary sides (executable active/warming + real configHome; non-executable empty/whitespace configHome, needs-reauth/disabled/rate-limited), selectAccount exclusion of a meta-only account, real-over-meta preference, no-regression for held accounts, and explicit never-loop-invariant agreement (`poolHeadroom.placeable ⟺ selectAccount !== null`) for meta-only and real cases. `tsc --noEmit` clean.
|
|
23
|
+
- Side-effects review + mandatory independent second-pass security review (concurred): verified the never-loop invariant is preserved by the shared predicate, the change is a true no-op for current accounts, zero dangling references, no missed selection path, fail-closed (no fail-open). Artifact: `upgrades/side-effects/ws52-account-follow-me-locally-executable.md`.
|
|
24
|
+
- Spec: `docs/specs/ws52-account-follow-me-security.md` §6.2 + §6.3a (converged, approved).
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Side-Effects Review — WS5.2 §6.2 `locallyExecutable` selection gate
|
|
2
|
+
|
|
3
|
+
**Version / slug:** `ws52-account-follow-me-locally-executable`
|
|
4
|
+
**Date:** `2026-06-17`
|
|
5
|
+
**Author:** `Echo (instar-dev agent)`
|
|
6
|
+
**Second-pass reviewer:** `pending (high-risk: account selection / credential boundary)`
|
|
7
|
+
|
|
8
|
+
## Summary of the change
|
|
9
|
+
|
|
10
|
+
WS5.2 §6.2. Adds a single shared predicate `isLocallyExecutable(account)` (exported from `src/core/SubscriptionPool.ts`) — an account is executable on THIS machine iff it carries a real local `configHome` AND a valid login (status `active`/`warming`). A meta-only account replicated in from a peer (credential-less, empty `configHome`) is NOT locally executable. The predicate is applied at the account-selection chokepoint in `src/core/QuotaAwareScheduler.ts` — in BOTH `selectAccount()` (the placement/swap selector, used by `ProactiveSwapMonitor` + `onQuotaPressure`/`SessionMigrator`) AND `poolHeadroom()` (the quota-throttle), which MUST share the exact eligibility predicate to preserve the documented never-loop invariant `placeable ⟺ selectAccount(...) !== null`. A `SubscriptionPool.locallyExecutable()` convenience method returns the filtered selectable set. Files: `SubscriptionPool.ts`, `QuotaAwareScheduler.ts`, plus `tests/unit/account-follow-me-locally-executable.test.ts`.
|
|
11
|
+
|
|
12
|
+
## Decision-point inventory
|
|
13
|
+
|
|
14
|
+
- `QuotaAwareScheduler.selectAccount()` eligibility filter — **modify** — tightened from status-only (`isEligibleStatus`) to `isLocallyExecutable` (status + non-empty configHome). A credential-less account is now unselectable.
|
|
15
|
+
- `QuotaAwareScheduler.poolHeadroom()` eligibility filter — **modify** — tightened identically, preserving `placeable ⟺ selectAccount !== null`.
|
|
16
|
+
- `SubscriptionPool.locallyExecutable()` — **add** — canonical read of the machine-executable account set.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 1. Over-block
|
|
21
|
+
|
|
22
|
+
**What legitimate inputs does this change reject that it shouldn't?**
|
|
23
|
+
|
|
24
|
+
None. Every genuinely-held pool account carries a non-empty `configHome` (required by `SubscriptionPool.add()`, which trims and validates it), so among real accounts this predicate is a pure no-op — it returns exactly what `isEligibleStatus` returned before. It only ever excludes an account with an empty/whitespace `configHome`, which by construction has no local credential and therefore cannot spawn a session. There is no legitimate "selectable account with no configHome" today.
|
|
25
|
+
|
|
26
|
+
## 2. Under-block
|
|
27
|
+
|
|
28
|
+
**What failure modes does this still miss?**
|
|
29
|
+
|
|
30
|
+
It gates SELECTION, not execution-time credential validity. An account that has a `configHome` and `active` status but whose on-disk token is stale/revoked still passes the predicate (the swap/refresh machinery + provider-side 401 handling owns that case — out of scope for §6.2). It also does not inspect token contents; a corrupted credential file at a valid `configHome` is caught downstream, not here. This is intentional: §6.2's job is "never select an account we hold no credential for," not "verify the credential works."
|
|
31
|
+
|
|
32
|
+
## 3. Level-of-abstraction fit
|
|
33
|
+
|
|
34
|
+
Correct layer. Account selection is exactly where "can this machine run this account?" must be decided — the predicate lives next to the `SubscriptionAccount` type (its canonical home) and is applied at the two selectors that gate placement. A higher layer (the router) does not select accounts (it routes SDK-vs-pool *path*, then the interactive pool runs whatever account the session was placed under); a lower layer (the credential store) does not know about selection. The shared-predicate design avoids the classic split-brain where two selectors drift.
|
|
35
|
+
|
|
36
|
+
## 4. Signal vs authority compliance
|
|
37
|
+
|
|
38
|
+
This is a **filter on a selection set**, not a brittle check with blocking authority over messages/actions. It is deterministic (a field-presence + status check), not heuristic — so it does not fall under the signal-vs-authority concern about brittle blocking logic. It cannot mis-fire on ambiguous input: `configHome` is either a non-empty string or not. It never blocks a user message or an outbound action; it only narrows which accounts a placement/swap may pick. Reference: `docs/signal-vs-authority.md` — a deterministic capability gate (can this machine physically execute this account) is authority appropriately exercised, not a brittle heuristic.
|
|
39
|
+
|
|
40
|
+
## 5. Interactions
|
|
41
|
+
|
|
42
|
+
The one real interaction is the **never-loop invariant** between `selectAccount` and `poolHeadroom`: the throttle's comment guarantees `placeable ⟺ selectAccount(...) !== null`. Tightening only one selector would break it (throttle says "go" while placement returns null → spin). Both are tightened with the SAME predicate, and a unit test asserts the two agree on a meta-only account. No other selector consumes these. `ProactiveSwapMonitor`/`SessionMigrator`/`onQuotaPressure` reach selection THROUGH `selectAccount`, so they inherit the gate for free. `PlacementExecutor` (cross-machine placement) does not select an account, so it is unaffected.
|
|
43
|
+
|
|
44
|
+
## 6. External surfaces
|
|
45
|
+
|
|
46
|
+
No new route, no new config, no user-facing surface. `SubscriptionPool.locallyExecutable()` is a new read method but no route exposes it in this change. Behavior visible to other agents/users is unchanged because the predicate is a no-op for all real accounts today (all have configHomes). It does not depend on timing or runtime conditions.
|
|
47
|
+
|
|
48
|
+
## 7. Multi-machine posture (Cross-Machine Coherence)
|
|
49
|
+
|
|
50
|
+
**Machine-local BY DESIGN.** This is the precise point of the change: a `configHome` is a per-machine credential location, so "locally executable" is inherently a per-machine question. The predicate deliberately treats a peer's account (which would arrive as a credential-less meta projection if/when a future scope=pool selection merges peer accounts into a local selection list) as NON-executable here. There is no replication or proxy-on-read surface — by design, each machine answers "which accounts can I run?" from its OWN configHome-bearing accounts. This is the structural guard that lets the later enrollment-execution PRs safely add accounts without any path ever selecting a peer's credential-less account.
|
|
51
|
+
|
|
52
|
+
## 8. Rollback cost
|
|
53
|
+
|
|
54
|
+
Trivial. Pure code change, no migration, no persisted state, no config. Revert is a single-commit back-out; because the predicate is a no-op for all current accounts, reverting changes nothing observable today. No agent state repair, no data migration.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Second-pass review
|
|
59
|
+
|
|
60
|
+
**Concur with the review.** Verified independently against the actual code, spec §6.2/§6.3a, build, and tests:
|
|
61
|
+
|
|
62
|
+
1. **Never-loop invariant preserved** — `selectAccount` (`QuotaAwareScheduler.ts:103-108`) and `poolHeadroom` (`:141-143`) use the byte-identical eligibility predicate `isLocallyExecutable(a) && bindingUtilization(a.lastQuota) < soft`. `selectAccount`'s extra `a.id !== excludeId` is a pure narrowing on the swap path; the throttle calls `poolHeadroom` without an exclude, so `placeable ⟺ selectAccount(...) !== null` holds.
|
|
63
|
+
2. **True no-op for current accounts** — `add()` (`SubscriptionPool.ts:308-309`) and `update()` (`:356-359`) both trim and reject empty `configHome`; no real account can have one. For real accounts `isLocallyExecutable` reduces to the old `active/warming` status check — exact behavioral parity.
|
|
64
|
+
3. **Zero dangling `isEligibleStatus`** — grep across `src/` + `tests/` returns nothing; `tsc --noEmit` EXIT=0.
|
|
65
|
+
4. **No missed selection path** — all `selectAccount`/`poolHeadroom` callers (`ProactiveSwapMonitor:226` swap-target, `server.ts:14343` spawn-resolver, `onQuotaPressure`, QuotaTracker throttle) route through the gated selectors. `AnthropicSubscriptionRouter` routes SDK-vs-pool *paths*, not accounts; `InteractivePoolIntelligenceProvider` runs sessions already spawned under a gated account; `mapCandidates` only enumerates running-session SOURCES; no `.list()[0]`-style ungated picks exist; `PlacementExecutor` doesn't select accounts.
|
|
66
|
+
5. **Tests cover both boundary sides + invariant agreement** — 9/9 pass; explicit `poolHeadroom.placeable ⟺ selectAccount !== null` assertions for meta-only and real cases.
|
|
67
|
+
6. **No fail-OPEN** — predicate is fail-closed (missing/non-string/empty `configHome` → false).
|
|
68
|
+
|
|
69
|
+
Sound, well-tested pure tightening with the never-loop invariant correctly preserved.
|