instar 1.3.608 → 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/commands/server.js +2 -1
- package/dist/commands/server.js.map +1 -1
- package/dist/coordination/AccountFollowMeMandateBridge.d.ts +56 -0
- package/dist/coordination/AccountFollowMeMandateBridge.d.ts.map +1 -0
- package/dist/coordination/AccountFollowMeMandateBridge.js +56 -0
- package/dist/coordination/AccountFollowMeMandateBridge.js.map +1 -0
- package/dist/core/AccountFollowMeDetector.d.ts +53 -0
- package/dist/core/AccountFollowMeDetector.d.ts.map +1 -0
- package/dist/core/AccountFollowMeDetector.js +56 -0
- package/dist/core/AccountFollowMeDetector.js.map +1 -0
- package/dist/core/AccountFollowMeEmailGate.d.ts +51 -0
- package/dist/core/AccountFollowMeEmailGate.d.ts.map +1 -0
- package/dist/core/AccountFollowMeEmailGate.js +50 -0
- package/dist/core/AccountFollowMeEmailGate.js.map +1 -0
- package/dist/core/AccountFollowMeOrchestrator.d.ts +98 -0
- package/dist/core/AccountFollowMeOrchestrator.d.ts.map +1 -0
- package/dist/core/AccountFollowMeOrchestrator.js +76 -0
- package/dist/core/AccountFollowMeOrchestrator.js.map +1 -0
- package/dist/core/AccountFollowMeService.d.ts +84 -0
- package/dist/core/AccountFollowMeService.d.ts.map +1 -0
- package/dist/core/AccountFollowMeService.js +105 -0
- package/dist/core/AccountFollowMeService.js.map +1 -0
- 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/dist/core/accountFollowMeDepth.d.ts +40 -0
- package/dist/core/accountFollowMeDepth.d.ts.map +1 -0
- package/dist/core/accountFollowMeDepth.js +47 -0
- package/dist/core/accountFollowMeDepth.js.map +1 -0
- package/dist/core/fetchPeerSubscriptionViews.d.ts +46 -0
- package/dist/core/fetchPeerSubscriptionViews.d.ts.map +1 -0
- package/dist/core/fetchPeerSubscriptionViews.js +70 -0
- package/dist/core/fetchPeerSubscriptionViews.js.map +1 -0
- package/dist/monitoring/guardManifest.d.ts.map +1 -1
- package/dist/monitoring/guardManifest.js +1 -0
- package/dist/monitoring/guardManifest.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 +3 -0
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +49 -0
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +47 -47
- package/upgrades/1.3.609.md +24 -0
- package/upgrades/1.3.610.md +24 -0
- package/upgrades/side-effects/ws52-account-follow-me-locally-executable.md +69 -0
- package/upgrades/side-effects/ws52-account-follow-me-pr2.md +59 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WS5.2 §5.2 — Account Follow-Me service: composes the primitives into the depth-zero → consent
|
|
3
|
+
* flow, and the mandate-delivered → proceed flow. Pure orchestration over INJECTED deps (pool
|
|
4
|
+
* reader, consent emitter, enroll driver) so it is unit-testable WITHOUT spawning a server; the
|
|
5
|
+
* HTTP route / scheduler tick later just constructs it with real deps.
|
|
6
|
+
*
|
|
7
|
+
* Two entry points:
|
|
8
|
+
* - scanAndOffer(): detect depth-zero enrollment candidates (R7-bounded), run each through the
|
|
9
|
+
* orchestrator (no operator mandate yet → consent-required), and emit ONE AGGREGATED consent
|
|
10
|
+
* item (P17 Bounded Notification Surface) — never one per machine. Never enrolls anything.
|
|
11
|
+
* - onMandateDelivered(): a portable account-follow-me mandate arrived from the operator machine
|
|
12
|
+
* → verify it (R4a bridge) → run the orchestrator with it → on allow, return an enroll-drive
|
|
13
|
+
* instruction for the caller to execute (per-server, OQ6). Still never self-authorizes.
|
|
14
|
+
*
|
|
15
|
+
* The service decides; the side effects (raising the attention item, driving the EnrollmentWizard,
|
|
16
|
+
* SubscriptionPool.add) are injected so each is independently testable + swappable. PR2 increment 3b.
|
|
17
|
+
*/
|
|
18
|
+
import { detectEnrollmentOffers } from './AccountFollowMeDetector.js';
|
|
19
|
+
import { acceptDeliveredMandate } from '../coordination/AccountFollowMeMandateBridge.js';
|
|
20
|
+
export class AccountFollowMeService {
|
|
21
|
+
deps;
|
|
22
|
+
constructor(deps) {
|
|
23
|
+
this.deps = deps;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* §5.2 scan: surface (never act on) the depth-zero enrollment offers. Runs each candidate through
|
|
27
|
+
* the orchestrator — with no mandate yet, each yields consent-required — and emits ONE aggregated
|
|
28
|
+
* consent item over all of them. Returns the consent requests surfaced (empty if none).
|
|
29
|
+
*/
|
|
30
|
+
scanAndOffer() {
|
|
31
|
+
const { machines, accounts } = this.deps.readPoolDepth();
|
|
32
|
+
const candidates = detectEnrollmentOffers({
|
|
33
|
+
machines,
|
|
34
|
+
accounts,
|
|
35
|
+
maxFollowMachines: this.deps.maxFollowMachines(),
|
|
36
|
+
inFlight: this.deps.inFlight(),
|
|
37
|
+
});
|
|
38
|
+
if (candidates.length === 0)
|
|
39
|
+
return { offered: [] };
|
|
40
|
+
const consents = [];
|
|
41
|
+
for (const c of candidates) {
|
|
42
|
+
const decision = this.deps.orchestrator.requestEnrollment({
|
|
43
|
+
accountId: c.accountId,
|
|
44
|
+
accountEmail: c.accountEmail,
|
|
45
|
+
targetMachineId: c.targetMachineId,
|
|
46
|
+
targetMachineNickname: c.targetMachineNickname,
|
|
47
|
+
// no mandateId on a scan → orchestrator returns consent-required (never proceeds)
|
|
48
|
+
});
|
|
49
|
+
if (!decision.proceed)
|
|
50
|
+
consents.push(decision.consent);
|
|
51
|
+
}
|
|
52
|
+
if (consents.length === 0)
|
|
53
|
+
return { offered: [] };
|
|
54
|
+
// ONE aggregated attention item over all offers (P17), id stable to the offered (account,target) set.
|
|
55
|
+
const key = consents.map((c) => `${c.accountId}:${c.targetMachineId}`).sort().join(',');
|
|
56
|
+
const targets = [...new Set(consents.map((c) => c.targetMachineNickname))].join(', ');
|
|
57
|
+
this.deps.emitAggregatedConsent({
|
|
58
|
+
id: `agent:account-follow-me-consent:${key}`,
|
|
59
|
+
title: `Authorize account access on ${consents.length} machine(s)?`,
|
|
60
|
+
body: `These machines have no account yet: ${targets}. ` +
|
|
61
|
+
`Authorize them to use your subscription on the dashboard (one tap each). ` +
|
|
62
|
+
`Nothing is enrolled until you approve.`,
|
|
63
|
+
priority: 'medium',
|
|
64
|
+
source: 'agent',
|
|
65
|
+
offers: consents,
|
|
66
|
+
});
|
|
67
|
+
this.deps.log?.(`[account-follow-me] surfaced ${consents.length} enrollment consent offer(s)`);
|
|
68
|
+
return { offered: consents };
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* A portable account-follow-me mandate was delivered from the operator machine. Verify it (R4a),
|
|
72
|
+
* then run the orchestrator with it. On allow, return an enroll-drive instruction; otherwise null
|
|
73
|
+
* (verification failed, or the gate denied — never proceed, never self-authorize).
|
|
74
|
+
*/
|
|
75
|
+
onMandateDelivered(args) {
|
|
76
|
+
const accept = acceptDeliveredMandate({
|
|
77
|
+
portable: args.portable,
|
|
78
|
+
operatorEd25519PublicKey: args.operatorEd25519PublicKey,
|
|
79
|
+
expectedOperatorMachineFingerprint: args.expectedOperatorMachineFingerprint,
|
|
80
|
+
});
|
|
81
|
+
if (!accept.accepted) {
|
|
82
|
+
this.deps.log?.(`[account-follow-me] delivered mandate rejected: ${accept.reason}`);
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
const decision = this.deps.orchestrator.requestEnrollment({
|
|
86
|
+
accountId: args.request.accountId,
|
|
87
|
+
accountEmail: args.request.accountEmail,
|
|
88
|
+
targetMachineId: args.request.targetMachineId,
|
|
89
|
+
targetMachineNickname: args.request.targetMachineNickname,
|
|
90
|
+
mechanism: args.request.mechanism,
|
|
91
|
+
mandateId: accept.mandate.id,
|
|
92
|
+
});
|
|
93
|
+
if (!decision.proceed) {
|
|
94
|
+
this.deps.log?.(`[account-follow-me] gate denied a verified mandate: ${decision.reason}`);
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
accountId: decision.accountId,
|
|
99
|
+
targetMachineId: decision.targetMachineId,
|
|
100
|
+
mechanism: decision.mechanism,
|
|
101
|
+
mandateId: accept.mandate.id,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=AccountFollowMeService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AccountFollowMeService.js","sourceRoot":"","sources":["../../src/core/AccountFollowMeService.ts"],"names":[],"mappings":"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"}
|
|
@@ -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":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,yCAAyC,EAAE,MAAM,6CAA6C,CAAC;AAI7G,uEAAuE;AACvE,MAAM,MAAM,oBAAoB,GAC5B,WAAW,GACX,QAAQ,GACR,gBAAgB,GAChB,QAAQ,CAAC;AAEb,gDAAgD;AAChD,MAAM,MAAM,qBAAqB,GAC7B,aAAa,GACb,WAAW,GACX,YAAY,GACZ,QAAQ,CAAC;AAEb;;;;;;;GAOG;AACH,MAAM,MAAM,yBAAyB,GACjC,QAAQ,GACR,SAAS,GACT,cAAc,GACd,cAAc,GACd,UAAU,CAAC;AAEf;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACxD,QAAQ,CAAC,EAAE;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IACzC,UAAU,CAAC,EAAE;QACX,SAAS,EAAE,OAAO,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,sEAAsE;IACtE,MAAM,CAAC,EAAE,0BAA0B,GAAG,+BAA+B,CAAC;IACtE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,kDAAkD;IAClD,EAAE,EAAE,MAAM,CAAC;IACX,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB;;;gFAG4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wBAAwB;IACxB,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,iDAAiD;IACjD,SAAS,EAAE,qBAAqB,CAAC;IACjC;;;;OAIG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,wBAAwB;IACxB,MAAM,EAAE,yBAAyB,CAAC;IAClC,mEAAmE;IACnE,SAAS,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACxC,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAC;CACjB;AAQD,MAAM,WAAW,sBAAsB;IACrC,6FAA6F;IAC7F,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,SAAS,EAAE,qBAAqB,CAAC;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,yBAAyB,CAAC;IACnC,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,uFAAuF;AACvF,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,qBAAqB,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,yBAAyB,CAAC;IACnC,SAAS,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAyCD,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,KAAK,CAAwB;IACrC;;;;;;OAMG;IACH,OAAO,CAAC,eAAe,CAA0D;gBAErE,MAAM,EAAE,sBAAsB;IAK1C,mFAAmF;IACnF,yBAAyB,CAAC,OAAO,EAAE,yCAAyC,GAAG,IAAI,GAAG,IAAI;IAM1F,sEAAsE;IACtE,IAAI,IAAI,mBAAmB,EAAE;IAI7B,kCAAkC;IAClC,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI;IAK3C,gEAAgE;IAChE,IAAI,IAAI,MAAM;IAMd;;;;OAIG;IACH,GAAG,CAAC,KAAK,EAAE,eAAe,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,mBAAmB;IA6CpF;;;;OAIG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,mBAAmB,GAAG,IAAI;IAkD7G,0DAA0D;IAC1D,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAa3B,SAAS,IAAI,eAAe;IAc5B,OAAO,CAAC,wBAAwB;IAWhC,OAAO,CAAC,IAAI;IAoBZ,OAAO,CAAC,IAAI;CAab"}
|
|
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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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WS5.2 §5.1/§5.2 — depth adapter: map real pool state (this machine's SubscriptionPool + the
|
|
3
|
+
* cross-machine `?scope=pool` view) into the AccountFollowMeDetector's input shape.
|
|
4
|
+
*
|
|
5
|
+
* The adapter is PURE (no I/O) so it is unit-testable without a server; the route/tick supplies
|
|
6
|
+
* the real fetched data (local accounts + the per-peer scope=pool rows). This is the seam between
|
|
7
|
+
* the server-coupled fetch and the pure detection logic.
|
|
8
|
+
*
|
|
9
|
+
* "Usable" = a machine can actually SERVE from an account = it holds a real local login (a
|
|
10
|
+
* config-home / non-meta-only account that is active or warming). A meta-only replicated account
|
|
11
|
+
* (known but not held) does NOT count toward a machine's usable depth — that is the whole point of
|
|
12
|
+
* follow-me (a machine that only KNOWS about an account still needs its own login).
|
|
13
|
+
*/
|
|
14
|
+
import type { PoolMachineDepth, OperatorAccount } from './AccountFollowMeDetector.js';
|
|
15
|
+
/** One account row as seen on a machine (local or via scope=pool). */
|
|
16
|
+
export interface MachineAccountRow {
|
|
17
|
+
accountId: string;
|
|
18
|
+
email?: string;
|
|
19
|
+
/** Lifecycle status (active/warming = usable; rate-limited/needs-reauth/disabled = not). */
|
|
20
|
+
status: string;
|
|
21
|
+
/** True iff this machine holds a REAL local login for it (has a config-home), not meta-only. */
|
|
22
|
+
locallyHeld: boolean;
|
|
23
|
+
}
|
|
24
|
+
export interface MachinePoolView {
|
|
25
|
+
machineId: string;
|
|
26
|
+
nickname: string;
|
|
27
|
+
/** The accounts this machine sees/holds. */
|
|
28
|
+
accounts: MachineAccountRow[];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Build the detector input from the per-machine pool views. `usableAccountCount` per machine =
|
|
32
|
+
* the count of accounts it can actually serve from (locally-held + active/warming). `accounts`
|
|
33
|
+
* (the operator's accounts + which machines hold each, usably) is derived across all machines —
|
|
34
|
+
* keyed by accountId, so the SAME account on two machines collapses to one entry with both holders.
|
|
35
|
+
*/
|
|
36
|
+
export declare function buildDepthInput(views: MachinePoolView[]): {
|
|
37
|
+
machines: PoolMachineDepth[];
|
|
38
|
+
accounts: OperatorAccount[];
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=accountFollowMeDepth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accountFollowMeDepth.d.ts","sourceRoot":"","sources":["../../src/core/accountFollowMeDepth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEtF,sEAAsE;AACtE,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4FAA4F;IAC5F,MAAM,EAAE,MAAM,CAAC;IACf,gGAAgG;IAChG,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAQD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG;IAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAAC,QAAQ,EAAE,eAAe,EAAE,CAAA;CAAE,CAsBvH"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WS5.2 §5.1/§5.2 — depth adapter: map real pool state (this machine's SubscriptionPool + the
|
|
3
|
+
* cross-machine `?scope=pool` view) into the AccountFollowMeDetector's input shape.
|
|
4
|
+
*
|
|
5
|
+
* The adapter is PURE (no I/O) so it is unit-testable without a server; the route/tick supplies
|
|
6
|
+
* the real fetched data (local accounts + the per-peer scope=pool rows). This is the seam between
|
|
7
|
+
* the server-coupled fetch and the pure detection logic.
|
|
8
|
+
*
|
|
9
|
+
* "Usable" = a machine can actually SERVE from an account = it holds a real local login (a
|
|
10
|
+
* config-home / non-meta-only account that is active or warming). A meta-only replicated account
|
|
11
|
+
* (known but not held) does NOT count toward a machine's usable depth — that is the whole point of
|
|
12
|
+
* follow-me (a machine that only KNOWS about an account still needs its own login).
|
|
13
|
+
*/
|
|
14
|
+
const USABLE_STATUSES = new Set(['active', 'warming']);
|
|
15
|
+
function isUsable(row) {
|
|
16
|
+
return row.locallyHeld === true && USABLE_STATUSES.has(row.status);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Build the detector input from the per-machine pool views. `usableAccountCount` per machine =
|
|
20
|
+
* the count of accounts it can actually serve from (locally-held + active/warming). `accounts`
|
|
21
|
+
* (the operator's accounts + which machines hold each, usably) is derived across all machines —
|
|
22
|
+
* keyed by accountId, so the SAME account on two machines collapses to one entry with both holders.
|
|
23
|
+
*/
|
|
24
|
+
export function buildDepthInput(views) {
|
|
25
|
+
const machines = [];
|
|
26
|
+
const accountMap = new Map();
|
|
27
|
+
for (const v of views) {
|
|
28
|
+
let usableCount = 0;
|
|
29
|
+
for (const row of v.accounts) {
|
|
30
|
+
if (!accountMap.has(row.accountId)) {
|
|
31
|
+
accountMap.set(row.accountId, { accountId: row.accountId, email: row.email ?? '', heldByMachineIds: [] });
|
|
32
|
+
}
|
|
33
|
+
const acct = accountMap.get(row.accountId);
|
|
34
|
+
// Prefer a non-empty email if any holder reports one.
|
|
35
|
+
if (!acct.email && row.email)
|
|
36
|
+
acct.email = row.email;
|
|
37
|
+
if (isUsable(row)) {
|
|
38
|
+
usableCount++;
|
|
39
|
+
if (!acct.heldByMachineIds.includes(v.machineId))
|
|
40
|
+
acct.heldByMachineIds.push(v.machineId);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
machines.push({ machineId: v.machineId, nickname: v.nickname, usableAccountCount: usableCount });
|
|
44
|
+
}
|
|
45
|
+
return { machines, accounts: [...accountMap.values()] };
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=accountFollowMeDepth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accountFollowMeDepth.js","sourceRoot":"","sources":["../../src/core/accountFollowMeDepth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAqBH,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC;AAEvD,SAAS,QAAQ,CAAC,GAAsB;IACtC,OAAO,GAAG,CAAC,WAAW,KAAK,IAAI,IAAI,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACrE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,KAAwB;IACtD,MAAM,QAAQ,GAAuB,EAAE,CAAC;IACxC,MAAM,UAAU,GAAG,IAAI,GAAG,EAA2B,CAAC;IAEtD,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,WAAW,GAAG,CAAC,CAAC;QACpB,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;YAC7B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;gBACnC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,EAAE,EAAE,gBAAgB,EAAE,EAAE,EAAE,CAAC,CAAC;YAC5G,CAAC;YACD,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAE,CAAC;YAC5C,sDAAsD;YACtD,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK;gBAAE,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;YACrD,IAAI,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAClB,WAAW,EAAE,CAAC;gBACd,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;oBAAE,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YAC5F,CAAC;QACH,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,kBAAkB,EAAE,WAAW,EAAE,CAAC,CAAC;IACnG,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;AAC1D,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WS5.2 §5.1 — fetch each online peer's account inventory for cross-machine depth detection.
|
|
3
|
+
*
|
|
4
|
+
* Extracts the `?scope=pool` fan-out into a standalone, injectable, unit-testable function: it
|
|
5
|
+
* queries each registered ONLINE peer's PLAIN `/subscription-pool` (NEVER `?scope=pool` — no
|
|
6
|
+
* recursion) and maps the result into the depth adapter's `MachinePoolView[]`. A peer that reports
|
|
7
|
+
* an account in its own plain pool HOLDS it locally (it has a config-home there), so those rows
|
|
8
|
+
* are `locallyHeld: true` — exactly what the detector needs to tell a depth-zero peer from one
|
|
9
|
+
* that can serve. Dark/slow/erroring peers are TOLERATED (skipped), never a throw — mirroring the
|
|
10
|
+
* existing scope=pool "classified per-peer failure, never a 500" discipline.
|
|
11
|
+
*
|
|
12
|
+
* Pure over injected deps (peer list, fetch, auth) ⇒ unit-testable with a mock fetch; the route/
|
|
13
|
+
* server wires the real peer URLs (resolvePeerUrls) + the agent's authToken.
|
|
14
|
+
*/
|
|
15
|
+
import type { MachinePoolView } from './accountFollowMeDepth.js';
|
|
16
|
+
export interface PeerRef {
|
|
17
|
+
machineId: string;
|
|
18
|
+
nickname: string;
|
|
19
|
+
/** Base URL of the peer's instar server (no trailing slash needed). */
|
|
20
|
+
url: string;
|
|
21
|
+
}
|
|
22
|
+
export interface FetchPeerViewsDeps {
|
|
23
|
+
/** Online, registered peers (excluding self). */
|
|
24
|
+
peers: () => PeerRef[] | Promise<PeerRef[]>;
|
|
25
|
+
/** Injected fetch (real `fetch` in prod; a stub in tests). */
|
|
26
|
+
fetchImpl: (url: string, init?: {
|
|
27
|
+
headers?: Record<string, string>;
|
|
28
|
+
signal?: AbortSignal;
|
|
29
|
+
}) => Promise<{
|
|
30
|
+
ok: boolean;
|
|
31
|
+
status: number;
|
|
32
|
+
json: () => Promise<unknown>;
|
|
33
|
+
}>;
|
|
34
|
+
/** Bearer token for the peer's authenticated `/subscription-pool` read. */
|
|
35
|
+
authToken: string;
|
|
36
|
+
/** Per-peer timeout (ms). Default 4000. */
|
|
37
|
+
timeoutMs?: number;
|
|
38
|
+
log?: (msg: string) => void;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Fetch peer views. Tolerant: a peer that is down / slow / non-200 / unparseable contributes
|
|
42
|
+
* NOTHING (skipped, logged) rather than failing the whole detection — a dark peer must not block
|
|
43
|
+
* depth detection on the others.
|
|
44
|
+
*/
|
|
45
|
+
export declare function fetchPeerSubscriptionViews(deps: FetchPeerViewsDeps): Promise<MachinePoolView[]>;
|
|
46
|
+
//# sourceMappingURL=fetchPeerSubscriptionViews.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetchPeerSubscriptionViews.d.ts","sourceRoot":"","sources":["../../src/core/fetchPeerSubscriptionViews.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAqB,MAAM,2BAA2B,CAAC;AAEpF,MAAM,WAAW,OAAO;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,kBAAkB;IACjC,iDAAiD;IACjD,KAAK,EAAE,MAAM,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5C,8DAA8D;IAC9D,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,KAAK,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;IACtK,2EAA2E;IAC3E,SAAS,EAAE,MAAM,CAAC;IAClB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AA4BD;;;;GAIG;AACH,wBAAsB,0BAA0B,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CA4BrG"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WS5.2 §5.1 — fetch each online peer's account inventory for cross-machine depth detection.
|
|
3
|
+
*
|
|
4
|
+
* Extracts the `?scope=pool` fan-out into a standalone, injectable, unit-testable function: it
|
|
5
|
+
* queries each registered ONLINE peer's PLAIN `/subscription-pool` (NEVER `?scope=pool` — no
|
|
6
|
+
* recursion) and maps the result into the depth adapter's `MachinePoolView[]`. A peer that reports
|
|
7
|
+
* an account in its own plain pool HOLDS it locally (it has a config-home there), so those rows
|
|
8
|
+
* are `locallyHeld: true` — exactly what the detector needs to tell a depth-zero peer from one
|
|
9
|
+
* that can serve. Dark/slow/erroring peers are TOLERATED (skipped), never a throw — mirroring the
|
|
10
|
+
* existing scope=pool "classified per-peer failure, never a 500" discipline.
|
|
11
|
+
*
|
|
12
|
+
* Pure over injected deps (peer list, fetch, auth) ⇒ unit-testable with a mock fetch; the route/
|
|
13
|
+
* server wires the real peer URLs (resolvePeerUrls) + the agent's authToken.
|
|
14
|
+
*/
|
|
15
|
+
function mapAccounts(raw) {
|
|
16
|
+
const accounts = (raw && typeof raw === 'object' && Array.isArray(raw.accounts))
|
|
17
|
+
? (raw.accounts)
|
|
18
|
+
: [];
|
|
19
|
+
const out = [];
|
|
20
|
+
for (const a of accounts) {
|
|
21
|
+
const r = a;
|
|
22
|
+
if (typeof r.id !== 'string' || r.id.length === 0)
|
|
23
|
+
continue;
|
|
24
|
+
out.push({
|
|
25
|
+
accountId: r.id,
|
|
26
|
+
email: typeof r.email === 'string' ? r.email : undefined,
|
|
27
|
+
status: typeof r.status === 'string' ? r.status : 'active',
|
|
28
|
+
// A peer reporting an account in its OWN plain pool holds it locally.
|
|
29
|
+
locallyHeld: true,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
return out;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Fetch peer views. Tolerant: a peer that is down / slow / non-200 / unparseable contributes
|
|
36
|
+
* NOTHING (skipped, logged) rather than failing the whole detection — a dark peer must not block
|
|
37
|
+
* depth detection on the others.
|
|
38
|
+
*/
|
|
39
|
+
export async function fetchPeerSubscriptionViews(deps) {
|
|
40
|
+
const peers = await deps.peers();
|
|
41
|
+
const timeoutMs = deps.timeoutMs ?? 4000;
|
|
42
|
+
const views = [];
|
|
43
|
+
for (const p of peers) {
|
|
44
|
+
try {
|
|
45
|
+
const ctrl = new AbortController();
|
|
46
|
+
const t = setTimeout(() => ctrl.abort(), timeoutMs);
|
|
47
|
+
let resp;
|
|
48
|
+
try {
|
|
49
|
+
resp = await deps.fetchImpl(`${p.url.replace(/\/$/, '')}/subscription-pool`, {
|
|
50
|
+
headers: { Authorization: `Bearer ${deps.authToken}` },
|
|
51
|
+
signal: ctrl.signal,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
finally {
|
|
55
|
+
clearTimeout(t);
|
|
56
|
+
}
|
|
57
|
+
if (!resp.ok) {
|
|
58
|
+
deps.log?.(`[account-follow-me] peer ${p.machineId} returned ${resp.status}; skipping`);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
const body = await resp.json();
|
|
62
|
+
views.push({ machineId: p.machineId, nickname: p.nickname, accounts: mapAccounts(body) });
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
deps.log?.(`[account-follow-me] peer ${p.machineId} unreachable (${err instanceof Error ? err.message : String(err)}); skipping`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return views;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=fetchPeerSubscriptionViews.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetchPeerSubscriptionViews.js","sourceRoot":"","sources":["../../src/core/fetchPeerSubscriptionViews.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guardManifest.d.ts","sourceRoot":"","sources":["../../src/monitoring/guardManifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,cAAc,CAAC;AAClD,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEjD,MAAM,WAAW,kBAAkB;IACjC,6FAA6F;IAC7F,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,SAAS,CAAC;IAChB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;qFAEiF;IACjF,cAAc,EAAE,OAAO,CAAC;IACxB,6DAA6D;IAC7D,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,8EAA8E;IAC9E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;wEACoE;IACpE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,YAAY,CAAC;IACtB;;;;2DAIuD;IACvD,aAAa,EAAE,OAAO,CAAC;IACvB,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,cAAc,EAAE,SAAS,kBAAkB,EAye9C,CAAC;AAEX;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,WAAW,EAAE,SAAS,cAAc,
|
|
1
|
+
{"version":3,"file":"guardManifest.d.ts","sourceRoot":"","sources":["../../src/monitoring/guardManifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,cAAc,CAAC;AAClD,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEjD,MAAM,WAAW,kBAAkB;IACjC,6FAA6F;IAC7F,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,SAAS,CAAC;IAChB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;qFAEiF;IACjF,cAAc,EAAE,OAAO,CAAC;IACxB,6DAA6D;IAC7D,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,8EAA8E;IAC9E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;wEACoE;IACpE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,YAAY,CAAC;IACtB;;;;2DAIuD;IACvD,aAAa,EAAE,OAAO,CAAC;IACvB,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,cAAc,EAAE,SAAS,kBAAkB,EAye9C,CAAC;AAEX;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,WAAW,EAAE,SAAS,cAAc,EA+EvC,CAAC;AAEX,qFAAqF;AACrF,wBAAgB,aAAa,IAAI,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAI/D;AAED,wBAAgB,kBAAkB,IAAI,GAAG,CAAC,MAAM,CAAC,CAIhD;AAED,wBAAgB,mBAAmB,IAAI,GAAG,CAAC,MAAM,CAAC,CAEjD"}
|
|
@@ -555,6 +555,7 @@ export const NOT_A_GUARD = [
|
|
|
555
555
|
{ component: 'A2ARedeliverySentinel', reason: 'A2A delivery-loop closer (redelivery + per-peer escalation) gated by monitoring.a2aRedelivery, default-OFF; threadline delivery-robustness mechanics, deliberately not in the protective-guard inventory.' },
|
|
556
556
|
{ component: 'AgentWorktreeDetector', reason: 'One-shot per-startup worktree-convention scan emitting at most one aggregated attention item; no running lifecycle or enabled switch, so posture is not expressible.' },
|
|
557
557
|
{ component: 'FeedbackAnomalyDetector', reason: 'In-memory rate/burst screening of feedback submissions; feedback-service input validation, not a session-protecting guard.' },
|
|
558
|
+
{ component: 'AccountFollowMeDetector', reason: 'Pure deterministic decision helper (WS5.2) computing which depth-zero machines to OFFER an enrollment consent for; no boot lifecycle, no enabled switch, never blocks — a computation library, not a guard.' },
|
|
558
559
|
{ component: 'FrameworkParitySentinel', reason: 'Parity-rules registry consumer surfacing framework-native drift; mentor/parity feature mechanics riding enabledFrameworks, not an operator-flippable protective guard.' },
|
|
559
560
|
{ component: 'GeminiCapacityEscalationMonitor', reason: 'Implementation file of the manifest guard monitoring.geminiCapacityEscalation.enabled — declared there under component name GeminiCapacityEscalation; this entry classifies the file-basename alias only.' },
|
|
560
561
|
{ component: 'HandoffSentinel', reason: 'Planned-handoff lifecycle state machine (multi-machine coordination mechanics); coordination layer, not an operator-flippable guard.' },
|