instar 1.2.39 → 1.2.40

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,63 @@
1
+ /**
2
+ * LocaltunnelProvider — Tier-2 consent-gated relay tunnel via *.loca.lt.
3
+ *
4
+ * Per spec specs/dev-infrastructure/tunnel-failure-resilience.md Part 1
5
+ * (provider abstraction, Tier 2) and Part 7 (supply-chain hardening).
6
+ *
7
+ * SECURITY POSTURE:
8
+ * - localtunnel routes the agent's local server traffic through
9
+ * loca.lt servers. The relay operator (and anyone who logs the URL)
10
+ * can see dashboard PIN + signed view URLs while the relay is active.
11
+ * This is exactly why the spec gates Tier-2 providers behind owner
12
+ * consent — see Part 3 (consent flow) and Part 6 (mandatory
13
+ * credential rotation on relay-episode end).
14
+ * - The agent never spins this up without an explicit per-episode
15
+ * consent record bound to the owner principal — that's enforced in
16
+ * TunnelManager's state machine, not in this provider.
17
+ *
18
+ * Supply-chain hardening (Part 7):
19
+ * - The npm package `localtunnel` is pinned at exact version in
20
+ * package.json (no caret range).
21
+ * - The provider spawns the localtunnel client via its programmatic
22
+ * API; a future hardening PR can switch to child-process isolation
23
+ * once the spec's checksum-verified install path is added.
24
+ * - `isAvailable()` resolves false if the npm package cannot be
25
+ * loaded, so a missing dep degrades gracefully (provider skipped)
26
+ * instead of crashing.
27
+ *
28
+ * The provider does NOT own retry/reconnect/notification — those are
29
+ * the manager's responsibility per the single-owner mandate (PR 2).
30
+ */
31
+ import type { TunnelProvider, TunnelProviderHandle, ProviderName, ProviderTier } from './TunnelProvider.js';
32
+ export interface LocaltunnelProviderOptions {
33
+ /** Local port the relay should point at. */
34
+ port: number;
35
+ /** Start timeout in milliseconds (default: 20_000). */
36
+ startTimeoutMs?: number;
37
+ /**
38
+ * Optional subdomain hint passed to localtunnel. When set, the
39
+ * service will try to allocate the requested name; when unavailable
40
+ * (already taken or rate-limited), localtunnel falls back to a
41
+ * random subdomain. NEVER use the agent's identity here — the
42
+ * subdomain is publicly visible on *.loca.lt.
43
+ */
44
+ subdomain?: string;
45
+ }
46
+ export declare class LocaltunnelProvider implements TunnelProvider {
47
+ readonly name: ProviderName;
48
+ readonly tier: ProviderTier;
49
+ private readonly port;
50
+ private readonly startTimeoutMs;
51
+ private readonly subdomain;
52
+ /**
53
+ * Cached dynamic-import result. The first `isAvailable()` call
54
+ * detects whether the npm package is present; subsequent calls reuse
55
+ * the cached resolution.
56
+ */
57
+ private _moduleResolved;
58
+ constructor(opts: LocaltunnelProviderOptions);
59
+ isAvailable(): Promise<boolean>;
60
+ start(localPort: number): Promise<TunnelProviderHandle>;
61
+ private loadModule;
62
+ }
63
+ //# sourceMappingURL=LocaltunnelProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocaltunnelProvider.d.ts","sourceRoot":"","sources":["../../src/tunnel/LocaltunnelProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,oBAAoB,EACpB,YAAY,EACZ,YAAY,EACb,MAAM,qBAAqB,CAAC;AAE7B,MAAM,WAAW,0BAA0B;IACzC,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAkBD,qBAAa,mBAAoB,YAAW,cAAc;IACxD,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAiB;IAC5C,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAK;IAEhC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqB;IAC/C;;;;OAIG;IACH,OAAO,CAAC,eAAe,CAAgD;gBAE3D,IAAI,EAAE,0BAA0B;IAMtC,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAK/B,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;YA8D/C,UAAU;CAezB"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * LocaltunnelProvider — Tier-2 consent-gated relay tunnel via *.loca.lt.
3
+ *
4
+ * Per spec specs/dev-infrastructure/tunnel-failure-resilience.md Part 1
5
+ * (provider abstraction, Tier 2) and Part 7 (supply-chain hardening).
6
+ *
7
+ * SECURITY POSTURE:
8
+ * - localtunnel routes the agent's local server traffic through
9
+ * loca.lt servers. The relay operator (and anyone who logs the URL)
10
+ * can see dashboard PIN + signed view URLs while the relay is active.
11
+ * This is exactly why the spec gates Tier-2 providers behind owner
12
+ * consent — see Part 3 (consent flow) and Part 6 (mandatory
13
+ * credential rotation on relay-episode end).
14
+ * - The agent never spins this up without an explicit per-episode
15
+ * consent record bound to the owner principal — that's enforced in
16
+ * TunnelManager's state machine, not in this provider.
17
+ *
18
+ * Supply-chain hardening (Part 7):
19
+ * - The npm package `localtunnel` is pinned at exact version in
20
+ * package.json (no caret range).
21
+ * - The provider spawns the localtunnel client via its programmatic
22
+ * API; a future hardening PR can switch to child-process isolation
23
+ * once the spec's checksum-verified install path is added.
24
+ * - `isAvailable()` resolves false if the npm package cannot be
25
+ * loaded, so a missing dep degrades gracefully (provider skipped)
26
+ * instead of crashing.
27
+ *
28
+ * The provider does NOT own retry/reconnect/notification — those are
29
+ * the manager's responsibility per the single-owner mandate (PR 2).
30
+ */
31
+ export class LocaltunnelProvider {
32
+ name = 'localtunnel';
33
+ tier = 2;
34
+ port;
35
+ startTimeoutMs;
36
+ subdomain;
37
+ /**
38
+ * Cached dynamic-import result. The first `isAvailable()` call
39
+ * detects whether the npm package is present; subsequent calls reuse
40
+ * the cached resolution.
41
+ */
42
+ _moduleResolved;
43
+ constructor(opts) {
44
+ this.port = opts.port;
45
+ this.startTimeoutMs = opts.startTimeoutMs ?? 20_000;
46
+ this.subdomain = opts.subdomain;
47
+ }
48
+ async isAvailable() {
49
+ const mod = await this.loadModule();
50
+ return mod !== 'unavailable';
51
+ }
52
+ async start(localPort) {
53
+ const mod = await this.loadModule();
54
+ if (mod === 'unavailable') {
55
+ throw new Error('binary-missing: localtunnel npm package is not installed');
56
+ }
57
+ const lt = mod.default;
58
+ if (typeof lt !== 'function') {
59
+ throw new Error('binary-missing: localtunnel module did not expose the expected factory');
60
+ }
61
+ const port = localPort || this.port;
62
+ return new Promise((resolve, reject) => {
63
+ let resolved = false;
64
+ const timeout = setTimeout(() => {
65
+ if (resolved)
66
+ return;
67
+ resolved = true;
68
+ reject(new Error('timeout: localtunnel did not emit a URL within the start budget'));
69
+ }, this.startTimeoutMs);
70
+ lt({ port, subdomain: this.subdomain }).then((client) => {
71
+ if (resolved) {
72
+ try {
73
+ client.close();
74
+ }
75
+ catch { /* best effort */ }
76
+ return;
77
+ }
78
+ resolved = true;
79
+ clearTimeout(timeout);
80
+ if (!client.url) {
81
+ reject(new Error('process-exit: localtunnel returned no URL'));
82
+ return;
83
+ }
84
+ client.on('error', () => { });
85
+ resolve({
86
+ url: client.url,
87
+ stop: async () => {
88
+ try {
89
+ client.close();
90
+ }
91
+ catch { /* already dead */ }
92
+ },
93
+ });
94
+ }, (err) => {
95
+ if (resolved)
96
+ return;
97
+ resolved = true;
98
+ clearTimeout(timeout);
99
+ const msg = (err?.message ?? '').toLowerCase();
100
+ if (msg.includes('rate') || msg.includes('429')) {
101
+ reject(new Error(`rate-limited: localtunnel: ${err.message}`));
102
+ return;
103
+ }
104
+ if (msg.includes('econnrefused') || msg.includes('dns')) {
105
+ reject(new Error(`network: localtunnel: ${err.message}`));
106
+ return;
107
+ }
108
+ reject(new Error(`process-exit: localtunnel start failed: ${err.message}`));
109
+ });
110
+ });
111
+ }
112
+ async loadModule() {
113
+ if (this._moduleResolved !== undefined)
114
+ return this._moduleResolved;
115
+ try {
116
+ // Dynamic specifier so TypeScript doesn't require an installed
117
+ // `@types/localtunnel`. The npm package itself is an optional
118
+ // peer-style dep — agents without it installed degrade
119
+ // gracefully via the catch below.
120
+ const specifier = 'localtunnel';
121
+ const mod = (await import(/* @vite-ignore */ specifier));
122
+ this._moduleResolved = mod;
123
+ }
124
+ catch {
125
+ this._moduleResolved = 'unavailable';
126
+ }
127
+ return this._moduleResolved;
128
+ }
129
+ }
130
+ //# sourceMappingURL=LocaltunnelProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocaltunnelProvider.js","sourceRoot":"","sources":["../../src/tunnel/LocaltunnelProvider.ts"],"names":[],"mappings":"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"}
@@ -40,7 +40,7 @@
40
40
  */
41
41
  import { EventEmitter } from 'node:events';
42
42
  import { type PersistedTunnelState } from './TunnelLifecycle.js';
43
- import type { TunnelProvider, ProviderFailureReason } from './TunnelProvider.js';
43
+ import type { TunnelProvider, ProviderName, ProviderFailureReason } from './TunnelProvider.js';
44
44
  import type { NotifierSink } from './TunnelNotifier.js';
45
45
  export interface TunnelConfig {
46
46
  /** Whether tunnel is enabled. */
@@ -110,6 +110,13 @@ export declare class TunnelManager extends EventEmitter {
110
110
  private _backoffAttempt;
111
111
  private _backoffTimer;
112
112
  private _postExhaustedTimer;
113
+ /**
114
+ * Pending consent record — populated when the manager enters
115
+ * `awaiting-consent` and cleared on grant / decline / timeout / stop.
116
+ * The nonce is the CSPRNG token sent to the owner; matching it on
117
+ * `grantConsent()` is the security-load-bearing check.
118
+ */
119
+ private _pendingConsent;
113
120
  constructor(config: TunnelConfig, injections?: TunnelManagerInjections);
114
121
  get url(): string | null;
115
122
  get isRunning(): boolean;
@@ -154,6 +161,42 @@ export declare class TunnelManager extends EventEmitter {
154
161
  private doStart;
155
162
  private driveTier1;
156
163
  private exhaustedOrBackoff;
164
+ /** First Tier-2 provider that reports available, or null. */
165
+ private findAvailableTier2;
166
+ /**
167
+ * Internal — called after the lifecycle transitions to
168
+ * `awaiting-consent`. Generates the one-time nonce, stores the
169
+ * pending consent record, and arms the timeout.
170
+ */
171
+ private requestConsent;
172
+ private clearPendingConsent;
173
+ /**
174
+ * Public — called by the consent UX layer (Telegram callback handler
175
+ * in PR 6) after the owner approves. Validates the nonce matches the
176
+ * pending consent record, starts the Tier-2 provider, and transitions
177
+ * to `relay-active`. Returns true on success, false if the nonce
178
+ * didn't match (replay, race, stale click) or the state moved beyond
179
+ * awaiting-consent.
180
+ */
181
+ grantConsent(nonce: string): Promise<boolean>;
182
+ /**
183
+ * Public — called by the consent UX layer when the owner declines.
184
+ * Validates the nonce, applies the cross-episode cooldown, and
185
+ * transitions to `exhausted` + background retry.
186
+ */
187
+ declineConsent(nonce: string): boolean;
188
+ private recordConsentDecline;
189
+ /**
190
+ * Public — the active pending-consent record (or null). Used by the
191
+ * consent UX layer (PR 6) to know what nonce to embed in the inline
192
+ * button.
193
+ */
194
+ get pendingConsent(): {
195
+ episodeId: string;
196
+ provider: ProviderName;
197
+ nonce: string;
198
+ issuedAt: number;
199
+ } | null;
157
200
  /**
158
201
  * Background retry — runs the bounded exponential ladder off the
159
202
  * start() promise so initial start() resolves/rejects fast. After
@@ -1 +1 @@
1
- {"version":3,"file":"TunnelManager.d.ts","sourceRoot":"","sources":["../../src/tunnel/TunnelManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TunnelManager.d.ts","sourceRoot":"","sources":["../../src/tunnel/TunnelManager.ts"],"names":[],"mappings":"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"}
@@ -41,9 +41,10 @@
41
41
  import { EventEmitter } from 'node:events';
42
42
  import fs from 'node:fs';
43
43
  import path from 'node:path';
44
- import { TunnelLifecycle, classifyFailure, } from './TunnelLifecycle.js';
44
+ import { TunnelLifecycle, classifyFailure, generateNonce, } from './TunnelLifecycle.js';
45
45
  import { CloudflareQuickProvider } from './CloudflareQuickProvider.js';
46
46
  import { CloudflareNamedProvider } from './CloudflareNamedProvider.js';
47
+ import { LocaltunnelProvider } from './LocaltunnelProvider.js';
47
48
  import { TunnelNotifier } from './TunnelNotifier.js';
48
49
  // ── Constants ───────────────────────────────────────────────────────
49
50
  const BASE_BACKOFF_MS = 5_000;
@@ -61,6 +62,8 @@ const REACHABILITY_TIMEOUT_MS = 8_000;
61
62
  * the regression we explicitly need to avoid in the PR chain.
62
63
  */
63
64
  const POST_EXHAUSTED_RETRY_INTERVAL_MS = 15 * 60_000;
65
+ /** Per-episode consent prompt timeout — matches spec Part 4 default (15 min). */
66
+ const CONSENT_TIMEOUT_MS = 15 * 60_000;
64
67
  // ── Manager ────────────────────────────────────────────────────────
65
68
  export class TunnelManager extends EventEmitter {
66
69
  config;
@@ -78,6 +81,13 @@ export class TunnelManager extends EventEmitter {
78
81
  _backoffAttempt = 0;
79
82
  _backoffTimer = null;
80
83
  _postExhaustedTimer = null;
84
+ /**
85
+ * Pending consent record — populated when the manager enters
86
+ * `awaiting-consent` and cleared on grant / decline / timeout / stop.
87
+ * The nonce is the CSPRNG token sent to the owner; matching it on
88
+ * `grantConsent()` is the security-load-bearing check.
89
+ */
90
+ _pendingConsent = null;
81
91
  constructor(config, injections) {
82
92
  super();
83
93
  this.config = config;
@@ -132,6 +142,7 @@ export class TunnelManager extends EventEmitter {
132
142
  this._stopped = true;
133
143
  this.clearBackoffTimer();
134
144
  this.clearPostExhaustedTimer();
145
+ this.clearPendingConsent();
135
146
  this._startPromise = null;
136
147
  if (this.currentHandle) {
137
148
  try {
@@ -208,6 +219,8 @@ export class TunnelManager extends EventEmitter {
208
219
  // ── Internals ──────────────────────────────────────────────────
209
220
  buildDefaultPool(config) {
210
221
  const pool = [];
222
+ // Tier-1 (automatic, secure). Cloudflare named first when configured,
223
+ // then quick as the zero-config default.
211
224
  if (config.token || config.configFile) {
212
225
  pool.push(new CloudflareNamedProvider({
213
226
  token: config.token,
@@ -216,6 +229,13 @@ export class TunnelManager extends EventEmitter {
216
229
  }));
217
230
  }
218
231
  pool.push(new CloudflareQuickProvider({ port: config.port, stateDir: config.stateDir }));
232
+ // Tier-2 (consent-gated relays). Listed AFTER Tier-1 — the driver
233
+ // only reaches these after exhausting Tier-1, and only after the
234
+ // owner explicitly grants consent. LocaltunnelProvider's
235
+ // isAvailable() returns false when the `localtunnel` npm package
236
+ // isn't installed, so agents without the dep see this slot
237
+ // silently skipped — the spec's "opt-in capability" posture.
238
+ pool.push(new LocaltunnelProvider({ port: config.port }));
219
239
  return pool;
220
240
  }
221
241
  async doStart() {
@@ -293,31 +313,195 @@ export class TunnelManager extends EventEmitter {
293
313
  return this.exhaustedOrBackoff(lastErr);
294
314
  }
295
315
  async exhaustedOrBackoff(lastErr) {
296
- // Matches the legacy semantics: start() rejects after the FIRST
297
- // round of provider attempts fails. The backoff retry runs in the
298
- // background — the manager keeps trying without blocking the
299
- // caller, and emits 'url' when a later attempt succeeds. This
300
- // prevents start() from blocking server.ts boot for the full
301
- // 25-minute worst-case exponential window. The original failing
302
- // E2E (tests/e2e/tunnel-private-view.test.ts) timed out at the
303
- // beforeAll 60s budget because the old draft kept retrying inside
304
- // start().
316
+ // start() rejects after the FIRST round of provider attempts
317
+ // fails (matches the legacy semantics). The backoff retry runs in
318
+ // the background — the manager keeps trying without blocking the
319
+ // caller, and emits 'url' when a later attempt succeeds.
320
+ //
321
+ // PR 5 addition: BEFORE transitioning to exhausted, check if any
322
+ // Tier-2 providers are available and the cross-episode consent
323
+ // cooldown isn't active. If so, transition to `awaiting-consent`
324
+ // and request consent from the owner. The relay-active path
325
+ // activates on `grantConsent()`.
326
+ const candidateTier2 = await this.findAvailableTier2();
327
+ const cooldownActive = this.lifecycle.isConsentSuppressed();
328
+ if (candidateTier2 && !cooldownActive) {
329
+ const from = this.lifecycle.state;
330
+ if (from === 'retrying' || from === 'starting') {
331
+ if (this.lifecycle.transition(from, 'awaiting-consent', {
332
+ activeProvider: null,
333
+ lastFailureReason: classifyFailure(lastErr),
334
+ })) {
335
+ this.requestConsent(candidateTier2);
336
+ }
337
+ }
338
+ const err = lastErr ?? new Error('Tier-1 exhausted; awaiting owner consent for backup relay');
339
+ this.emit('error', err);
340
+ throw err;
341
+ }
305
342
  const from = this.lifecycle.state;
306
343
  if (from === 'retrying' || from === 'starting') {
307
344
  this.lifecycle.transition(from, 'exhausted', { activeProvider: null });
308
345
  }
309
346
  const err = lastErr ?? new Error('all Tier-1 providers failed');
310
- // Schedule background retry (bounded exponential ladder, then the
311
- // indefinite post-exhausted placeholder once the ladder runs out).
312
- // Fire-and-forget; if a later attempt succeeds, the 'url' event
313
- // fires and downstream subscribers (notifier, dashboard
314
- // broadcaster, log line) catch up.
315
347
  if (this._autoReconnect && !this._stopped) {
316
348
  this.scheduleBackgroundRetry();
317
349
  }
318
350
  this.emit('error', err);
319
351
  throw err;
320
352
  }
353
+ /** First Tier-2 provider that reports available, or null. */
354
+ async findAvailableTier2() {
355
+ for (const p of this.providers) {
356
+ if (p.tier !== 2)
357
+ continue;
358
+ const avail = await p.isAvailable().catch(() => false);
359
+ if (avail)
360
+ return p;
361
+ }
362
+ return null;
363
+ }
364
+ /**
365
+ * Internal — called after the lifecycle transitions to
366
+ * `awaiting-consent`. Generates the one-time nonce, stores the
367
+ * pending consent record, and arms the timeout.
368
+ */
369
+ requestConsent(provider) {
370
+ this.clearPendingConsent();
371
+ const episode = this.lifecycle.episode;
372
+ if (!episode)
373
+ return;
374
+ const nonce = generateNonce();
375
+ const timer = setTimeout(() => {
376
+ this.recordConsentDecline(nonce, 'timeout');
377
+ }, CONSENT_TIMEOUT_MS);
378
+ this._pendingConsent = {
379
+ episodeId: episode.episodeId,
380
+ provider,
381
+ nonce,
382
+ issuedAt: Date.now(),
383
+ timer,
384
+ };
385
+ }
386
+ clearPendingConsent() {
387
+ if (this._pendingConsent) {
388
+ clearTimeout(this._pendingConsent.timer);
389
+ this._pendingConsent = null;
390
+ }
391
+ }
392
+ /**
393
+ * Public — called by the consent UX layer (Telegram callback handler
394
+ * in PR 6) after the owner approves. Validates the nonce matches the
395
+ * pending consent record, starts the Tier-2 provider, and transitions
396
+ * to `relay-active`. Returns true on success, false if the nonce
397
+ * didn't match (replay, race, stale click) or the state moved beyond
398
+ * awaiting-consent.
399
+ */
400
+ async grantConsent(nonce) {
401
+ if (!this._pendingConsent)
402
+ return false;
403
+ if (this._pendingConsent.nonce !== nonce)
404
+ return false;
405
+ if (this.lifecycle.state !== 'awaiting-consent') {
406
+ this.clearPendingConsent();
407
+ return false;
408
+ }
409
+ const { provider, episodeId } = this._pendingConsent;
410
+ if (this.lifecycle.episode?.episodeId !== episodeId) {
411
+ this.clearPendingConsent();
412
+ return false;
413
+ }
414
+ // Single-use: clear BEFORE starting so a replay loses cleanly.
415
+ this.clearPendingConsent();
416
+ try {
417
+ const handle = await provider.start(this.config.port);
418
+ const reachable = await this.probeReachability(handle.url).catch(() => false);
419
+ if (!reachable) {
420
+ try {
421
+ await handle.stop();
422
+ }
423
+ catch { /* best effort */ }
424
+ this.lifecycle.recordAttempt(provider.name, 'reachability-failed');
425
+ this.lifecycle.recordConsentRefusal();
426
+ const from = this.lifecycle.state;
427
+ if (from === 'awaiting-consent') {
428
+ this.lifecycle.transition('awaiting-consent', 'exhausted', { activeProvider: null });
429
+ }
430
+ if (this._autoReconnect && !this._stopped) {
431
+ this.scheduleBackgroundRetry();
432
+ }
433
+ return false;
434
+ }
435
+ this.currentHandle = handle;
436
+ this.currentProviderName = provider.name;
437
+ this._legacyState.url = handle.url;
438
+ this._legacyState.startedAt = new Date().toISOString();
439
+ // Set rotation-pending — entering relay-active is the persisted
440
+ // marker that says "credentials must rotate when this episode
441
+ // ends" (per spec Part 6 / verification finding V1).
442
+ this.lifecycle.setRotationPending(true);
443
+ this.lifecycle.transition('awaiting-consent', 'relay-active', {
444
+ activeProvider: provider.name,
445
+ lastFailureReason: null,
446
+ rotationPending: true,
447
+ });
448
+ this.persist();
449
+ this.emit('url', handle.url);
450
+ return true;
451
+ }
452
+ catch (err) {
453
+ this.lifecycle.recordAttempt(provider.name, classifyFailure(err));
454
+ this.lifecycle.recordConsentRefusal();
455
+ const from = this.lifecycle.state;
456
+ if (from === 'awaiting-consent') {
457
+ this.lifecycle.transition('awaiting-consent', 'exhausted', { activeProvider: null });
458
+ }
459
+ if (this._autoReconnect && !this._stopped) {
460
+ this.scheduleBackgroundRetry();
461
+ }
462
+ return false;
463
+ }
464
+ }
465
+ /**
466
+ * Public — called by the consent UX layer when the owner declines.
467
+ * Validates the nonce, applies the cross-episode cooldown, and
468
+ * transitions to `exhausted` + background retry.
469
+ */
470
+ declineConsent(nonce) {
471
+ return this.recordConsentDecline(nonce, 'decline');
472
+ }
473
+ recordConsentDecline(nonce, _reason) {
474
+ if (!this._pendingConsent)
475
+ return false;
476
+ if (this._pendingConsent.nonce !== nonce)
477
+ return false;
478
+ if (this.lifecycle.state !== 'awaiting-consent') {
479
+ this.clearPendingConsent();
480
+ return false;
481
+ }
482
+ this.clearPendingConsent();
483
+ this.lifecycle.recordConsentRefusal();
484
+ this.lifecycle.transition('awaiting-consent', 'exhausted', { activeProvider: null });
485
+ if (this._autoReconnect && !this._stopped) {
486
+ this.scheduleBackgroundRetry();
487
+ }
488
+ return true;
489
+ }
490
+ /**
491
+ * Public — the active pending-consent record (or null). Used by the
492
+ * consent UX layer (PR 6) to know what nonce to embed in the inline
493
+ * button.
494
+ */
495
+ get pendingConsent() {
496
+ if (!this._pendingConsent)
497
+ return null;
498
+ return {
499
+ episodeId: this._pendingConsent.episodeId,
500
+ provider: this._pendingConsent.provider.name,
501
+ nonce: this._pendingConsent.nonce,
502
+ issuedAt: this._pendingConsent.issuedAt,
503
+ };
504
+ }
321
505
  /**
322
506
  * Background retry — runs the bounded exponential ladder off the
323
507
  * start() promise so initial start() resolves/rejects fast. After
@@ -1 +1 @@
1
- {"version":3,"file":"TunnelManager.js","sourceRoot":"","sources":["../../src/tunnel/TunnelManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TunnelManager.js","sourceRoot":"","sources":["../../src/tunnel/TunnelManager.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instar",
3
- "version": "1.2.39",
3
+ "version": "1.2.40",
4
4
  "description": "Persistent autonomy infrastructure for AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "./builtin-manifest.schema.json",
3
3
  "schemaVersion": 1,
4
- "generatedAt": "2026-05-23T02:07:34.437Z",
5
- "instarVersion": "1.2.39",
4
+ "generatedAt": "2026-05-23T02:31:36.933Z",
5
+ "instarVersion": "1.2.40",
6
6
  "entryCount": 191,
7
7
  "entries": {
8
8
  "hook:session-start": {
@@ -0,0 +1,119 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- bump: patch -->
4
+ <!-- patch = consent state machine + grantConsent/declineConsent API; no Telegram wire-up yet -->
5
+
6
+ ## What Changed
7
+
8
+ **feat(tunnel): consent state machine — Tier-1 exhaustion → awaiting-consent → relay-active.**
9
+
10
+ PR 5 of the tunnel-failure-resilience chain. Lands the consent state
11
+ machine inside `TunnelManager` so an exhausted Tier-1 path can offer
12
+ the Tier-2 relay (LocaltunnelProvider from PR 4) behind an
13
+ owner-approval gate.
14
+
15
+ What's new:
16
+
17
+ - `TunnelManager.buildDefaultPool` now appends a `LocaltunnelProvider`
18
+ as the Tier-2 slot. `isAvailable()` returns false when the
19
+ `localtunnel` npm package isn't installed (per the spec's opt-in
20
+ posture), so the slot is silently skipped on agents without the
21
+ dep — behavior is unchanged for them.
22
+ - `TunnelManager.exhaustedOrBackoff` now checks for an available
23
+ Tier-2 provider AND that the cross-episode consent cooldown isn't
24
+ active before deciding between `exhausted` and `awaiting-consent`.
25
+ When both conditions hold, the manager transitions to
26
+ `awaiting-consent` and generates a one-time CSPRNG nonce stored in
27
+ a new `_pendingConsent` record.
28
+ - `TunnelManager.grantConsent(nonce)` — public API. Validates the
29
+ nonce matches the pending record AND the state is still
30
+ `awaiting-consent` (replay-safe single-use), starts the Tier-2
31
+ provider, runs the post-start reachability probe, and transitions
32
+ to `relay-active` with `rotationPending=true` (the persisted
33
+ marker for the upcoming mandatory PIN+authToken rotation in PR 6).
34
+ Returns true on success; false on any validation failure or
35
+ start/probe failure.
36
+ - `TunnelManager.declineConsent(nonce)` — public API. Validates the
37
+ nonce, advances the cross-episode cooldown counter, and
38
+ transitions to `exhausted` + background retry.
39
+ - Consent timeout (15 min, per spec Part 4 default) — fires
40
+ automatically; same effect as decline.
41
+ - `stop()` clears the pending consent + its timer so a torn-down
42
+ manager can't have a stale timeout fire.
43
+ - `TunnelManager.pendingConsent` accessor — returns a defensive
44
+ snapshot (episodeId, provider name, nonce, issuedAt) for the
45
+ upcoming Telegram callback handler (PR 6) to embed the nonce in
46
+ the inline-button payload.
47
+
48
+ What's NOT new yet (deliberate, future PRs in the chain):
49
+
50
+ - Telegram `callback_query` handler that invokes `grantConsent` /
51
+ `declineConsent` on owner button clicks (PR 6).
52
+ - Inline-button payload in the consent prompt (PR 6).
53
+ - `authToken` / PIN rotation lifecycle on relay-episode end (PR 6+).
54
+ - Full N-consecutive-success self-heal stability gate (PR 7).
55
+ - The auth-gated `/tunnel` route + `ConfigDefaults` migration +
56
+ CLAUDE.md template (PR 8).
57
+ - The `localtunnel` npm dep itself (PR 6, alongside the consent
58
+ wire-up — keeps the capability opt-in until the gate is fully
59
+ live).
60
+
61
+ Behavior change for users today: **none** at runtime. Agents without
62
+ the `localtunnel` dep installed continue exactly as before (Tier-2
63
+ slot is unavailable, manager falls through to exhausted). The
64
+ plumbing is in place; PR 6 makes it user-facing.
65
+
66
+ ## Evidence
67
+
68
+ 11 new unit tests in `tests/unit/tunnel-consent-state-machine.test.ts`:
69
+
70
+ - Tier-1 exhausts + Tier-2 available + cooldown inactive →
71
+ `awaiting-consent` + pendingConsent populated with 128-bit hex nonce.
72
+ - Tier-1 exhausts + NO Tier-2 available → `exhausted` (baseline path).
73
+ - Tier-1 exhausts + consent cooldown active → `exhausted` (cooldown
74
+ wins).
75
+ - `grantConsent` with matching nonce → `relay-active` + URL emitted +
76
+ rotationPending=true + pendingConsent cleared (single-use).
77
+ - `grantConsent` with wrong nonce → returns false, state unchanged,
78
+ provider.start NOT called.
79
+ - `grantConsent` replay of a used nonce → returns false, state
80
+ unchanged.
81
+ - `grantConsent` + reachability probe fails → `exhausted` + cooldown
82
+ advanced.
83
+ - `grantConsent` + provider.start throws → `exhausted` + cooldown
84
+ advanced.
85
+ - `declineConsent` with matching nonce → `exhausted` + cooldown
86
+ advanced + pendingConsent cleared.
87
+ - `declineConsent` with wrong nonce → returns false, state unchanged,
88
+ no cooldown change.
89
+ - `stop()` clears pendingConsent + the timeout timer.
90
+
91
+ All 92 tunnel-related unit tests pass (11 new + 81 from PRs 1–4).
92
+ `tsc --noEmit` clean. `npm run lint` clean.
93
+
94
+ ## What to Tell Your User
95
+
96
+ This release puts the security gate for backup tunnels into place.
97
+ Nothing visible to you yet — the gate needs a button to click, and
98
+ that's the next release. Once that lands, when Cloudflare goes fully
99
+ down, you'll get a private message from your agent asking permission
100
+ to use a backup. Until you approve, the agent stays link-less and
101
+ keeps retrying Cloudflare. If you decline or don't reply, the agent
102
+ won't ask again for a while (the wait window grows the more you
103
+ decline, so the agent stops bothering you about something you've
104
+ already decided).
105
+
106
+ If you want the backup capability to actually work when the next
107
+ release lands, install the localtunnel npm package alongside your
108
+ agent. Without it the backup option is silently skipped and the
109
+ agent continues with Cloudflare only — which is fine if that's your
110
+ preference.
111
+
112
+ ## Summary of New Capabilities
113
+
114
+ | Capability | How to Use |
115
+ |-----------|-----------|
116
+ | Consent state machine (Tier-1 → awaiting-consent → relay-active) | Internal — exposed via grantConsent / declineConsent APIs that the upcoming Telegram callback handler will call |
117
+ | Single-use CSPRNG nonce binding | Automatic — pendingConsent.nonce embeds in the inline button in the next release |
118
+ | Cross-episode consent cooldown | Automatic — exponential back-off on decline/timeout (1h → 4h → 24h) |
119
+ | Mandatory rotation marker on relay-active entry | Automatic — rotationPending=true is the crash-safe flag the upcoming rotation lifecycle reads |
@@ -0,0 +1,135 @@
1
+ # Side-effects review — consent state machine (PR 5 of tunnel-failure-resilience chain)
2
+
3
+ **Scope (PR 5 of the chain):** Land the consent state machine inside
4
+ `TunnelManager` and append `LocaltunnelProvider` (from PR 4) to the
5
+ default Tier-2 slot. Adds public `grantConsent` / `declineConsent`
6
+ methods so the upcoming Telegram callback handler (PR 6) can drive the
7
+ owner-approval gate. Spec
8
+ `specs/dev-infrastructure/tunnel-failure-resilience.md` is converged
9
+ + approved on main.
10
+
11
+ **Files touched:**
12
+ - `src/tunnel/TunnelManager.ts` — adds Tier-2 to `buildDefaultPool`;
13
+ modifies `exhaustedOrBackoff` to branch on Tier-2 availability +
14
+ consent cooldown; adds `findAvailableTier2`, `requestConsent`,
15
+ `clearPendingConsent`, `grantConsent`, `declineConsent`,
16
+ `recordConsentDecline`, and the `pendingConsent` accessor; updates
17
+ `stop()` to clear the pending consent.
18
+ - `tests/unit/tunnel-consent-state-machine.test.ts` — 11 tests covering
19
+ the awaiting-consent transition (and its negative cases — no Tier-2
20
+ available, cooldown active), grantConsent happy path, nonce
21
+ rejection (wrong nonce, replay), grant-failure paths (unreachable
22
+ relay, provider.start throws), declineConsent happy path + wrong
23
+ nonce, stop() clearing pendingConsent.
24
+
25
+ **Under-block**: None at user-visible runtime. Agents without the
26
+ `localtunnel` npm dep installed continue to fall through to
27
+ `exhausted` exactly as before (the Tier-2 slot's `isAvailable()`
28
+ returns false; `findAvailableTier2` returns null; the branch picks
29
+ the existing `exhausted` path). This is the spec's opt-in posture —
30
+ PR 4's side-effects review documented it explicitly.
31
+
32
+ **Over-block**: Minimal. Agents that DO have `localtunnel` installed
33
+ WILL see the new `awaiting-consent` transition fire instead of going
34
+ straight to `exhausted` — but the manager has no UX layer to surface
35
+ the prompt yet (PR 6 lands the Telegram callback handler that
36
+ actually calls `grantConsent` / `declineConsent`). For now the
37
+ manager sits in `awaiting-consent` for the 15-minute timeout, then
38
+ auto-declines and falls through to exhausted with the cooldown
39
+ advanced. From the user's perspective this looks identical to
40
+ "exhausted" today — there's just a 15-min delay before the cooldown
41
+ counter ticks the first time.
42
+
43
+ To explicitly avoid this UX gap during the interim window between
44
+ PR 5 and PR 6, operators who don't want the awaiting-consent state
45
+ can simply not install `localtunnel`. The default ships without it.
46
+
47
+ **Level-of-abstraction fit**:
48
+ - The state machine lives in `TunnelLifecycle` (PR 1); the manager
49
+ drives state through the existing CAS-guarded transitions.
50
+ - `_pendingConsent` is private state on the manager (binds nonce +
51
+ episode + provider). Exposed read-only via the `pendingConsent`
52
+ accessor that returns a snapshot — callers cannot mutate the
53
+ manager's state from outside.
54
+ - `grantConsent` / `declineConsent` are the AUTHORITY surface for
55
+ consent decisions. The Telegram callback handler (PR 6) will be
56
+ the SIGNAL layer — it validates the click came from the owner and
57
+ the message id matches, then calls these methods.
58
+
59
+ **Signal vs authority**: Compliant. The manager is the authority for
60
+ state transitions and the consent record's lifecycle; external
61
+ callers can only ask for grant/decline by presenting the nonce, and
62
+ the manager validates+decides. The Telegram callback handler in PR 6
63
+ will be a thin signal layer above this; it cannot bypass the nonce
64
+ check.
65
+
66
+ **Interactions**:
67
+ - `_pendingConsent` is single-flight per manager instance — only one
68
+ consent record can be active at a time (the lifecycle's `episode`
69
+ invariant: one episode = one consent prompt = one nonce).
70
+ - `clearPendingConsent` is called on every terminal path (grant
71
+ success, decline, timeout, stop, episode change). The timer is
72
+ cleared atomically with the record so no stale callback can fire.
73
+ - The consent timeout uses the lifecycle's `recordConsentRefusal`
74
+ to advance the cross-episode cooldown — same path as a manual
75
+ decline. The cooldown progression is exponential (1h → 4h → 24h)
76
+ per PR 1's lifecycle implementation.
77
+ - `rotationPending=true` is set on entering `relay-active` (the
78
+ crash-safe persisted marker for the upcoming rotation lifecycle
79
+ in PR 6). The actual rotation work is NOT in this PR — only the
80
+ marker.
81
+ - Reachability probe on the granted Tier-2 provider follows the
82
+ same `/health` semantics as Tier-1 — a relay that emits a URL
83
+ but doesn't actually serve traffic falls through to exhausted +
84
+ cooldown (so the owner isn't asked again immediately).
85
+
86
+ **External surfaces**:
87
+ - New public methods: `grantConsent(nonce)`, `declineConsent(nonce)`,
88
+ `pendingConsent` getter on `TunnelManager`. All require the
89
+ caller to have the current pending nonce, which is itself only
90
+ accessible via `pendingConsent.nonce` — there's no broader
91
+ exposure.
92
+ - No new API endpoint, no new CLI command, no new config field.
93
+ - The default tunnel pool now includes a `LocaltunnelProvider`
94
+ slot, but the manager only activates it after Tier-1 exhausts +
95
+ consent is granted, so users who never hit a Tier-1 exhaustion
96
+ never see Tier-2 attempted.
97
+
98
+ **Migration parity**: N/A. Server-side code only.
99
+
100
+ **Rollback cost**: Trivial. Revert `TunnelManager.ts` + the test file.
101
+ The new methods become unused (they're not called from anywhere
102
+ outside the manager + tests yet). LocaltunnelProvider stays in tree
103
+ from PR 4 but is no longer in the default pool.
104
+
105
+ **Tests**:
106
+ - 11/11 new tests in `tests/unit/tunnel-consent-state-machine.test.ts`.
107
+ - 19/19 tests in `tests/unit/tunnel-manager-rewrite.test.ts` (from
108
+ PR 2 + 3) still pass.
109
+ - 32/32 lifecycle, 13/13 notifier, 10/10 providers, 7/7 localtunnel-
110
+ provider — all still pass.
111
+ - `tsc --noEmit` clean. `npm run lint` clean. No existing tests
112
+ modified.
113
+
114
+ **Decision-point inventory**:
115
+ 1. `_pendingConsent` stores the provider directly (vs. a provider-name
116
+ key into the pool) — keeps the grant path independent of the pool
117
+ ordering, and ensures a provider that becomes "unavailable"
118
+ between request and grant is still the one we attempt (failure
119
+ surfaces cleanly).
120
+ 2. Nonce is 128-bit CSPRNG via `generateNonce` from PR 1 — meets the
121
+ GPT external review's spec for entropy + atomic compare-and-delete.
122
+ 3. Single-use enforced by `clearPendingConsent` BEFORE the provider
123
+ starts — a replay of the same nonce loses cleanly even if the
124
+ start is in flight.
125
+ 4. Timeout = 15 min (spec Part 4 default, staggered off the 10-min
126
+ reconnect window per verification finding V1).
127
+ 5. Reachability failure on a granted relay → cooldown advanced.
128
+ Reason: the relay started but doesn't serve; bothering the owner
129
+ again immediately wouldn't help. The cooldown gates the next ask.
130
+ 6. State machine transitions `awaiting-consent → exhausted` directly
131
+ on decline/timeout/start-failure — same transition the cooldown
132
+ path uses, so background retry semantics are uniform.
133
+ 7. `pendingConsent` accessor returns a defensive snapshot — mutating
134
+ it does NOT affect the manager. External callers cannot inject
135
+ their own nonce or change the bound provider.
@@ -0,0 +1,95 @@
1
+ # Side-effects review — LocaltunnelProvider (PR 4 of tunnel-failure-resilience chain)
2
+
3
+ **Scope (PR 4 of the chain):** Add the `LocaltunnelProvider`
4
+ implementation of the `TunnelProvider` interface from PR 1. The class
5
+ is added in isolation — NOT wired into the manager's active pool —
6
+ so PR 5 can ship the consent state machine + inline-button UX +
7
+ relay-active activation path with the provider already in place
8
+ under separate review. Spec
9
+ `specs/dev-infrastructure/tunnel-failure-resilience.md` is converged
10
+ + approved on main.
11
+
12
+ **Files touched:**
13
+ - `src/tunnel/LocaltunnelProvider.ts` — NEW. Implements
14
+ `TunnelProvider` with `name: 'localtunnel'`, `tier: 2`. Dynamic
15
+ import of the `localtunnel` npm package; graceful "unavailable"
16
+ return path when the dep isn't installed. Failure classification
17
+ preserves the `ProviderFailureReason` enum surface from PR 1
18
+ (rate-limited / network / process-exit / binary-missing).
19
+ - `tests/unit/localtunnel-provider.test.ts` — NEW. 7 tests covering
20
+ the provider's surface (name + tier), graceful degradation when
21
+ the npm package is absent (isAvailable=false; start() rejects
22
+ binary-missing; verdict cached across calls), and constructor
23
+ option acceptance.
24
+
25
+ **Under-block**: None — the provider is added but NOT wired into the
26
+ manager's active pool. The manager's existing `buildDefaultPool`
27
+ returns Cloudflare-named + Cloudflare-quick only, and the driver
28
+ filters Tier-2 providers (`if (provider.tier !== 1) continue;`).
29
+ User-facing behavior is unchanged.
30
+
31
+ **Over-block**: None. The provider class is purely additive; no
32
+ existing behavior changes.
33
+
34
+ **Level-of-abstraction fit**: The provider implements the same
35
+ interface as the Cloudflare providers, so PR 5's state-machine
36
+ changes can use it through the existing pool abstraction without
37
+ needing provider-specific code paths. Tier-2 trust classification
38
+ lives on the provider (`tier: 2` field), which is correctly the
39
+ manager's structural signal for "consent required."
40
+
41
+ **Signal vs authority**: Compliant. The provider raises errors with
42
+ classified reason strings (the SIGNAL); the manager classifies them
43
+ into `ProviderFailureReason` (the AUTHORITY). The consent gate (PR 5)
44
+ will be a separate AUTHORITY layer above the manager's driver — the
45
+ provider never makes consent decisions on its own.
46
+
47
+ **Interactions**:
48
+ - Dynamic import: the provider does `await import('localtunnel')` at
49
+ first `isAvailable()` call. On environments without the dep, the
50
+ import throws and the provider caches the "unavailable" verdict.
51
+ This is deliberately a runtime check, not a build-time one — instar
52
+ ships without the `localtunnel` dep in `package.json` (per the
53
+ spec's supply-chain hardening — Tier-2 backup capability is opt-in,
54
+ installed explicitly by operators who want it).
55
+ - The `subdomain` constructor option is operator-controlled. The
56
+ comment documents the privacy posture: never use the agent's
57
+ identity as a subdomain hint — it would be publicly visible on
58
+ `*.loca.lt`.
59
+
60
+ **External surfaces**:
61
+ - New exported class `LocaltunnelProvider` from `src/tunnel/`.
62
+ - No new npm dependency — `localtunnel` is NOT added to
63
+ `package.json` in this PR. The provider degrades gracefully when
64
+ the dep is absent. Operators add the dep explicitly to enable the
65
+ capability. This matches the spec's supply-chain posture (Part 7).
66
+ - No new API endpoint, no new CLI command, no new config field
67
+ (Part 4 fields land with PR 5 alongside the consent flow).
68
+
69
+ **Migration parity**: N/A. The provider is server-side code only;
70
+ no agent-installed file change.
71
+
72
+ **Rollback cost**: Trivial. Delete two files (`src/tunnel/Local-
73
+ tunnelProvider.ts` and the test). The provider is isolated; nothing
74
+ else references it.
75
+
76
+ **Tests**:
77
+ - 7/7 tests in `tests/unit/localtunnel-provider.test.ts`.
78
+ - 70/70 tunnel-related tests from PRs 1–3 unaffected.
79
+ - `tsc --noEmit` clean. `npm run lint` clean.
80
+
81
+ **Decision-point inventory**:
82
+ 1. Dynamic import (vs. static `import localtunnel from 'localtunnel'`)
83
+ — keeps `localtunnel` out of the build-time type-check graph so
84
+ instar can ship without the dep. Operators add it explicitly per
85
+ the spec's supply-chain stance.
86
+ 2. `localtunnel` NOT added to `package.json` in this PR — landing the
87
+ dep before the consent gate ships would expose users to an
88
+ unchecked Tier-2 capability. The dep lands in PR 5 alongside the
89
+ consent flow that gates its use. This is intentional and
90
+ per-spec — Part 7 frames the capability as opt-in regardless.
91
+ 3. `subdomain` is operator-controlled and documented as
92
+ non-identifying. The provider does not auto-generate one.
93
+ 4. Failure classification matches PR 1's enum — no new failure
94
+ reasons needed; the manager's existing logic handles localtunnel
95
+ failures the same way as cloudflared failures.