@adhdev/daemon-core 1.0.28-rc.13 → 1.0.28-rc.15
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.mjs
CHANGED
|
@@ -786,10 +786,10 @@ function readInjected(value) {
|
|
|
786
786
|
}
|
|
787
787
|
function getDaemonBuildInfo() {
|
|
788
788
|
if (cached) return cached;
|
|
789
|
-
const commit = readInjected(true ? "
|
|
790
|
-
const commitShort = readInjected(true ? "
|
|
791
|
-
const version = readInjected(true ? "1.0.28-rc.
|
|
792
|
-
const builtAt = readInjected(true ? "2026-07-
|
|
789
|
+
const commit = readInjected(true ? "3c6684c9e2549bf7ab1508195857595a89ae9ec1" : void 0) ?? "unknown";
|
|
790
|
+
const commitShort = readInjected(true ? "3c6684c" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
791
|
+
const version = readInjected(true ? "1.0.28-rc.15" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
792
|
+
const builtAt = readInjected(true ? "2026-07-26T13:11:34.159Z" : void 0);
|
|
793
793
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
794
794
|
return cached;
|
|
795
795
|
}
|
|
@@ -24951,7 +24951,7 @@ async function pollAssignedTaskInTurnProgress(components, mesh, row) {
|
|
|
24951
24951
|
return ts2 >= dispatchedAtMs;
|
|
24952
24952
|
});
|
|
24953
24953
|
}
|
|
24954
|
-
async function pollAssignedTaskTerminalEvidence(components, mesh, row) {
|
|
24954
|
+
async function pollAssignedTaskTerminalEvidence(components, mesh, row, opts) {
|
|
24955
24955
|
const sessionId = readNonEmptyString(row.assignedSessionId);
|
|
24956
24956
|
const nodeId = readNonEmptyString(row.assignedNodeId);
|
|
24957
24957
|
if (!sessionId || !nodeId) return null;
|
|
@@ -24968,6 +24968,9 @@ async function pollAssignedTaskTerminalEvidence(components, mesh, row) {
|
|
|
24968
24968
|
if (!(Number.isFinite(dispatchedAtMs) && Number.isFinite(transcriptAtMs) && transcriptAtMs >= dispatchedAtMs)) {
|
|
24969
24969
|
return null;
|
|
24970
24970
|
}
|
|
24971
|
+
if (typeof opts?.minFinalAssistantAgeMs === "number" && opts.minFinalAssistantAgeMs > 0 && Date.now() - transcriptAtMs < opts.minFinalAssistantAgeMs) {
|
|
24972
|
+
return null;
|
|
24973
|
+
}
|
|
24971
24974
|
return {
|
|
24972
24975
|
outcome: "completed",
|
|
24973
24976
|
finalSummary: evidence.finalSummary,
|
|
@@ -25367,7 +25370,9 @@ async function recoverStrandedAssignedDispatches(components, mesh, store, localD
|
|
|
25367
25370
|
if (since === void 0) {
|
|
25368
25371
|
assignedIdleFinalAssistantSince.set(idleTranscriptStreakKey, nowMs);
|
|
25369
25372
|
} else if (nowMs - since >= ASSIGNED_IDLE_TRANSCRIPT_COMPLETE_MS) {
|
|
25370
|
-
const terminalEvidence = await pollAssignedTaskTerminalEvidence(components, mesh, row
|
|
25373
|
+
const terminalEvidence = await pollAssignedTaskTerminalEvidence(components, mesh, row, {
|
|
25374
|
+
minFinalAssistantAgeMs: ASSIGNED_IDLE_TRANSCRIPT_COMPLETE_MS
|
|
25375
|
+
});
|
|
25371
25376
|
if (terminalEvidence) {
|
|
25372
25377
|
assignedIdleFinalAssistantSince.delete(idleTranscriptStreakKey);
|
|
25373
25378
|
updateTaskStatus(meshId, row.id, terminalEvidence.outcome);
|
|
@@ -45962,6 +45967,20 @@ init_transcript_evidence();
|
|
|
45962
45967
|
|
|
45963
45968
|
// src/providers/transcript-signal-source.ts
|
|
45964
45969
|
init_logger();
|
|
45970
|
+
|
|
45971
|
+
// src/providers/busy-lease-gate.ts
|
|
45972
|
+
var BUSY_LEASE_BOUND_MS = 18e4;
|
|
45973
|
+
var DEFAULT_CANARY_PROVIDERS = ["kimi", "codex-cli"];
|
|
45974
|
+
function resolveBusyLeaseGate(providerType, env = process.env) {
|
|
45975
|
+
const boundRaw = Number(env.ADHDEV_TX_BUSY_LEASE_BOUND_MS);
|
|
45976
|
+
const boundMs = Number.isFinite(boundRaw) && boundRaw > 0 ? Math.floor(boundRaw) : BUSY_LEASE_BOUND_MS;
|
|
45977
|
+
const listRaw = env.ADHDEV_TX_BUSY_LEASE_PROVIDERS;
|
|
45978
|
+
const list = (typeof listRaw === "string" ? listRaw : DEFAULT_CANARY_PROVIDERS.join(",")).split(",").map((s2) => s2.trim()).filter(Boolean);
|
|
45979
|
+
const type = (providerType ?? "").trim();
|
|
45980
|
+
return { enabled: type.length > 0 && list.includes(type), boundMs };
|
|
45981
|
+
}
|
|
45982
|
+
|
|
45983
|
+
// src/providers/transcript-signal-source.ts
|
|
45965
45984
|
init_signal_envelope();
|
|
45966
45985
|
var TranscriptSignalSource = class {
|
|
45967
45986
|
constructor(opts) {
|
|
@@ -45969,6 +45988,10 @@ var TranscriptSignalSource = class {
|
|
|
45969
45988
|
}
|
|
45970
45989
|
/** msgCount seen at the previous update — drives in_turn_progress. */
|
|
45971
45990
|
prevMsgCount = -1;
|
|
45991
|
+
/** TX-FSM Stage 2: wall-clock of the most recent sample that proved the
|
|
45992
|
+
* transcript live (in_turn_progress === true — a count advance OR mtime
|
|
45993
|
+
* inside the growth-quiet window). -1 = the lease was never issued. */
|
|
45994
|
+
lastLiveSampleAt = -1;
|
|
45972
45995
|
/** Fingerprint of the last LOGGED snapshot, so the shadow log fires on
|
|
45973
45996
|
* change only (a quiet session must not spam one line per read). */
|
|
45974
45997
|
lastLoggedFingerprint = "";
|
|
@@ -46017,6 +46040,7 @@ var TranscriptSignalSource = class {
|
|
|
46017
46040
|
const inTurnProgress = countAdvanced || fresh;
|
|
46018
46041
|
const transcriptGrowing = ageMs === null ? null : fresh;
|
|
46019
46042
|
this.prevMsgCount = msgCount;
|
|
46043
|
+
if (inTurnProgress) this.lastLiveSampleAt = now;
|
|
46020
46044
|
return {
|
|
46021
46045
|
kind: SIGNAL_SNAPSHOT_KIND,
|
|
46022
46046
|
sampledAt: now,
|
|
@@ -46030,6 +46054,33 @@ var TranscriptSignalSource = class {
|
|
|
46030
46054
|
detail: { msgCount, sourceMtimeMs, ageMs }
|
|
46031
46055
|
};
|
|
46032
46056
|
}
|
|
46057
|
+
/**
|
|
46058
|
+
* TX-FSM Stage 2 — the bounded busy lease, derived from the SAME sample
|
|
46059
|
+
* stream that produces the envelope (zero added I/O, pure memory read).
|
|
46060
|
+
*
|
|
46061
|
+
* Semantics: every sample whose in_turn_progress is true (re)issues the
|
|
46062
|
+
* lease at that sample's wall-clock; the lease stays ACTIVE for
|
|
46063
|
+
* leaseBoundMs after the LAST such sample and then EXPIRES. The bound is
|
|
46064
|
+
* the whole point: the lease extends busy across PTY-quiet stretches while
|
|
46065
|
+
* the transcript is demonstrably alive, but it can never hold busy
|
|
46066
|
+
* indefinitely — after expiry the consumer must resume its normal
|
|
46067
|
+
* (pre-lease) judgment, so a finished-but-wedged session escapes on the
|
|
46068
|
+
* bound, not on a transcript event that may never come.
|
|
46069
|
+
*
|
|
46070
|
+
* Fail-open by construction: a non-native-source class, an unresolved
|
|
46071
|
+
* transcript, or a read error never reaches the issuance line, so the
|
|
46072
|
+
* lease is simply never issued (active:false, lastLiveAt:null) — a
|
|
46073
|
+
* missing lease must never wedge a session or fabricate one.
|
|
46074
|
+
*/
|
|
46075
|
+
busyLease(now = Date.now()) {
|
|
46076
|
+
if (this.lastLiveSampleAt < 0) {
|
|
46077
|
+
return { active: false, lastLiveAt: null, expiresAt: null, remainingMs: 0 };
|
|
46078
|
+
}
|
|
46079
|
+
const bound = this.opts.leaseBoundMs ?? BUSY_LEASE_BOUND_MS;
|
|
46080
|
+
const expiresAt = this.lastLiveSampleAt + bound;
|
|
46081
|
+
const remainingMs = Math.max(0, expiresAt - now);
|
|
46082
|
+
return { active: remainingMs > 0, lastLiveAt: this.lastLiveSampleAt, expiresAt, remainingMs };
|
|
46083
|
+
}
|
|
46033
46084
|
/** Stage-0 shadow log: emit one line when the normalized observation
|
|
46034
46085
|
* CHANGES. This log is the Stage 1-3 judgment input ("which signals were
|
|
46035
46086
|
* actually observable, and when"), so it carries the full signal set —
|
|
@@ -51467,7 +51518,11 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
51467
51518
|
// final_assistant_present signal rather than duplicating
|
|
51468
51519
|
// the message scan.
|
|
51469
51520
|
finalAssistantPresent: (msgs, ts2) => this.completionHasFinalAssistantMessage(msgs, ts2),
|
|
51470
|
-
growthQuietMs: MISSING_ASSISTANT_TRANSCRIPT_GROWTH_QUIET_MS
|
|
51521
|
+
growthQuietMs: MISSING_ASSISTANT_TRANSCRIPT_GROWTH_QUIET_MS,
|
|
51522
|
+
// TX-FSM Stage 2: the lease bound follows the rollout gate's
|
|
51523
|
+
// (possibly env-overridden) value; the gate's enabled flag is
|
|
51524
|
+
// consulted per judgment, not here.
|
|
51525
|
+
leaseBoundMs: resolveBusyLeaseGate(this.type).boundMs
|
|
51471
51526
|
});
|
|
51472
51527
|
}
|
|
51473
51528
|
const snapshot = this.transcriptSignalSource.update(
|
|
@@ -52068,6 +52123,21 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
52068
52123
|
}
|
|
52069
52124
|
return { snapshot: this.lastTranscriptSignalSnapshot, messages };
|
|
52070
52125
|
}
|
|
52126
|
+
/**
|
|
52127
|
+
* TX-FSM Stage 2: is the bounded busy lease enabled for THIS provider?
|
|
52128
|
+
* This is the canary rollout gate (busy-lease-gate.ts) — a per-provider
|
|
52129
|
+
* feature switch, NOT a classification (transcript class/timing still come
|
|
52130
|
+
* from resolveTranscriptAuthorityProfile only). Resolved per call so an
|
|
52131
|
+
* env-driven rollout change takes effect without rebuilding the instance;
|
|
52132
|
+
* any resolver error fails closed (lease disabled → pre-Stage-2 behavior).
|
|
52133
|
+
*/
|
|
52134
|
+
busyLeaseGateEnabled() {
|
|
52135
|
+
try {
|
|
52136
|
+
return resolveBusyLeaseGate(this.type).enabled;
|
|
52137
|
+
} catch {
|
|
52138
|
+
return false;
|
|
52139
|
+
}
|
|
52140
|
+
}
|
|
52071
52141
|
/**
|
|
52072
52142
|
* KIMI-MESH-COMPLETION-EMIT (axis 2). Last-chance completion emit for a mesh
|
|
52073
52143
|
* DELEGATED worker whose PTY has already exited (e.g. killed by a false stall)
|
|
@@ -52494,6 +52564,28 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
52494
52564
|
this.scheduleCompletedDebounceFlush(COMPLETED_FINALIZATION_RETRY_MS);
|
|
52495
52565
|
return;
|
|
52496
52566
|
}
|
|
52567
|
+
if (growthSnapshot?.available === true && this.busyLeaseGateEnabled()) {
|
|
52568
|
+
const lease = this.transcriptSignalSource?.busyLease() ?? null;
|
|
52569
|
+
if (lease?.active === true) {
|
|
52570
|
+
if (pending.loggedBlockReason !== "busy_lease_active") {
|
|
52571
|
+
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`);
|
|
52572
|
+
if (this.isMeshWorkerSession()) {
|
|
52573
|
+
traceMeshEventDrop("completion_gate_hold", this.meshTraceCtx(), `busy_lease_active lastLiveAt=${lease.lastLiveAt} expiresIn=${lease.remainingMs}ms`);
|
|
52574
|
+
}
|
|
52575
|
+
if (this.completionTraceOn()) this.recordCompletionGateTrace("hold", {
|
|
52576
|
+
blockReason: "busy_lease_active",
|
|
52577
|
+
latestVisibleStatus,
|
|
52578
|
+
leaseLastLiveAt: lease.lastLiveAt,
|
|
52579
|
+
leaseExpiresAt: lease.expiresAt,
|
|
52580
|
+
leaseRemainingMs: lease.remainingMs,
|
|
52581
|
+
waitedMs
|
|
52582
|
+
});
|
|
52583
|
+
pending.loggedBlockReason = "busy_lease_active";
|
|
52584
|
+
}
|
|
52585
|
+
this.scheduleCompletedDebounceFlush(COMPLETED_FINALIZATION_RETRY_MS);
|
|
52586
|
+
return;
|
|
52587
|
+
}
|
|
52588
|
+
}
|
|
52497
52589
|
}
|
|
52498
52590
|
if (!isTranscriptEvidenceGate && (block2.terminal || waitedMs < COMPLETED_FINALIZATION_MAX_WAIT_MS)) {
|
|
52499
52591
|
if (pending.loggedBlockReason !== blockReason) {
|