instar 1.3.138 → 1.3.140

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.
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAmSH,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAwvDD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAoqPtE;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDzE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuD5E"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAoSH,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAwvDD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAisPtE;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDzE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuD5E"}
@@ -66,6 +66,7 @@ import { wireRegistrySync } from '../core/wireRegistrySync.js';
66
66
  import { assertSeamlessnessInvariants } from '../core/seamlessnessConfig.js';
67
67
  import { FencedLease } from '../core/FencedLease.js';
68
68
  import { GitLeaseStore } from '../core/GitLeaseStore.js';
69
+ import { LocalLeaseStore } from '../core/LocalLeaseStore.js';
69
70
  import { LeaseCoordinator } from '../core/LeaseCoordinator.js';
70
71
  import { HttpLeaseTransport } from '../core/HttpLeaseTransport.js';
71
72
  import { HttpLiveTailTransport } from '../core/HttpLiveTailTransport.js';
@@ -2250,50 +2251,72 @@ export async function startServer(options) {
2250
2251
  // (the Phase-0 scenario) must ALREADY have it so its role-change push fires.
2251
2252
  // Only an awake machine pulls+pushes at boot; the durable registry push is
2252
2253
  // driven by the RegistrySyncDebouncer below, gated on authority.
2253
- if (coordinator.enabled && isGitRepo && gitBackupEnabled) {
2254
+ if (coordinator.enabled && coordinator.identity) {
2255
+ const idMgr = coordinator.managers.identityManager;
2256
+ const selfMachineId = coordinator.identity.machineId;
2257
+ // ── Git-sync substrate (OPTIONAL — not required for coordination) ──
2258
+ // git is the durable shared-CAS substrate for the lease + the registry
2259
+ // push channel. It is NOT required for cross-machine coordination: a
2260
+ // credential-less standby, or an agent whose home IS the instar source
2261
+ // tree (where SourceTreeGuard refuses GitSyncManager), has no git medium.
2262
+ // Construct it best-effort; its failure must NOT skip the HTTP lease/
2263
+ // handoff/live-tail transports below. (2026-05-31 bug, found live: the
2264
+ // lease block was nested in the git-gated try, so a gitSync throw left the
2265
+ // standby with leaseHolder=null → MeshRpc 'not-router' → transfer dead.)
2266
+ let gitSyncRef;
2267
+ if (isGitRepo && gitBackupEnabled) {
2268
+ try {
2269
+ gitSync = new GitSyncManager({
2270
+ projectDir: config.projectDir,
2271
+ stateDir: config.stateDir,
2272
+ identityManager: coordinator.managers.identityManager,
2273
+ securityLog: coordinator.managers.securityLog,
2274
+ machineId: selfMachineId,
2275
+ });
2276
+ // Configure commit signing if not already done
2277
+ if (!gitSync.isSigningConfigured() && localSigningKeyPem) {
2278
+ gitSync.configureCommitSigning();
2279
+ console.log(pc.green(' Git commit signing configured'));
2280
+ }
2281
+ // Pull (and auto-push) latest on startup — awake machine only.
2282
+ if (coordinator.isAwake) {
2283
+ const syncResult = await gitSync.sync();
2284
+ if (syncResult.pulled) {
2285
+ console.log(pc.green(` Git sync: pulled ${syncResult.commitsPulled} commit(s)`));
2286
+ }
2287
+ }
2288
+ gitSyncRef = gitSync;
2289
+ // ── G2 wiring (spec §8 G2) — roleChange/leaseEpoch → debounced push ──
2290
+ // Without a subscriber the durable registry push never fires; a
2291
+ // wiring-integrity test asserts this subscription exists.
2292
+ const gitSyncForDebounce = gitSyncRef;
2293
+ registrySyncDebouncer = new RegistrySyncDebouncer({
2294
+ commitAndPush: (msg, paths) => gitSyncForDebounce.commitAndPush(msg, paths),
2295
+ registryAbsPath: coordinator.managers.identityManager.registryPath,
2296
+ isAuthoritative: () => coordinator.isAwake,
2297
+ debounceMs: seamlessness.registrySyncDebounceMs,
2298
+ logger: (m) => console.log(pc.dim(m)),
2299
+ });
2300
+ wireRegistrySync(coordinator, registrySyncDebouncer);
2301
+ console.log(pc.dim(' Registry sync wired (roleChange/leaseEpoch → durable push)'));
2302
+ }
2303
+ catch (err) {
2304
+ // @silent-fallback-ok — git medium unavailable (SourceTreeGuard, no
2305
+ // remote, etc). The lease falls back to LocalLeaseStore + the HTTP
2306
+ // transport below, so cross-machine coordination still works.
2307
+ console.log(pc.yellow(` Git sync setup: ${err instanceof Error ? err.message : String(err)}`));
2308
+ gitSyncRef = undefined;
2309
+ }
2310
+ }
2254
2311
  try {
2255
- gitSync = new GitSyncManager({
2256
- projectDir: config.projectDir,
2257
- stateDir: config.stateDir,
2258
- identityManager: coordinator.managers.identityManager,
2259
- securityLog: coordinator.managers.securityLog,
2260
- machineId: coordinator.identity.machineId,
2261
- });
2262
- // Configure commit signing if not already done
2263
- if (!gitSync.isSigningConfigured() && localSigningKeyPem) {
2264
- gitSync.configureCommitSigning();
2265
- console.log(pc.green(' Git commit signing configured'));
2266
- }
2267
- // Pull (and auto-push) latest on startup — awake machine only.
2268
- if (coordinator.isAwake) {
2269
- const syncResult = await gitSync.sync();
2270
- if (syncResult.pulled) {
2271
- console.log(pc.green(` Git sync: pulled ${syncResult.commitsPulled} commit(s)`));
2272
- }
2273
- }
2274
- // ── G2 wiring (spec §8 G2) — the Phase-0 fix, named explicitly ──
2275
- // MultiMachineCoordinator emits roleChange / leaseEpochChange; without
2276
- // a subscriber the durable push never fired. wireRegistrySync connects
2277
- // those events to a debounced, single-writer registry push. A
2278
- // wiring-integrity test asserts this subscription exists.
2279
- const gitSyncRef = gitSync;
2280
- registrySyncDebouncer = new RegistrySyncDebouncer({
2281
- commitAndPush: (msg, paths) => gitSyncRef.commitAndPush(msg, paths),
2282
- registryAbsPath: coordinator.managers.identityManager.registryPath,
2283
- isAuthoritative: () => coordinator.isAwake,
2284
- debounceMs: seamlessness.registrySyncDebounceMs,
2285
- logger: (m) => console.log(pc.dim(m)),
2286
- });
2287
- wireRegistrySync(coordinator, registrySyncDebouncer);
2288
- console.log(pc.dim(' Registry sync wired (roleChange/leaseEpoch → durable push)'));
2289
2312
  // ── G1 fenced-lease integration (spec §6) ──────────────────
2290
- // The lease becomes the authority for awake/standby. git is the durable
2291
- // CAS substrate (correct, bounded by git cadence — the tunnel accelerator
2292
- // is a tracked follow-on, ACT-156-adjacent). A holder that cannot refresh
2293
- // its lease over git for > leaseTtlMs self-suspends, preventing the
2294
- // partitioned-old-awake split-brain.
2295
- const idMgr = coordinator.managers.identityManager;
2296
- const selfMachineId = coordinator.identity.machineId;
2313
+ // The lease is the authority for awake/standby + the MeshRpc router-only
2314
+ // RBAC (deliverMessage/place/transfer). GitLeaseStore is the durable
2315
+ // shared-CAS substrate WHEN git is available; otherwise LocalLeaseStore
2316
+ // persists this machine's own view and the HttpLeaseTransport carries
2317
+ // cross-machine propagation (broadcast/observe). A holder that cannot
2318
+ // confirm its renewal over its medium for > leaseTtlMs self-suspends,
2319
+ // preventing the partitioned-old-awake split-brain.
2297
2320
  const leaseCrypto = {
2298
2321
  selfMachineId,
2299
2322
  sign: (canonical) => signEd25519(canonical, idMgr.loadSigningKey()),
@@ -2313,15 +2336,26 @@ export async function startServer(options) {
2313
2336
  leaseTtlMs: seamlessness.leaseTtlMs,
2314
2337
  failoverThresholdMs: seamlessness.failoverThresholdMs,
2315
2338
  });
2316
- const leaseStore = new GitLeaseStore({
2317
- machineId: selfMachineId,
2318
- loadRegistry: () => idMgr.loadRegistry(),
2319
- saveRegistry: (r) => idMgr.saveRegistry(r),
2320
- registryAbsPath: idMgr.registryPath,
2321
- pullRebase: () => gitSyncRef.pullRebase(),
2322
- commitAndPush: (msg, paths) => gitSyncRef.commitAndPush(msg, paths),
2323
- logger: (m) => console.log(pc.dim(m)),
2324
- });
2339
+ let leaseStore;
2340
+ if (gitSyncRef) {
2341
+ const gs = gitSyncRef;
2342
+ leaseStore = new GitLeaseStore({
2343
+ machineId: selfMachineId,
2344
+ loadRegistry: () => idMgr.loadRegistry(),
2345
+ saveRegistry: (r) => idMgr.saveRegistry(r),
2346
+ registryAbsPath: idMgr.registryPath,
2347
+ pullRebase: () => gs.pullRebase(),
2348
+ commitAndPush: (msg, paths) => gs.commitAndPush(msg, paths),
2349
+ logger: (m) => console.log(pc.dim(m)),
2350
+ });
2351
+ }
2352
+ else {
2353
+ leaseStore = new LocalLeaseStore({
2354
+ filePath: path.join(config.stateDir, 'lease-local.json'),
2355
+ logger: (m) => console.log(pc.dim(m)),
2356
+ });
2357
+ console.log(pc.dim(' Lease store: LocalLeaseStore (no git medium — HTTP transport carries cross-machine lease)'));
2358
+ }
2325
2359
  // Lease wire transport (spec §6) — the low-latency authoritative copy
2326
2360
  // travels over the existing authenticated machine channel. For a
2327
2361
  // single-machine mesh (no peers) broadcast is a no-op and isReachable()
@@ -2471,8 +2505,9 @@ export async function startServer(options) {
2471
2505
  }
2472
2506
  }
2473
2507
  catch (err) {
2474
- // @silent-fallback-ok — git sync disabled gracefully
2475
- console.log(pc.yellow(` Git sync setup: ${err instanceof Error ? err.message : String(err)}`));
2508
+ // @silent-fallback-ok — lease/transport setup failed; the agent still
2509
+ // serves single-machine (cross-machine coordination simply stays off).
2510
+ console.log(pc.yellow(` Lease/transport setup: ${err instanceof Error ? err.message : String(err)}`));
2476
2511
  }
2477
2512
  }
2478
2513
  // Per-agent Codex threadline MCP override. Codex reads a SHARED