@adhdev/daemon-core 0.9.82-rc.404 → 0.9.82-rc.405

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.
@@ -87,6 +87,7 @@ export declare class CliProviderInstance implements ProviderInstance {
87
87
  private agentReadyEmitted;
88
88
  private generatingStartedAt;
89
89
  private fastCollapseSynthesizedTaskId;
90
+ private startupGraceCollapseAt;
90
91
  private settings;
91
92
  private monitor;
92
93
  private generatingDebounceTimer;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adhdev/daemon-core",
3
- "version": "0.9.82-rc.404",
3
+ "version": "0.9.82-rc.405",
4
4
  "description": "ADHDev daemon core — CDP, IDE detection, providers, command execution",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -46,7 +46,7 @@
46
46
  "author": "vilmire",
47
47
  "license": "AGPL-3.0-or-later",
48
48
  "dependencies": {
49
- "@adhdev/mesh-shared": "0.9.82-rc.404",
49
+ "@adhdev/mesh-shared": "0.9.82-rc.405",
50
50
  "@adhdev/session-host-core": "*",
51
51
  "@agentclientprotocol/sdk": "^0.16.1",
52
52
  "ajv": "^8.20.0",
@@ -140,15 +140,18 @@ const NATIVE_HISTORY_MESH_IDLE_SETTLE_MS = 4000;
140
140
  // DUPLICATE_DISPATCH_WINDOW_MS (mesh-tools) so the daemon's bubble-level guard
141
141
  // covers the same retry horizon as the MCP-level dispatch dedup.
142
142
  const USER_INPUT_ACK_DEDUP_WINDOW_MS = 60_000;
143
- // GENERATING-BOUNDARY (R4b): age-since-boot window inside which a "first turn that
144
- // ran+completed without the FSM ever observing a 'generating' frame" is attributed
145
- // to the startup-grace collapse and synthesized (reason 'startup_grace_idle_turn_collapse').
146
- // The spec's startup-grace exit is elapsed_ms=8000; a turn dispatched into that window
147
- // can complete a little after it drains, so the window is the 8s grace plus a settle
148
- // buffer. The strong discriminator is generatingStartedAt===0 (generating was never
149
- // observed) AND a started-but-finished turn the window only keeps the synthesized
150
- // reason honest and scopes the synthesis to boot, so a much-later unobservably-fast turn
151
- // is not mislabelled a startup collapse.
143
+ // GENERATING-BOUNDARY (R4c): window measured from the startup-grace COLLAPSE moment
144
+ // (startupGraceCollapseAt), not boot inside which a "first turn that ran+completed
145
+ // without the FSM ever observing a 'generating' frame" is attributed to the startup-grace
146
+ // collapse and synthesized (reason 'startup_grace_idle_turn_collapse').
147
+ // The spec's startup-grace exit is elapsed_ms=8000, so the FSM spends ~8s in 'starting'
148
+ // before collapsing to idle; a turn can be dispatched a few seconds AFTER that collapse
149
+ // (the live R4b miss: collapse at boot+8s, dispatch at boot+12.4s already past a 12s
150
+ // boot-anchored window before the turn even started). Anchoring on the collapse moment
151
+ // makes the window cover dispatch-delay + turn-duration. The strong discriminator is
152
+ // generatingStartedAt===0 (generating was never observed) AND a started-but-finished turn
153
+ // — the window only keeps the synthesized reason honest and scopes the synthesis to the
154
+ // boot collapse, so a much-later unobservably-fast turn is not mislabelled a startup collapse.
152
155
  const STARTUP_GRACE_IDLE_COLLAPSE_WINDOW_MS = 12_000;
153
156
 
154
157
  /** Events that signal a dispatched mesh task has reached a terminal state.
@@ -481,6 +484,16 @@ export class CliProviderInstance implements ProviderInstance {
481
484
  // steadily while the session sits idle, so this guard makes the synthesis fire
482
485
  // AT MOST ONCE per collapsed turn.
483
486
  private fastCollapseSynthesizedTaskId: string | null = null;
487
+ // GENERATING-BOUNDARY (R4c): the wall-clock moment the FSM's starting→idle
488
+ // startup-grace collapse was observed (set ONCE, on the first starting→idle
489
+ // transition this boot). The idle-stayed collapse window is anchored on THIS,
490
+ // not on instance/boot time (this.startedAt): the FSM spends the full 8s
491
+ // startup-grace sitting in 'starting' before collapsing, and a turn can be
492
+ // dispatched a few seconds AFTER the collapse — measuring the window from boot
493
+ // would have it already closed by the time that turn lands+completes (the live
494
+ // R4b miss: collapse at boot+8s, dispatch at boot+12.4s > the 12s boot window).
495
+ // Anchoring on the collapse moment makes the window cover dispatch-delay+turn.
496
+ private startupGraceCollapseAt: number | null = null;
484
497
  private settings: Record<string, any> = {};
485
498
  private monitor: StatusMonitor;
486
499
  private generatingDebounceTimer: NodeJS.Timeout | null = null;
@@ -2382,6 +2395,11 @@ export class CliProviderInstance implements ProviderInstance {
2382
2395
  }
2383
2396
  } else if (newStatus === 'idle' && this.lastStatus === 'starting') {
2384
2397
  this.emitAgentReadyOnce(chatTitle, now);
2398
+ // GENERATING-BOUNDARY (R4c): stamp the collapse moment ONCE so the
2399
+ // idle-stayed window below is anchored on the startup-grace collapse,
2400
+ // not on boot. Set only the first time so a later starting re-entry
2401
+ // cannot slide the window forward.
2402
+ if (this.startupGraceCollapseAt === null) this.startupGraceCollapseAt = now;
2385
2403
  // GENERATING-BOUNDARY fast-collapse (R4, win32 startup-grace first turn):
2386
2404
  // a turn dispatched into the startup-grace window can START and FINISH while
2387
2405
  // the FSM is still in 'starting'. On a daemon whose claude-cli spec has NOT yet
@@ -2453,7 +2471,8 @@ export class CliProviderInstance implements ProviderInstance {
2453
2471
  if (
2454
2472
  newStatus === 'idle'
2455
2473
  && previousStatus === 'idle'
2456
- && (now - this.startedAt) < STARTUP_GRACE_IDLE_COLLAPSE_WINDOW_MS
2474
+ && this.startupGraceCollapseAt !== null
2475
+ && (now - this.startupGraceCollapseAt) < STARTUP_GRACE_IDLE_COLLAPSE_WINDOW_MS
2457
2476
  ) {
2458
2477
  this.maybeSynthesizeStartupGraceCollapse(chatTitle, now, 'startup_grace_idle_turn_collapse');
2459
2478
  }