instar 1.3.710 → 1.3.712

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.
Files changed (72) hide show
  1. package/dist/commands/server.d.ts.map +1 -1
  2. package/dist/commands/server.js +228 -1
  3. package/dist/commands/server.js.map +1 -1
  4. package/dist/config/ConfigDefaults.d.ts.map +1 -1
  5. package/dist/config/ConfigDefaults.js +25 -0
  6. package/dist/config/ConfigDefaults.js.map +1 -1
  7. package/dist/core/HttpLeaseTransport.d.ts +9 -0
  8. package/dist/core/HttpLeaseTransport.d.ts.map +1 -1
  9. package/dist/core/HttpLeaseTransport.js +28 -2
  10. package/dist/core/HttpLeaseTransport.js.map +1 -1
  11. package/dist/core/MessagingToneGate.d.ts.map +1 -1
  12. package/dist/core/MessagingToneGate.js +3 -2
  13. package/dist/core/MessagingToneGate.js.map +1 -1
  14. package/dist/core/MultiMachineCoordinator.d.ts +44 -0
  15. package/dist/core/MultiMachineCoordinator.d.ts.map +1 -1
  16. package/dist/core/MultiMachineCoordinator.js +52 -0
  17. package/dist/core/MultiMachineCoordinator.js.map +1 -1
  18. package/dist/core/PeerEndpointResolver.d.ts +0 -0
  19. package/dist/core/PeerEndpointResolver.d.ts.map +1 -1
  20. package/dist/core/PeerEndpointResolver.js +0 -0
  21. package/dist/core/PeerEndpointResolver.js.map +1 -1
  22. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  23. package/dist/core/PostUpdateMigrator.js +19 -0
  24. package/dist/core/PostUpdateMigrator.js.map +1 -1
  25. package/dist/core/RopeRecoveryProber.d.ts +126 -0
  26. package/dist/core/RopeRecoveryProber.d.ts.map +1 -0
  27. package/dist/core/RopeRecoveryProber.js +266 -0
  28. package/dist/core/RopeRecoveryProber.js.map +1 -0
  29. package/dist/core/devGatedFeatures.d.ts.map +1 -1
  30. package/dist/core/devGatedFeatures.js +12 -0
  31. package/dist/core/devGatedFeatures.js.map +1 -1
  32. package/dist/core/ropeProbeContract.d.ts +56 -0
  33. package/dist/core/ropeProbeContract.d.ts.map +1 -0
  34. package/dist/core/ropeProbeContract.js +92 -0
  35. package/dist/core/ropeProbeContract.js.map +1 -0
  36. package/dist/core/tailscaleStatusParser.d.ts +46 -0
  37. package/dist/core/tailscaleStatusParser.d.ts.map +1 -0
  38. package/dist/core/tailscaleStatusParser.js +80 -0
  39. package/dist/core/tailscaleStatusParser.js.map +1 -0
  40. package/dist/core/types.d.ts +56 -0
  41. package/dist/core/types.d.ts.map +1 -1
  42. package/dist/core/types.js.map +1 -1
  43. package/dist/monitoring/RopeHealthMonitor.d.ts +243 -0
  44. package/dist/monitoring/RopeHealthMonitor.d.ts.map +1 -0
  45. package/dist/monitoring/RopeHealthMonitor.js +659 -0
  46. package/dist/monitoring/RopeHealthMonitor.js.map +1 -0
  47. package/dist/monitoring/guardManifest.d.ts.map +1 -1
  48. package/dist/monitoring/guardManifest.js +45 -0
  49. package/dist/monitoring/guardManifest.js.map +1 -1
  50. package/dist/scaffold/templates.d.ts.map +1 -1
  51. package/dist/scaffold/templates.js +9 -0
  52. package/dist/scaffold/templates.js.map +1 -1
  53. package/dist/server/AgentServer.d.ts +2 -0
  54. package/dist/server/AgentServer.d.ts.map +1 -1
  55. package/dist/server/AgentServer.js +1 -0
  56. package/dist/server/AgentServer.js.map +1 -1
  57. package/dist/server/CapabilityIndex.js +1 -1
  58. package/dist/server/CapabilityIndex.js.map +1 -1
  59. package/dist/server/routes.d.ts +3 -0
  60. package/dist/server/routes.d.ts.map +1 -1
  61. package/dist/server/routes.js +19 -0
  62. package/dist/server/routes.js.map +1 -1
  63. package/package.json +1 -1
  64. package/scripts/lint-scrape-fixture-realness.js +20 -0
  65. package/src/data/builtin-manifest.json +65 -65
  66. package/src/data/state-coherence-registry.json +17 -0
  67. package/src/scaffold/templates/jobs/instar/rope-health-digest.md +42 -0
  68. package/src/scaffold/templates.ts +9 -0
  69. package/upgrades/1.3.711.md +79 -0
  70. package/upgrades/1.3.712.md +41 -0
  71. package/upgrades/side-effects/tone-gate-rule-id-contract.md +78 -0
  72. package/upgrades/side-effects/u4-rope-probe-alerts.md +140 -0
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA8CH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAU3D,OAAO,EAAE,eAAe,EAAiC,MAAM,iCAAiC,CAAC;AAyBjG,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AA6H7D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAgFtD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC1C,OAAO,CAUT;AAyID,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA07CD,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,eAAe,EACzB,cAAc,EAAE,cAAc,EAC9B,YAAY,CAAC,EAAE,YAAY,EAC3B,WAAW,CAAC,EAAE,WAAW,EACzB,WAAW,CAAC,EAAE,WAAW,EACzB,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,EAGvE,UAAU,CAAC,EAAE,MAAM,OAAO,8BAA8B,EAAE,WAAW,GAAG,IAAI,EAK5E,qBAAqB,CAAC,EAAE,MAAM,OAAO,gCAAgC,EAAE,kBAAkB,GAAG,IAAI,EAKhG,mBAAmB,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,GACpD,IAAI,CAijBN;AA2lBD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAggiBtE;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;AA8CH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAU3D,OAAO,EAAE,eAAe,EAAiC,MAAM,iCAAiC,CAAC;AAyBjG,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AA6H7D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAgFtD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC1C,OAAO,CAUT;AAyID,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA07CD,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,eAAe,EACzB,cAAc,EAAE,cAAc,EAC9B,YAAY,CAAC,EAAE,YAAY,EAC3B,WAAW,CAAC,EAAE,WAAW,EACzB,WAAW,CAAC,EAAE,WAAW,EACzB,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,EAGvE,UAAU,CAAC,EAAE,MAAM,OAAO,8BAA8B,EAAE,WAAW,GAAG,IAAI,EAK5E,qBAAqB,CAAC,EAAE,MAAM,OAAO,gCAAgC,EAAE,kBAAkB,GAAG,IAAI,EAKhG,mBAAmB,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,GACpD,IAAI,CAijBN;AA2lBD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAyuiBtE;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"}
@@ -4093,6 +4093,12 @@ export async function startServer(options) {
4093
4093
  // honesty observer that STOPS attempting goes BLIND if the registry recovers.
4094
4094
  const MAX_BACKOFF_TICKS = 20;
4095
4095
  let leaseCoordinatorRef;
4096
+ // U4.3/U4.5 — hoisted rope-health seams. The resolver + prober are closure-locals
4097
+ // of the mesh-init block; U4.5's RopeHealthMonitor (constructed far below) reads the
4098
+ // REAL resolver snapshot through `_ropeSnapshotSource` (never a copy), and the
4099
+ // prober rides the coordinator's lease-pull tick.
4100
+ let _ropeSnapshotSource = null;
4101
+ let _ropeProber = null;
4096
4102
  let liveTailBuffer;
4097
4103
  let liveTailSendTransport;
4098
4104
  let handoffWireTransport;
@@ -4394,6 +4400,130 @@ export async function startServer(options) {
4394
4400
  };
4395
4401
  await coordinator.initializeLease();
4396
4402
  console.log(pc.dim(` Fenced lease active (epoch ${leaseCoordinator.currentEpoch()}, holder=${leaseCoordinator.currentHolder() ?? 'none'})`));
4403
+ // ── U4.3 — traffic-independent rope-health recovery probe ──────────
4404
+ // (docs/specs/u4-3-breaker-recovery-probe.md). Rides the lease-pull tick
4405
+ // (attachLeasePullTickListener — the carrier, no new loop), dials each
4406
+ // probe-eligible dead rope PINNED via a MeshRpcClient-built signed
4407
+ // envelope (never the router-forward funnel), classifies the response by
4408
+ // the exact typed G4 canary contract, and feeds recordResult on the ONE
4409
+ // health authority. Dev-gated: recoveryProbeEnabled OMITTED from config
4410
+ // ⇒ live (dry-run) on a development agent, dark on the fleet.
4411
+ _ropeSnapshotSource = () => meshResolver.snapshot();
4412
+ try {
4413
+ const probeEnabled = resolveDevAgentGate(meshCfg?.recoveryProbeEnabled, config);
4414
+ if (probeEnabled && meshEnabled()) {
4415
+ const { RopeRecoveryProber } = await import('../core/RopeRecoveryProber.js');
4416
+ const { buildRopeProbeCommand, parseProbeResponse } = await import('../core/ropeProbeContract.js');
4417
+ const probeClientMod = await import('../core/MeshRpcClient.js');
4418
+ const { getFeatureMetricsRecorder } = await import('../core/CircuitBreakingIntelligenceProvider.js');
4419
+ let probeNonce = 0;
4420
+ const probeClient = new probeClientMod.MeshRpcClient({
4421
+ selfMachineId,
4422
+ sign: (c) => signEd25519(c, idMgr.loadSigningKey()),
4423
+ nonce: () => `${selfMachineId}:rope-probe:${Date.now()}:${++probeNonce}`,
4424
+ });
4425
+ const probeDryRun = meshCfg?.recoveryProbeDryRun !== false;
4426
+ const ropeProber = new RopeRecoveryProber({
4427
+ resolver: meshResolver,
4428
+ // The same validated registry view the transport dials: resolve()
4429
+ // validates URL shape per kind + the LAN-subnet gate, so the probe
4430
+ // can never dial a forbidden host.
4431
+ listTargets: () => {
4432
+ try {
4433
+ const reg = idMgr.loadRegistry();
4434
+ const out = [];
4435
+ for (const [id, e] of Object.entries(reg.machines ?? {})) {
4436
+ if (id === selfMachineId || e.revokedAt)
4437
+ continue;
4438
+ if (!e.lastKnownUrl && (e.endpoints?.length ?? 0) === 0)
4439
+ continue;
4440
+ for (const ep of meshResolver.resolve(id, e.endpoints, (e.lastKnownUrl ?? undefined))) {
4441
+ out.push({ machineId: id, kind: ep.kind, url: ep.url });
4442
+ }
4443
+ }
4444
+ return out;
4445
+ }
4446
+ catch {
4447
+ // @silent-fallback-ok: an unreadable registry yields no probe
4448
+ // targets THIS tick — the next tick re-reads; never a crash on
4449
+ // the lease-pull carrier.
4450
+ return [];
4451
+ }
4452
+ },
4453
+ sendProbe: async (target) => {
4454
+ const started = Date.now();
4455
+ try {
4456
+ const env = probeClient.buildEnvelope({ machineId: target.machineId, url: target.url }, buildRopeProbeCommand(selfMachineId, `${Date.now()}-${++probeNonce}`), leaseCoordinatorRef?.currentEpoch() ?? 0);
4457
+ const res = await fetch(`${target.url.replace(/\/$/, '')}/mesh/rpc`, {
4458
+ method: 'POST',
4459
+ headers: { 'Content-Type': 'application/json' },
4460
+ body: JSON.stringify(env),
4461
+ signal: AbortSignal.timeout(10_000),
4462
+ });
4463
+ const raw = await res.text();
4464
+ const verdict = parseProbeResponse(raw, res.status);
4465
+ return {
4466
+ typedSuccess: verdict.typedSuccess,
4467
+ detail: verdict.detail ? `${verdict.classification}:${verdict.detail}` : verdict.classification,
4468
+ latencyMs: Date.now() - started,
4469
+ };
4470
+ }
4471
+ catch (err) {
4472
+ return {
4473
+ typedSuccess: false,
4474
+ detail: `dial-failed: ${err instanceof Error ? err.message : String(err)}`,
4475
+ latencyMs: Date.now() - started,
4476
+ };
4477
+ }
4478
+ },
4479
+ raiseAttention: (item) => telegram?.createAttentionItem({
4480
+ id: item.id,
4481
+ title: item.title,
4482
+ summary: item.body.slice(0, 160),
4483
+ description: item.body,
4484
+ category: 'rope-recovery-probe',
4485
+ priority: 'NORMAL',
4486
+ sourceContext: 'rope-recovery-probe',
4487
+ }),
4488
+ recordMetric: (event) => {
4489
+ try {
4490
+ getFeatureMetricsRecorder()?.record({
4491
+ feature: 'rope-recovery-probe',
4492
+ kind: 'event',
4493
+ outcome: event === 'probe-failure' || event === 'exhaustion-trip'
4494
+ ? 'error'
4495
+ : event.startsWith('dry-run')
4496
+ ? 'noop'
4497
+ : 'fired',
4498
+ verdictId: event,
4499
+ });
4500
+ }
4501
+ catch {
4502
+ // @silent-fallback-ok: metrics are observability, never authority —
4503
+ // a recorder fault must not break the probe path.
4504
+ }
4505
+ },
4506
+ logger: (m) => console.log(pc.dim(` ${m}`)),
4507
+ }, {
4508
+ dryRun: probeDryRun,
4509
+ floorMs: meshCfg?.recoveryProbeFloorMs ?? 900_000,
4510
+ exhaustAttempts: meshCfg?.recoveryProbeExhaustAttempts ?? 20,
4511
+ reopenEpisodeWindowMs: meshCfg?.recoveryProbeReopenEpisodeWindowMs ?? 600_000,
4512
+ midIntervalMs: meshCfg?.recoveryProbeMidIntervalMs ?? 45_000,
4513
+ maxUnreclaimedSuccesses: meshCfg?.recoveryProbeMaxUnreclaimedSuccesses ?? 20,
4514
+ });
4515
+ _ropeProber = ropeProber;
4516
+ coordinator.attachLeasePullTickListener(() => ropeProber.onTick());
4517
+ coordinator.attachRopeHealthProvider(() => ropeProber.view());
4518
+ console.log(pc.dim(` Rope recovery probe: armed (${probeDryRun ? 'dry-run — sends real probes, never mutates health' : 'LIVE'})`));
4519
+ }
4520
+ else {
4521
+ console.log(pc.dim(' Rope recovery probe: dark (recoveryProbeEnabled resolves off on this agent)'));
4522
+ }
4523
+ }
4524
+ catch (err) {
4525
+ console.warn(pc.yellow(` Rope recovery probe init failed: ${err instanceof Error ? err.message : String(err)}`));
4526
+ }
4397
4527
  // ── Handoff ack/yield wire (spec §8 G3d/G3e) ───────────────
4398
4528
  // The point-to-point channel the two machines use to negotiate a
4399
4529
  // verified, lease-safe planned handoff. The /api/handoff/ack route
@@ -18807,10 +18937,106 @@ export async function startServer(options) {
18807
18937
  console.error(' StrandedTopicSentinel wiring failed (non-fatal):', e instanceof Error ? e.message : String(e));
18808
18938
  }
18809
18939
  }
18940
+ // ── U4.5 — Rope-Health Alerts monitor (docs/specs/u4-5-rope-health-alerts.md) ──
18941
+ // Constructed by the real server boot with its OWN bounded 30s evaluation
18942
+ // loop (R-r2-2), reading the REAL U4.3 resolver snapshot through the hoisted
18943
+ // `_ropeSnapshotSource` seam (never a copy). DEV-GATED: monitoring.ropeHealth
18944
+ // `enabled` is OMITTED from ConfigDefaults so resolveDevAgentGate decides —
18945
+ // LIVE on a development agent day one, DARK on the fleet (route 503s, no
18946
+ // timer). Single-machine installs idle at zero cost (no peers). Torn down in
18947
+ // the shutdown handler. Own try/catch: an init failure leaves it null
18948
+ // (route 503s, deny-safe) and never blocks boot.
18949
+ let ropeHealthMonitor = null;
18950
+ try {
18951
+ const rhCfg = config.monitoring?.ropeHealth;
18952
+ if (resolveDevAgentGate(rhCfg?.enabled, config)) {
18953
+ const { RopeHealthMonitor } = await import('../monitoring/RopeHealthMonitor.js');
18954
+ const { getFeatureMetricsRecorder } = await import('../core/CircuitBreakingIntelligenceProvider.js');
18955
+ const rhSelfId = coordinator?.identity?.machineId ?? machineHeartbeat.config.machineId;
18956
+ ropeHealthMonitor = new RopeHealthMonitor({
18957
+ // U4.3 hard data dependency: the resolver snapshot seam. Null until
18958
+ // the mesh block wires it (single-machine → always []) — the monitor
18959
+ // then idles (UNKNOWN fails toward NOT-urgent).
18960
+ snapshot: () => _ropeSnapshotSource?.() ?? [],
18961
+ selfMachineId: rhSelfId,
18962
+ listPeers: () => (machinePoolRegistry?.getCapacities() ?? [])
18963
+ .filter((c) => c.machineId !== rhSelfId)
18964
+ .map((c) => ({
18965
+ machineId: c.machineId,
18966
+ nickname: c.nickname ?? c.machineId,
18967
+ registryOnline: c.online === true,
18968
+ })),
18969
+ // The mesh-INDEPENDENT liveness discriminator (R-r2-1): the git-synced
18970
+ // coarse MachineHeartbeat file, parsed to epoch-ms.
18971
+ readHeartbeatAtMs: (id) => {
18972
+ const r = machineHeartbeatApi.read(id);
18973
+ if (!r)
18974
+ return null;
18975
+ const t = Date.parse(r.lastHeartbeatAt);
18976
+ return Number.isFinite(t) ? t : null;
18977
+ },
18978
+ raiseAttention: (item) => telegram?.createAttentionItem({
18979
+ id: item.id,
18980
+ title: item.title,
18981
+ summary: item.body.slice(0, 160),
18982
+ description: item.body,
18983
+ category: 'rope-health',
18984
+ priority: 'HIGH',
18985
+ sourceContext: 'rope-health',
18986
+ }),
18987
+ // One episode, one ask: while the lease layer's split-brain surface is
18988
+ // active for this partition, its item wins — the monitor stays quiet.
18989
+ splitBrainItemOpen: () => (coordinator?.getSyncStatus?.().splitBrainState ?? 'clear') !== 'clear',
18990
+ stateFilePath: path.join(config.stateDir, 'state', 'rope-health.json'),
18991
+ recordMetric: (event) => {
18992
+ try {
18993
+ getFeatureMetricsRecorder()?.record({
18994
+ feature: 'rope-health',
18995
+ kind: 'event',
18996
+ outcome: event === 'urgent-episode' || event === 'key-expiry-warning' || event.startsWith('transition-')
18997
+ ? 'fired'
18998
+ : event === 'detected-not-notified-retry'
18999
+ ? 'error'
19000
+ : 'noop',
19001
+ verdictId: event,
19002
+ });
19003
+ }
19004
+ catch {
19005
+ // @silent-fallback-ok: metrics are observability, never authority —
19006
+ // a recorder fault must not break the evaluation loop.
19007
+ }
19008
+ },
19009
+ logger: (m) => console.log(pc.dim(` ${m}`)),
19010
+ }, {
19011
+ urgentEnabled: rhCfg?.urgentEnabled !== false,
19012
+ urgentDebounceMs: rhCfg?.urgentDebounceMs ?? 60_000,
19013
+ clearSustainMs: rhCfg?.clearSustainMs ?? 600_000,
19014
+ keyExpiryWarnDays: rhCfg?.keyExpiryWarnDays ?? 14,
19015
+ wakeGraceMaxMs: rhCfg?.wakeGraceMaxMs ?? 300_000,
19016
+ });
19017
+ // Self-wake grace feed (the ONE thing SleepWakeDetector can tell us —
19018
+ // OWN-machine wake). BOUNDED inside the monitor by wakeGraceMaxMs:
19019
+ // docs/audits/multi-machine-seamless-ux-audit-2026-07.md finding P1-A7
19020
+ // documented 26 FALSE wake events in one night (event-loop stalls
19021
+ // misread as sleeps), so a wake signal is a short grace, never a veto.
19022
+ sleepWakeDetector.on('wake', () => ropeHealthMonitor?.noteOwnWake());
19023
+ ropeHealthMonitor.start();
19024
+ console.log(pc.dim(' Rope-health monitor: live (own 30s evaluation loop)'));
19025
+ }
19026
+ else {
19027
+ console.log(pc.dim(' Rope-health monitor: dark (monitoring.ropeHealth resolves off on this agent)'));
19028
+ }
19029
+ }
19030
+ catch (err) {
19031
+ // @silent-fallback-ok — reported via console.warn; init failure leaves the
19032
+ // monitor null → route 503s (deny-safe), never blocks boot.
19033
+ console.warn(pc.yellow(` Rope-health monitor init failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`));
19034
+ ropeHealthMonitor = null;
19035
+ }
18810
19036
  const server = new AgentServer({ config, sessionManager, state, scheduler, telegram, relationships, feedback, feedbackAnomalyDetector, dispatches, updateChecker, autoUpdater, autoDispatcher, quotaTracker, quotaManager, publisher, viewer, tunnel, evolution, watchdog, topicMemory, triageNurse, projectMapper, cartographer: cartographer ?? undefined, coherenceGate: scopeVerifier, contextHierarchy, canonicalState, operationGate, sentinel, adaptiveTrust, memoryMonitor, orphanReaper, coherenceMonitor, commitmentTracker, subscriptionPool, accountFollowMePeerViews: async () => { const nickById = new Map((_listPoolMachines?.() ?? []).map((m) => [m.machineId, m.nickname ?? m.machineId])); let peers = (_resolvePeerUrls?.() ?? []).map((p) => ({ machineId: p.machineId, nickname: nickById.get(p.machineId) ?? p.machineId, url: p.url })); if (peers.length === 0) {
18811
19037
  peers = (_listPoolMachines?.() ?? []).filter((m) => m.machineId !== _meshSelfId && !!m.lastKnownUrl).map((m) => ({ machineId: m.machineId, nickname: m.nickname ?? m.machineId, url: m.lastKnownUrl }));
18812
19038
  } if (peers.length === 0)
18813
- return []; const { fetchPeerSubscriptionViews } = await import('../core/fetchPeerSubscriptionViews.js'); return fetchPeerSubscriptionViews({ peers: () => peers, fetchImpl: fetch, authToken: config.authToken ?? '' }); }, quotaPoller, quotaAwareScheduler: _quotaAwareScheduler ?? undefined, proactiveSwapMonitor: _proactiveSwapMonitor ?? undefined, inUseAccountResolver, enrollmentWizard, accountFollowMeRevocation, credentialRepointing, semanticMemory, activitySentinel, rateLimitSentinel, releaseReadinessSentinel: releaseReadinessSentinel ?? undefined, greenPrAutoMerger: greenPrAutoMerger ?? undefined, guardLatchStore: guardLatchStore ?? undefined, messageRouter, summarySentinel, spawnManager, systemReviewer, capabilityMapper, selfKnowledgeTree, coverageAuditor, topicResumeMap: _topicResumeMap ?? undefined, topicProfile: _topicProfileCtx ?? undefined, sessionRefresh: _sessionRefresh ?? undefined, autonomyManager, trustElevationTracker, autonomousEvolution, coordinator: coordinator.enabled ? coordinator : undefined, meshBindActive: coordinator.managers.identityManager.hasIdentity() && config.multiMachine?.meshTransport?.enabled !== false, localSigningKeyPem, leaseTransport, peerEndpointRecorder, getSelfMeshEndpoints, onLeasePullRequest: () => leaseCoordinatorRef?.currentLease() ?? null, liveTailReceiver, handoffWireTransport, onHandoffBegin, onHandoffInitiate: handoffInitiate, handoffInProgress: handoffSentinelInProgress, messageLedger, currentInboundByTopic, replyMarkerTransport, onReplyMarker: messageLedger ? (marker) => { const m = marker; messageLedger.applyRemoteReplyMarker(m.dedupeKey, { platform: m.platform, replyIdempotencyKey: m.replyIdempotencyKey, epoch: m.epoch, topic: m.topic ?? null }); } : undefined, whatsapp: whatsappAdapter, slack: slackAdapter, imessage: imessageAdapter, whatsappBusinessBackend, messageBridge, hookEventReceiver, worktreeMonitor, subagentTracker, instructionsVerifier, handshakeManager: threadlineHandshake, threadlineRouter, conversationStore, threadLog, threadMessageRecorder, warrantsReplyGate, collaborationSurfacer, threadResumeMap, topicLinkageHandler: topicLinkageHandler ?? undefined, threadlineRelayClient, threadlineReplyWaiters, listenerManager: listenerManager ?? undefined, a2aDeliveryTracker: a2aDeliveryTracker ?? undefined, responseReviewGate, messagingToneGate, outboundDedupGate, telemetryHeartbeat, pasteManager, featureRegistry, discoveryEvaluator, completionEvaluator, unifiedTrust, liveConfig, sharedStateLedger, ledgerSessionRegistry, worktreeManager, oidcEnrolledRepos: parallelDevConfig?.oidcEnrolledRepos, initiativeTracker, projectRoundRunner, projectDriftChecker, machineHeartbeat, machinePoolRegistry, getInboundQueue: () => _inboundQueue, meshRpcDispatcher, workingSetPullCoordinator, commitmentReplicaStore, preferenceReplicaStore, replicatedRecordEmitter, conflictStore, rollbackUnmerge, droppedOriginRegistry, preferencesUnionReader, forwardCommitmentMutate, sessionOwnershipRegistry, topicPinStore: _topicPinStore ?? undefined, ownershipReconciler: _ownershipReconciler ?? undefined, streamTicketStore: _streamTicketStore ?? undefined, poolStreamAllowRemoteInput: config.dashboard?.poolStream?.allowRemoteInput ?? false, poolStreamConnector: _poolStreamConnector ?? undefined, secretSync: _secretSyncHandle ?? undefined, meshSelfId: _meshSelfId ?? undefined, resolveRouterUrl: _resolveRouterUrl ?? undefined, resolvePeerUrls: _resolvePeerUrls ?? undefined, guardRegistry, listPoolMachines: _listPoolMachines ?? undefined, deliverMandateToMachine: _deliverMandateToMachine ?? undefined, poolLink: _poolLink ?? undefined, poolPollCache: _poolPollCache ?? undefined, sessionPoolE2EResultStore, proxyCoordinator, topicIntentStore, topicIntentArcCheck, usherSignalStore, intelligence: sharedIntelligence ?? undefined, telegramBridgeConfig, telegramBridge: telegramBridge ?? undefined, threadlineObservability, briefDeps, workingMemory, taskFlowRegistry, threadlineFlowBridge, sessionReaper, agentWorktreeReaper, orphanedWorkSentinel, mcpProcessReaper, geminiLoopRunner, sleepController, agentActivityState, reapLog, resumeQueue, resumeDrainer, autonomousLivenessReconciler, enforcedTerminationStatus: () => enforcedTerminationWatchdog?.guardStatus() ?? null, prHandLease: prHandLease ?? undefined, operatorStopRecorder: recordOperatorStop, sleepWakeDetector, unjustifiedStopGate, stopGateDb, stopNotifier, liveTestGate, liveTestGateMode, liveTestRunnerCtx }); // Resolve the late-bound topic-operator getter (increment 2e): routing was
19039
+ return []; const { fetchPeerSubscriptionViews } = await import('../core/fetchPeerSubscriptionViews.js'); return fetchPeerSubscriptionViews({ peers: () => peers, fetchImpl: fetch, authToken: config.authToken ?? '' }); }, quotaPoller, quotaAwareScheduler: _quotaAwareScheduler ?? undefined, proactiveSwapMonitor: _proactiveSwapMonitor ?? undefined, inUseAccountResolver, enrollmentWizard, accountFollowMeRevocation, credentialRepointing, semanticMemory, activitySentinel, rateLimitSentinel, releaseReadinessSentinel: releaseReadinessSentinel ?? undefined, greenPrAutoMerger: greenPrAutoMerger ?? undefined, guardLatchStore: guardLatchStore ?? undefined, messageRouter, summarySentinel, spawnManager, systemReviewer, capabilityMapper, selfKnowledgeTree, coverageAuditor, topicResumeMap: _topicResumeMap ?? undefined, topicProfile: _topicProfileCtx ?? undefined, sessionRefresh: _sessionRefresh ?? undefined, autonomyManager, trustElevationTracker, autonomousEvolution, coordinator: coordinator.enabled ? coordinator : undefined, meshBindActive: coordinator.managers.identityManager.hasIdentity() && config.multiMachine?.meshTransport?.enabled !== false, localSigningKeyPem, leaseTransport, peerEndpointRecorder, getSelfMeshEndpoints, onLeasePullRequest: () => leaseCoordinatorRef?.currentLease() ?? null, liveTailReceiver, handoffWireTransport, onHandoffBegin, onHandoffInitiate: handoffInitiate, handoffInProgress: handoffSentinelInProgress, messageLedger, currentInboundByTopic, replyMarkerTransport, onReplyMarker: messageLedger ? (marker) => { const m = marker; messageLedger.applyRemoteReplyMarker(m.dedupeKey, { platform: m.platform, replyIdempotencyKey: m.replyIdempotencyKey, epoch: m.epoch, topic: m.topic ?? null }); } : undefined, whatsapp: whatsappAdapter, slack: slackAdapter, imessage: imessageAdapter, whatsappBusinessBackend, messageBridge, hookEventReceiver, worktreeMonitor, subagentTracker, instructionsVerifier, handshakeManager: threadlineHandshake, threadlineRouter, conversationStore, threadLog, threadMessageRecorder, warrantsReplyGate, collaborationSurfacer, threadResumeMap, topicLinkageHandler: topicLinkageHandler ?? undefined, threadlineRelayClient, threadlineReplyWaiters, listenerManager: listenerManager ?? undefined, a2aDeliveryTracker: a2aDeliveryTracker ?? undefined, responseReviewGate, messagingToneGate, outboundDedupGate, telemetryHeartbeat, pasteManager, featureRegistry, discoveryEvaluator, completionEvaluator, unifiedTrust, liveConfig, sharedStateLedger, ledgerSessionRegistry, worktreeManager, oidcEnrolledRepos: parallelDevConfig?.oidcEnrolledRepos, initiativeTracker, projectRoundRunner, projectDriftChecker, machineHeartbeat, machinePoolRegistry, ropeHealthMonitor, getInboundQueue: () => _inboundQueue, meshRpcDispatcher, workingSetPullCoordinator, commitmentReplicaStore, preferenceReplicaStore, replicatedRecordEmitter, conflictStore, rollbackUnmerge, droppedOriginRegistry, preferencesUnionReader, forwardCommitmentMutate, sessionOwnershipRegistry, topicPinStore: _topicPinStore ?? undefined, ownershipReconciler: _ownershipReconciler ?? undefined, streamTicketStore: _streamTicketStore ?? undefined, poolStreamAllowRemoteInput: config.dashboard?.poolStream?.allowRemoteInput ?? false, poolStreamConnector: _poolStreamConnector ?? undefined, secretSync: _secretSyncHandle ?? undefined, meshSelfId: _meshSelfId ?? undefined, resolveRouterUrl: _resolveRouterUrl ?? undefined, resolvePeerUrls: _resolvePeerUrls ?? undefined, guardRegistry, listPoolMachines: _listPoolMachines ?? undefined, deliverMandateToMachine: _deliverMandateToMachine ?? undefined, poolLink: _poolLink ?? undefined, poolPollCache: _poolPollCache ?? undefined, sessionPoolE2EResultStore, proxyCoordinator, topicIntentStore, topicIntentArcCheck, usherSignalStore, intelligence: sharedIntelligence ?? undefined, telegramBridgeConfig, telegramBridge: telegramBridge ?? undefined, threadlineObservability, briefDeps, workingMemory, taskFlowRegistry, threadlineFlowBridge, sessionReaper, agentWorktreeReaper, orphanedWorkSentinel, mcpProcessReaper, geminiLoopRunner, sleepController, agentActivityState, reapLog, resumeQueue, resumeDrainer, autonomousLivenessReconciler, enforcedTerminationStatus: () => enforcedTerminationWatchdog?.guardStatus() ?? null, prHandLease: prHandLease ?? undefined, operatorStopRecorder: recordOperatorStop, sleepWakeDetector, unjustifiedStopGate, stopGateDb, stopNotifier, liveTestGate, liveTestGateMode, liveTestRunnerCtx }); // Resolve the late-bound topic-operator getter (increment 2e): routing was
18814
19040
  // wired before the server existed; from here on inbound binds use the
18815
19041
  // server's own store instance.
18816
19042
  _agentServerRef = server;
@@ -19592,6 +19818,7 @@ export async function startServer(options) {
19592
19818
  registrySyncDebouncer?.stop();
19593
19819
  gitSync?.stop();
19594
19820
  coordinator.stop();
19821
+ ropeHealthMonitor?.stop();
19595
19822
  coherenceMonitor.stop();
19596
19823
  commitmentTracker.stop();
19597
19824
  commitmentSentinel?.stop();