@adhdev/daemon-core 1.0.28-rc.12 → 1.0.28-rc.14
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/index.js +99 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +99 -7
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/mesh-completion-synthesis.d.ts +25 -0
- package/dist/providers/busy-lease-gate.d.ts +25 -0
- package/dist/providers/cli-provider-instance.d.ts +9 -0
- package/dist/providers/transcript-signal-source.d.ts +45 -0
- package/package.json +3 -3
- package/src/mesh/mesh-completion-synthesis.ts +36 -0
- package/src/mesh/mesh-reconcile-loop.ts +8 -1
- package/src/providers/busy-lease-gate.ts +66 -0
- package/src/providers/cli-provider-instance.ts +51 -0
- package/src/providers/transcript-signal-source.ts +60 -0
package/dist/index.js
CHANGED
|
@@ -791,10 +791,10 @@ function readInjected(value) {
|
|
|
791
791
|
}
|
|
792
792
|
function getDaemonBuildInfo() {
|
|
793
793
|
if (cached) return cached;
|
|
794
|
-
const commit = readInjected(true ? "
|
|
795
|
-
const commitShort = readInjected(true ? "
|
|
796
|
-
const version = readInjected(true ? "1.0.28-rc.
|
|
797
|
-
const builtAt = readInjected(true ? "2026-07-
|
|
794
|
+
const commit = readInjected(true ? "a13de2dc4d24bfeb8d0e512a76f5e50d5e7cb05d" : void 0) ?? "unknown";
|
|
795
|
+
const commitShort = readInjected(true ? "a13de2dc" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
796
|
+
const version = readInjected(true ? "1.0.28-rc.14" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
797
|
+
const builtAt = readInjected(true ? "2026-07-26T10:04:17.736Z" : void 0);
|
|
798
798
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
799
799
|
return cached;
|
|
800
800
|
}
|
|
@@ -24943,7 +24943,7 @@ async function pollAssignedTaskInTurnProgress(components, mesh, row) {
|
|
|
24943
24943
|
return ts2 >= dispatchedAtMs;
|
|
24944
24944
|
});
|
|
24945
24945
|
}
|
|
24946
|
-
async function pollAssignedTaskTerminalEvidence(components, mesh, row) {
|
|
24946
|
+
async function pollAssignedTaskTerminalEvidence(components, mesh, row, opts) {
|
|
24947
24947
|
const sessionId = readNonEmptyString(row.assignedSessionId);
|
|
24948
24948
|
const nodeId = readNonEmptyString(row.assignedNodeId);
|
|
24949
24949
|
if (!sessionId || !nodeId) return null;
|
|
@@ -24960,6 +24960,9 @@ async function pollAssignedTaskTerminalEvidence(components, mesh, row) {
|
|
|
24960
24960
|
if (!(Number.isFinite(dispatchedAtMs) && Number.isFinite(transcriptAtMs) && transcriptAtMs >= dispatchedAtMs)) {
|
|
24961
24961
|
return null;
|
|
24962
24962
|
}
|
|
24963
|
+
if (typeof opts?.minFinalAssistantAgeMs === "number" && opts.minFinalAssistantAgeMs > 0 && Date.now() - transcriptAtMs < opts.minFinalAssistantAgeMs) {
|
|
24964
|
+
return null;
|
|
24965
|
+
}
|
|
24963
24966
|
return {
|
|
24964
24967
|
outcome: "completed",
|
|
24965
24968
|
finalSummary: evidence.finalSummary,
|
|
@@ -25359,7 +25362,9 @@ async function recoverStrandedAssignedDispatches(components, mesh, store, localD
|
|
|
25359
25362
|
if (since === void 0) {
|
|
25360
25363
|
assignedIdleFinalAssistantSince.set(idleTranscriptStreakKey, nowMs);
|
|
25361
25364
|
} else if (nowMs - since >= ASSIGNED_IDLE_TRANSCRIPT_COMPLETE_MS) {
|
|
25362
|
-
const terminalEvidence = await pollAssignedTaskTerminalEvidence(components, mesh, row
|
|
25365
|
+
const terminalEvidence = await pollAssignedTaskTerminalEvidence(components, mesh, row, {
|
|
25366
|
+
minFinalAssistantAgeMs: ASSIGNED_IDLE_TRANSCRIPT_COMPLETE_MS
|
|
25367
|
+
});
|
|
25363
25368
|
if (terminalEvidence) {
|
|
25364
25369
|
assignedIdleFinalAssistantSince.delete(idleTranscriptStreakKey);
|
|
25365
25370
|
updateTaskStatus(meshId, row.id, terminalEvidence.outcome);
|
|
@@ -46404,6 +46409,20 @@ init_transcript_evidence();
|
|
|
46404
46409
|
|
|
46405
46410
|
// src/providers/transcript-signal-source.ts
|
|
46406
46411
|
init_logger();
|
|
46412
|
+
|
|
46413
|
+
// src/providers/busy-lease-gate.ts
|
|
46414
|
+
var BUSY_LEASE_BOUND_MS = 18e4;
|
|
46415
|
+
var DEFAULT_CANARY_PROVIDERS = ["kimi", "codex-cli"];
|
|
46416
|
+
function resolveBusyLeaseGate(providerType, env = process.env) {
|
|
46417
|
+
const boundRaw = Number(env.ADHDEV_TX_BUSY_LEASE_BOUND_MS);
|
|
46418
|
+
const boundMs = Number.isFinite(boundRaw) && boundRaw > 0 ? Math.floor(boundRaw) : BUSY_LEASE_BOUND_MS;
|
|
46419
|
+
const listRaw = env.ADHDEV_TX_BUSY_LEASE_PROVIDERS;
|
|
46420
|
+
const list = (typeof listRaw === "string" ? listRaw : DEFAULT_CANARY_PROVIDERS.join(",")).split(",").map((s2) => s2.trim()).filter(Boolean);
|
|
46421
|
+
const type = (providerType ?? "").trim();
|
|
46422
|
+
return { enabled: type.length > 0 && list.includes(type), boundMs };
|
|
46423
|
+
}
|
|
46424
|
+
|
|
46425
|
+
// src/providers/transcript-signal-source.ts
|
|
46407
46426
|
init_signal_envelope();
|
|
46408
46427
|
var TranscriptSignalSource = class {
|
|
46409
46428
|
constructor(opts) {
|
|
@@ -46411,6 +46430,10 @@ var TranscriptSignalSource = class {
|
|
|
46411
46430
|
}
|
|
46412
46431
|
/** msgCount seen at the previous update — drives in_turn_progress. */
|
|
46413
46432
|
prevMsgCount = -1;
|
|
46433
|
+
/** TX-FSM Stage 2: wall-clock of the most recent sample that proved the
|
|
46434
|
+
* transcript live (in_turn_progress === true — a count advance OR mtime
|
|
46435
|
+
* inside the growth-quiet window). -1 = the lease was never issued. */
|
|
46436
|
+
lastLiveSampleAt = -1;
|
|
46414
46437
|
/** Fingerprint of the last LOGGED snapshot, so the shadow log fires on
|
|
46415
46438
|
* change only (a quiet session must not spam one line per read). */
|
|
46416
46439
|
lastLoggedFingerprint = "";
|
|
@@ -46459,6 +46482,7 @@ var TranscriptSignalSource = class {
|
|
|
46459
46482
|
const inTurnProgress = countAdvanced || fresh;
|
|
46460
46483
|
const transcriptGrowing = ageMs === null ? null : fresh;
|
|
46461
46484
|
this.prevMsgCount = msgCount;
|
|
46485
|
+
if (inTurnProgress) this.lastLiveSampleAt = now;
|
|
46462
46486
|
return {
|
|
46463
46487
|
kind: SIGNAL_SNAPSHOT_KIND,
|
|
46464
46488
|
sampledAt: now,
|
|
@@ -46472,6 +46496,33 @@ var TranscriptSignalSource = class {
|
|
|
46472
46496
|
detail: { msgCount, sourceMtimeMs, ageMs }
|
|
46473
46497
|
};
|
|
46474
46498
|
}
|
|
46499
|
+
/**
|
|
46500
|
+
* TX-FSM Stage 2 — the bounded busy lease, derived from the SAME sample
|
|
46501
|
+
* stream that produces the envelope (zero added I/O, pure memory read).
|
|
46502
|
+
*
|
|
46503
|
+
* Semantics: every sample whose in_turn_progress is true (re)issues the
|
|
46504
|
+
* lease at that sample's wall-clock; the lease stays ACTIVE for
|
|
46505
|
+
* leaseBoundMs after the LAST such sample and then EXPIRES. The bound is
|
|
46506
|
+
* the whole point: the lease extends busy across PTY-quiet stretches while
|
|
46507
|
+
* the transcript is demonstrably alive, but it can never hold busy
|
|
46508
|
+
* indefinitely — after expiry the consumer must resume its normal
|
|
46509
|
+
* (pre-lease) judgment, so a finished-but-wedged session escapes on the
|
|
46510
|
+
* bound, not on a transcript event that may never come.
|
|
46511
|
+
*
|
|
46512
|
+
* Fail-open by construction: a non-native-source class, an unresolved
|
|
46513
|
+
* transcript, or a read error never reaches the issuance line, so the
|
|
46514
|
+
* lease is simply never issued (active:false, lastLiveAt:null) — a
|
|
46515
|
+
* missing lease must never wedge a session or fabricate one.
|
|
46516
|
+
*/
|
|
46517
|
+
busyLease(now = Date.now()) {
|
|
46518
|
+
if (this.lastLiveSampleAt < 0) {
|
|
46519
|
+
return { active: false, lastLiveAt: null, expiresAt: null, remainingMs: 0 };
|
|
46520
|
+
}
|
|
46521
|
+
const bound = this.opts.leaseBoundMs ?? BUSY_LEASE_BOUND_MS;
|
|
46522
|
+
const expiresAt = this.lastLiveSampleAt + bound;
|
|
46523
|
+
const remainingMs = Math.max(0, expiresAt - now);
|
|
46524
|
+
return { active: remainingMs > 0, lastLiveAt: this.lastLiveSampleAt, expiresAt, remainingMs };
|
|
46525
|
+
}
|
|
46475
46526
|
/** Stage-0 shadow log: emit one line when the normalized observation
|
|
46476
46527
|
* CHANGES. This log is the Stage 1-3 judgment input ("which signals were
|
|
46477
46528
|
* actually observable, and when"), so it carries the full signal set —
|
|
@@ -51909,7 +51960,11 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
51909
51960
|
// final_assistant_present signal rather than duplicating
|
|
51910
51961
|
// the message scan.
|
|
51911
51962
|
finalAssistantPresent: (msgs, ts2) => this.completionHasFinalAssistantMessage(msgs, ts2),
|
|
51912
|
-
growthQuietMs: MISSING_ASSISTANT_TRANSCRIPT_GROWTH_QUIET_MS
|
|
51963
|
+
growthQuietMs: MISSING_ASSISTANT_TRANSCRIPT_GROWTH_QUIET_MS,
|
|
51964
|
+
// TX-FSM Stage 2: the lease bound follows the rollout gate's
|
|
51965
|
+
// (possibly env-overridden) value; the gate's enabled flag is
|
|
51966
|
+
// consulted per judgment, not here.
|
|
51967
|
+
leaseBoundMs: resolveBusyLeaseGate(this.type).boundMs
|
|
51913
51968
|
});
|
|
51914
51969
|
}
|
|
51915
51970
|
const snapshot = this.transcriptSignalSource.update(
|
|
@@ -52510,6 +52565,21 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
52510
52565
|
}
|
|
52511
52566
|
return { snapshot: this.lastTranscriptSignalSnapshot, messages };
|
|
52512
52567
|
}
|
|
52568
|
+
/**
|
|
52569
|
+
* TX-FSM Stage 2: is the bounded busy lease enabled for THIS provider?
|
|
52570
|
+
* This is the canary rollout gate (busy-lease-gate.ts) — a per-provider
|
|
52571
|
+
* feature switch, NOT a classification (transcript class/timing still come
|
|
52572
|
+
* from resolveTranscriptAuthorityProfile only). Resolved per call so an
|
|
52573
|
+
* env-driven rollout change takes effect without rebuilding the instance;
|
|
52574
|
+
* any resolver error fails closed (lease disabled → pre-Stage-2 behavior).
|
|
52575
|
+
*/
|
|
52576
|
+
busyLeaseGateEnabled() {
|
|
52577
|
+
try {
|
|
52578
|
+
return resolveBusyLeaseGate(this.type).enabled;
|
|
52579
|
+
} catch {
|
|
52580
|
+
return false;
|
|
52581
|
+
}
|
|
52582
|
+
}
|
|
52513
52583
|
/**
|
|
52514
52584
|
* KIMI-MESH-COMPLETION-EMIT (axis 2). Last-chance completion emit for a mesh
|
|
52515
52585
|
* DELEGATED worker whose PTY has already exited (e.g. killed by a false stall)
|
|
@@ -52936,6 +53006,28 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
52936
53006
|
this.scheduleCompletedDebounceFlush(COMPLETED_FINALIZATION_RETRY_MS);
|
|
52937
53007
|
return;
|
|
52938
53008
|
}
|
|
53009
|
+
if (growthSnapshot?.available === true && this.busyLeaseGateEnabled()) {
|
|
53010
|
+
const lease = this.transcriptSignalSource?.busyLease() ?? null;
|
|
53011
|
+
if (lease?.active === true) {
|
|
53012
|
+
if (pending.loggedBlockReason !== "busy_lease_active") {
|
|
53013
|
+
LOG.info("CLI", `[${this.type}] holding pending completed (busy_lease_active: lastLiveAt=${lease.lastLiveAt} expiresIn=${lease.remainingMs}ms) \u2014 transcript live within the lease bound, screen-idle verdict not trusted`);
|
|
53014
|
+
if (this.isMeshWorkerSession()) {
|
|
53015
|
+
traceMeshEventDrop("completion_gate_hold", this.meshTraceCtx(), `busy_lease_active lastLiveAt=${lease.lastLiveAt} expiresIn=${lease.remainingMs}ms`);
|
|
53016
|
+
}
|
|
53017
|
+
if (this.completionTraceOn()) this.recordCompletionGateTrace("hold", {
|
|
53018
|
+
blockReason: "busy_lease_active",
|
|
53019
|
+
latestVisibleStatus,
|
|
53020
|
+
leaseLastLiveAt: lease.lastLiveAt,
|
|
53021
|
+
leaseExpiresAt: lease.expiresAt,
|
|
53022
|
+
leaseRemainingMs: lease.remainingMs,
|
|
53023
|
+
waitedMs
|
|
53024
|
+
});
|
|
53025
|
+
pending.loggedBlockReason = "busy_lease_active";
|
|
53026
|
+
}
|
|
53027
|
+
this.scheduleCompletedDebounceFlush(COMPLETED_FINALIZATION_RETRY_MS);
|
|
53028
|
+
return;
|
|
53029
|
+
}
|
|
53030
|
+
}
|
|
52939
53031
|
}
|
|
52940
53032
|
if (!isTranscriptEvidenceGate && (block2.terminal || waitedMs < COMPLETED_FINALIZATION_MAX_WAIT_MS)) {
|
|
52941
53033
|
if (pending.loggedBlockReason !== blockReason) {
|