@adhdev/daemon-standalone 1.0.29-rc.3 → 1.0.29-rc.5
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 +446 -33
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/public/assets/{index-BnsnvtGz.js → index-Cono379Q.js} +46 -46
- package/public/assets/{index-Jy4W-yh-.css → index-DaANjDZS.css} +1 -1
- package/public/index.html +2 -2
- package/vendor/mcp-server/index.js +2 -0
- package/vendor/mcp-server/index.js.map +1 -1
package/dist/index.js
CHANGED
|
@@ -33311,10 +33311,10 @@ var require_dist3 = __commonJS({
|
|
|
33311
33311
|
}
|
|
33312
33312
|
function getDaemonBuildInfo() {
|
|
33313
33313
|
if (cached2) return cached2;
|
|
33314
|
-
const commit = readInjected(true ? "
|
|
33315
|
-
const commitShort = readInjected(true ? "
|
|
33316
|
-
const version2 = readInjected(true ? "1.0.29-rc.
|
|
33317
|
-
const builtAt = readInjected(true ? "2026-08-
|
|
33314
|
+
const commit = readInjected(true ? "f4bab0079a473c45327927eb9481c5b4c2d48aa7" : void 0) ?? "unknown";
|
|
33315
|
+
const commitShort = readInjected(true ? "f4bab007" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
33316
|
+
const version2 = readInjected(true ? "1.0.29-rc.5" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
33317
|
+
const builtAt = readInjected(true ? "2026-08-02T04:13:46.304Z" : void 0);
|
|
33318
33318
|
cached2 = builtAt ? { commit, commitShort, version: version2, builtAt } : { commit, commitShort, version: version2 };
|
|
33319
33319
|
return cached2;
|
|
33320
33320
|
}
|
|
@@ -36258,6 +36258,7 @@ ${error48.message || ""}`;
|
|
|
36258
36258
|
resolveScopedMeshId: () => resolveScopedMeshId,
|
|
36259
36259
|
setDifficultyBrains: () => setDifficultyBrains,
|
|
36260
36260
|
setMagiKindPanel: () => setMagiKindPanel,
|
|
36261
|
+
setMeshHostPin: () => setMeshHostPin,
|
|
36261
36262
|
tokenIdForManualPairing: () => tokenIdForManualPairing,
|
|
36262
36263
|
updateMesh: () => updateMesh,
|
|
36263
36264
|
updateNode: () => updateNode
|
|
@@ -36424,7 +36425,11 @@ ${error48.message || ""}`;
|
|
|
36424
36425
|
defaultBranch: opts.defaultBranch,
|
|
36425
36426
|
policy: mergeMeshPolicy(void 0, opts.policy),
|
|
36426
36427
|
coordinator: opts.coordinator || {},
|
|
36427
|
-
meshHost: opts.meshHost ||
|
|
36428
|
+
meshHost: opts.meshHost || (() => {
|
|
36429
|
+
const base = createDefaultMeshHostMetadata();
|
|
36430
|
+
const creatingDaemonId = typeof opts.hostDaemonId === "string" ? opts.hostDaemonId.trim() : "";
|
|
36431
|
+
return creatingDaemonId ? { ...base, hostDaemonId: creatingDaemonId } : base;
|
|
36432
|
+
})(),
|
|
36428
36433
|
nodes: [],
|
|
36429
36434
|
createdAt: now,
|
|
36430
36435
|
updatedAt: now
|
|
@@ -36610,6 +36615,86 @@ ${error48.message || ""}`;
|
|
|
36610
36615
|
saveMeshConfig(config2);
|
|
36611
36616
|
return { accepted: true, mesh, meshHost: mesh.meshHost, node, tokenId: validation.tokenId };
|
|
36612
36617
|
}
|
|
36618
|
+
function setMeshHostPin(meshId, opts) {
|
|
36619
|
+
const config2 = loadMeshConfig();
|
|
36620
|
+
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
36621
|
+
if (!mesh) return void 0;
|
|
36622
|
+
const hostDaemonId = typeof opts.hostDaemonId === "string" ? opts.hostDaemonId.trim() : "";
|
|
36623
|
+
const hostNodeId = typeof opts.hostNodeId === "string" ? opts.hostNodeId.trim() : "";
|
|
36624
|
+
const previous = mesh.meshHost || createDefaultMeshHostMetadata();
|
|
36625
|
+
if (!hostDaemonId && !hostNodeId) {
|
|
36626
|
+
return {
|
|
36627
|
+
mesh,
|
|
36628
|
+
meshHost: previous,
|
|
36629
|
+
applied: false,
|
|
36630
|
+
reason: "invalid_host_daemon_id",
|
|
36631
|
+
...previous.hostDaemonId ? { hostDaemonId: previous.hostDaemonId } : {},
|
|
36632
|
+
...previous.hostNodeId ? { hostNodeId: previous.hostNodeId } : {}
|
|
36633
|
+
};
|
|
36634
|
+
}
|
|
36635
|
+
if (previous.role === "member") {
|
|
36636
|
+
return {
|
|
36637
|
+
mesh,
|
|
36638
|
+
meshHost: previous,
|
|
36639
|
+
applied: false,
|
|
36640
|
+
reason: "not_host_role",
|
|
36641
|
+
...previous.hostDaemonId ? { hostDaemonId: previous.hostDaemonId } : {},
|
|
36642
|
+
...previous.hostNodeId ? { hostNodeId: previous.hostNodeId } : {}
|
|
36643
|
+
};
|
|
36644
|
+
}
|
|
36645
|
+
const existingDaemonId = typeof previous.hostDaemonId === "string" ? previous.hostDaemonId.trim() : "";
|
|
36646
|
+
if (existingDaemonId && !opts.force) {
|
|
36647
|
+
const sameHost = hostDaemonId ? daemonIdsEquivalent(existingDaemonId, hostDaemonId) : true;
|
|
36648
|
+
if (!sameHost) {
|
|
36649
|
+
return {
|
|
36650
|
+
mesh,
|
|
36651
|
+
meshHost: previous,
|
|
36652
|
+
applied: false,
|
|
36653
|
+
reason: "host_already_pinned",
|
|
36654
|
+
hostDaemonId: existingDaemonId,
|
|
36655
|
+
...previous.hostNodeId ? { hostNodeId: previous.hostNodeId } : {}
|
|
36656
|
+
};
|
|
36657
|
+
}
|
|
36658
|
+
const existingNodeId = typeof previous.hostNodeId === "string" ? previous.hostNodeId.trim() : "";
|
|
36659
|
+
if (!hostNodeId || hostNodeId === existingNodeId) {
|
|
36660
|
+
return {
|
|
36661
|
+
mesh,
|
|
36662
|
+
meshHost: previous,
|
|
36663
|
+
applied: false,
|
|
36664
|
+
reason: "already_pinned_same",
|
|
36665
|
+
hostDaemonId: existingDaemonId,
|
|
36666
|
+
...existingNodeId ? { hostNodeId: existingNodeId } : {}
|
|
36667
|
+
};
|
|
36668
|
+
}
|
|
36669
|
+
}
|
|
36670
|
+
const now = opts.now || (/* @__PURE__ */ new Date()).toISOString();
|
|
36671
|
+
const effectiveDaemonId = hostDaemonId || existingDaemonId;
|
|
36672
|
+
mesh.meshHost = {
|
|
36673
|
+
...previous,
|
|
36674
|
+
role: "host",
|
|
36675
|
+
...effectiveDaemonId ? { hostDaemonId: effectiveDaemonId } : {},
|
|
36676
|
+
...hostNodeId ? { hostNodeId } : previous.hostNodeId ? { hostNodeId: previous.hostNodeId } : {},
|
|
36677
|
+
...opts.hostAddress?.trim() ? { hostAddress: opts.hostAddress.trim() } : {}
|
|
36678
|
+
};
|
|
36679
|
+
const hostNode = hostNodeId ? mesh.nodes.find((n) => n.id === hostNodeId) : effectiveDaemonId ? mesh.nodes.find((n) => n.daemonId && daemonIdsEquivalent(n.daemonId, effectiveDaemonId)) : void 0;
|
|
36680
|
+
if (hostNode) {
|
|
36681
|
+
for (const node of mesh.nodes) {
|
|
36682
|
+
if (node.role === "host" && node !== hostNode) node.role = void 0;
|
|
36683
|
+
}
|
|
36684
|
+
hostNode.role = "host";
|
|
36685
|
+
if (!mesh.meshHost.hostNodeId) mesh.meshHost.hostNodeId = hostNode.id;
|
|
36686
|
+
}
|
|
36687
|
+
mesh.updatedAt = now;
|
|
36688
|
+
saveMeshConfig(config2);
|
|
36689
|
+
return {
|
|
36690
|
+
mesh,
|
|
36691
|
+
meshHost: mesh.meshHost,
|
|
36692
|
+
applied: true,
|
|
36693
|
+
reason: "pinned",
|
|
36694
|
+
...mesh.meshHost.hostDaemonId ? { hostDaemonId: mesh.meshHost.hostDaemonId } : {},
|
|
36695
|
+
...mesh.meshHost.hostNodeId ? { hostNodeId: mesh.meshHost.hostNodeId } : {}
|
|
36696
|
+
};
|
|
36697
|
+
}
|
|
36613
36698
|
function markMeshHostPairingJoined(meshId, opts) {
|
|
36614
36699
|
const config2 = loadMeshConfig();
|
|
36615
36700
|
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
@@ -36670,6 +36755,12 @@ ${error48.message || ""}`;
|
|
|
36670
36755
|
worktreeBootstrap: opts.worktreeBootstrap,
|
|
36671
36756
|
role: opts.role
|
|
36672
36757
|
};
|
|
36758
|
+
const pinnedHostDaemonId = typeof mesh.meshHost?.hostDaemonId === "string" ? mesh.meshHost.hostDaemonId.trim() : "";
|
|
36759
|
+
const anchorMissing = !(typeof mesh.meshHost?.hostNodeId === "string" && mesh.meshHost.hostNodeId.trim());
|
|
36760
|
+
if (!node.role && anchorMissing && pinnedHostDaemonId && mesh.meshHost?.role !== "member" && node.daemonId && daemonIdsEquivalent(node.daemonId, pinnedHostDaemonId) && !mesh.nodes.some((n) => n.role === "host")) {
|
|
36761
|
+
node.role = "host";
|
|
36762
|
+
mesh.meshHost = { ...mesh.meshHost || createDefaultMeshHostMetadata(), hostNodeId: node.id };
|
|
36763
|
+
}
|
|
36673
36764
|
mesh.nodes.push(node);
|
|
36674
36765
|
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
36675
36766
|
saveMeshConfig(config2);
|
|
@@ -39392,9 +39483,20 @@ Next step: ${nextStep}`;
|
|
|
39392
39483
|
}
|
|
39393
39484
|
continue;
|
|
39394
39485
|
}
|
|
39486
|
+
if (validated.intendedFor && !validated.intendedFor.sessionId && daemonIdsEquivalent(validated.intendedFor.daemonId, drainer.daemonId)) {
|
|
39487
|
+
const liveSessions = ctx.countLiveCoordinatorSessions?.(validated.intendedFor.daemonId) ?? 0;
|
|
39488
|
+
if (liveSessions > 1) {
|
|
39489
|
+
warnV2Once(
|
|
39490
|
+
`${event.meshId}::${eventId}::ambiguous-unicast`,
|
|
39491
|
+
`v2 unicast ${event.event} on mesh ${event.meshId} carries NO coordinator session but ${liveSessions} coordinator sessions are live on ${validated.intendedFor.daemonId} \u2014 delivery is first-come-first-served and may reach the wrong coordinator. Delivered to ${coordinatorIdentityKey(drainer)}. The EMITTING path must stamp targetCoordinatorSessionId.`
|
|
39492
|
+
);
|
|
39493
|
+
bump("v2AmbiguousUnicastDelivered");
|
|
39494
|
+
}
|
|
39495
|
+
}
|
|
39395
39496
|
if (validated.intendedFor && identityDeliversTo(validated.intendedFor, drainer)) {
|
|
39396
39497
|
ctx.batchSeen.add(eventId);
|
|
39397
39498
|
bump("v2Delivered");
|
|
39499
|
+
LOG2.debug("MeshEventsV2", `unicast ${event.event} (mesh ${event.meshId}, eventId ${eventId}) delivered to ${coordinatorIdentityKey(drainer)}; intendedFor=${coordinatorIdentityKey(validated.intendedFor)}`);
|
|
39398
39500
|
kept.push(event);
|
|
39399
39501
|
continue;
|
|
39400
39502
|
}
|
|
@@ -39409,6 +39511,7 @@ Next step: ${nextStep}`;
|
|
|
39409
39511
|
kept.push(event);
|
|
39410
39512
|
continue;
|
|
39411
39513
|
}
|
|
39514
|
+
LOG2.debug("MeshEventsV2", `unicast ${event.event} (mesh ${event.meshId}, eventId ${eventId}) NOT delivered to ${coordinatorIdentityKey(drainer)}; intendedFor=${validated.intendedFor ? coordinatorIdentityKey(validated.intendedFor) : "none"} \u2014 left for its own drainer`);
|
|
39412
39515
|
bump("v2RoutedAway");
|
|
39413
39516
|
}
|
|
39414
39517
|
return kept;
|
|
@@ -39861,7 +39964,12 @@ Next step: ${nextStep}`;
|
|
|
39861
39964
|
try {
|
|
39862
39965
|
const store = MeshRuntimeStore.getInstance();
|
|
39863
39966
|
if (store.pendingEventCount(meshId) > 0) {
|
|
39864
|
-
|
|
39967
|
+
const drainedBy = drainer ? JSON.stringify(drainer) : null;
|
|
39968
|
+
for (const row of store.drainPendingEvents(
|
|
39969
|
+
meshId,
|
|
39970
|
+
daemonIds.length > 0 ? daemonIds : void 0,
|
|
39971
|
+
{ ...onlyEvents ? { onlyEvents } : {}, drainedBy }
|
|
39972
|
+
)) {
|
|
39865
39973
|
const event = row.payload;
|
|
39866
39974
|
if (event) pushUnique(event);
|
|
39867
39975
|
}
|
|
@@ -39900,7 +40008,8 @@ Next step: ${nextStep}`;
|
|
|
39900
40008
|
const routed = routeV2EventsForDrainer(merged, drainer, {
|
|
39901
40009
|
alreadyDrained: (eventId) => priorDrainedEventIds.has(eventId),
|
|
39902
40010
|
batchSeen: /* @__PURE__ */ new Set(),
|
|
39903
|
-
countMetrics: true
|
|
40011
|
+
countMetrics: true,
|
|
40012
|
+
...opts?.countLiveCoordinatorSessions ? { countLiveCoordinatorSessions: opts.countLiveCoordinatorSessions } : {}
|
|
39904
40013
|
});
|
|
39905
40014
|
return reconcilePendingMeshCoordinatorEvents(meshId, routed);
|
|
39906
40015
|
}
|
|
@@ -40120,6 +40229,11 @@ Next step: ${nextStep}`;
|
|
|
40120
40229
|
/** unicast events re-attributed to the drainer via daemon-core match (a
|
|
40121
40230
|
* coordinatorRunId change orphaned them). */
|
|
40122
40231
|
v2ReattributedToDrainer: 0,
|
|
40232
|
+
/** REFINE-EVENT-SESSION-SCOPED-UNICAST: unicast events delivered while addressed only
|
|
40233
|
+
* at DAEMON granularity (no sessionId in intendedFor) even though >1 coordinator
|
|
40234
|
+
* session was live on that daemon — i.e. delivered by race, not by address. Non-zero
|
|
40235
|
+
* here names an emit path that still fails to stamp targetCoordinatorSessionId. */
|
|
40236
|
+
v2AmbiguousUnicastDelivered: 0,
|
|
40123
40237
|
/** v1 (unversioned) events passed through as broadcast (rollout baseline). */
|
|
40124
40238
|
v1BroadcastAccepted: 0,
|
|
40125
40239
|
/** T6 enforce: v2 events that FAILED validation and were QUARANTINED (held back
|
|
@@ -41878,7 +41992,15 @@ Next step: ${nextStep}`;
|
|
|
41878
41992
|
event_id TEXT,
|
|
41879
41993
|
scope TEXT,
|
|
41880
41994
|
dispatched_by TEXT,
|
|
41881
|
-
intended_for TEXT
|
|
41995
|
+
intended_for TEXT,
|
|
41996
|
+
-- REFINE-EVENT-SESSION-SCOPED-UNICAST: WHO consumed this row. The ledger
|
|
41997
|
+
-- previously recorded only THAT an event was drained, never by which
|
|
41998
|
+
-- coordinator identity \u2014 so a mis-delivered unicast (a sibling session
|
|
41999
|
+
-- consuming another coordinator's event) left no evidence and had to be
|
|
42000
|
+
-- inferred. Written at drain time as the JSON-serialized drainer
|
|
42001
|
+
-- CoordinatorIdentity. NULL on rows drained before this column existed
|
|
42002
|
+
-- and on any drain whose caller passed no identity (daemon-level drain).
|
|
42003
|
+
drained_by TEXT
|
|
41882
42004
|
);
|
|
41883
42005
|
|
|
41884
42006
|
CREATE INDEX IF NOT EXISTS idx_mesh_pending_events_mesh_drained
|
|
@@ -42124,7 +42246,7 @@ Next step: ${nextStep}`;
|
|
|
42124
42246
|
this.db.exec(`ALTER TABLE mesh_missions ADD COLUMN close_candidate_emitted_at TEXT`);
|
|
42125
42247
|
}
|
|
42126
42248
|
const pendingCols = this.tableColumns("mesh_pending_events");
|
|
42127
|
-
for (const col of ["protocol_version", "event_id", "scope", "dispatched_by", "intended_for"]) {
|
|
42249
|
+
for (const col of ["protocol_version", "event_id", "scope", "dispatched_by", "intended_for", "drained_by"]) {
|
|
42128
42250
|
if (!pendingCols.has(col)) {
|
|
42129
42251
|
this.db.exec(`ALTER TABLE mesh_pending_events ADD COLUMN ${col} TEXT`);
|
|
42130
42252
|
}
|
|
@@ -43393,8 +43515,8 @@ Next step: ${nextStep}`;
|
|
|
43393
43515
|
const ids = rows.map((r) => r.id);
|
|
43394
43516
|
const now = Date.now();
|
|
43395
43517
|
this.db.prepare(
|
|
43396
|
-
`UPDATE mesh_pending_events SET drained = 1, drained_at = ? WHERE id IN (${ids.map(() => "?").join(",")})`
|
|
43397
|
-
).run(now, ...ids);
|
|
43518
|
+
`UPDATE mesh_pending_events SET drained = 1, drained_at = ?, drained_by = ? WHERE id IN (${ids.map(() => "?").join(",")})`
|
|
43519
|
+
).run(now, opts?.drainedBy ?? null, ...ids);
|
|
43398
43520
|
return rows.map((r) => ({
|
|
43399
43521
|
id: r.id,
|
|
43400
43522
|
event: r.event,
|
|
@@ -43428,6 +43550,30 @@ Next step: ${nextStep}`;
|
|
|
43428
43550
|
})()
|
|
43429
43551
|
}));
|
|
43430
43552
|
}
|
|
43553
|
+
/**
|
|
43554
|
+
* REFINE-EVENT-SESSION-SCOPED-UNICAST — drain attribution audit. Returns the most
|
|
43555
|
+
* recent pending-event rows for a mesh with WHO drained each one, so a suspected
|
|
43556
|
+
* mis-delivery ("my refine result went to another coordinator session") is answered
|
|
43557
|
+
* from the ledger instead of inferred from timing. `drainedBy` is the serialized
|
|
43558
|
+
* drainer CoordinatorIdentity, or null when the row is still queued, was drained
|
|
43559
|
+
* before this column existed, or was drained by a caller that passed no identity.
|
|
43560
|
+
*/
|
|
43561
|
+
recentDrainedPendingEvents(meshId, limit = 100) {
|
|
43562
|
+
const rows = this.db.prepare(
|
|
43563
|
+
`SELECT id, event, scope, intended_for, drained_by, drained, queued_at, drained_at
|
|
43564
|
+
FROM mesh_pending_events WHERE mesh_id = ? ORDER BY queued_at DESC LIMIT ?`
|
|
43565
|
+
).all(meshId, Math.max(1, limit));
|
|
43566
|
+
return rows.map((r) => ({
|
|
43567
|
+
id: r.id,
|
|
43568
|
+
event: r.event,
|
|
43569
|
+
scope: r.scope ?? null,
|
|
43570
|
+
intendedFor: r.intended_for ?? null,
|
|
43571
|
+
drainedBy: r.drained_by ?? null,
|
|
43572
|
+
drained: r.drained === 1,
|
|
43573
|
+
queuedAt: r.queued_at,
|
|
43574
|
+
drainedAt: r.drained_at ?? null
|
|
43575
|
+
}));
|
|
43576
|
+
}
|
|
43431
43577
|
hasPendingEventFingerprint(meshId, fingerprint) {
|
|
43432
43578
|
const row = this.db.prepare(
|
|
43433
43579
|
"SELECT 1 FROM mesh_pending_events WHERE mesh_id = ? AND fingerprint = ? AND drained = 0 LIMIT 1"
|
|
@@ -43602,7 +43748,7 @@ Next step: ${nextStep}`;
|
|
|
43602
43748
|
requeueDrainedPendingEventByFingerprint(meshId, fingerprint) {
|
|
43603
43749
|
if (!fingerprint) return false;
|
|
43604
43750
|
const changes = this.db.prepare(
|
|
43605
|
-
`UPDATE mesh_pending_events SET drained = 0, drained_at = NULL
|
|
43751
|
+
`UPDATE mesh_pending_events SET drained = 0, drained_at = NULL, drained_by = NULL
|
|
43606
43752
|
WHERE mesh_id = ? AND fingerprint = ? AND drained = 1`
|
|
43607
43753
|
).run(meshId, fingerprint).changes;
|
|
43608
43754
|
if (changes > 0) this.maybeCheckpointWal();
|
|
@@ -54276,11 +54422,34 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
54276
54422
|
if (!workspace) return null;
|
|
54277
54423
|
try {
|
|
54278
54424
|
const result = loadRepoMeshJsonConfig(workspace);
|
|
54279
|
-
|
|
54425
|
+
if (result.sourceType !== "repo_file" || !result.config) return null;
|
|
54426
|
+
if (!isConfigPathInsideWorkspace(result.path, workspace)) return null;
|
|
54427
|
+
return result.config;
|
|
54280
54428
|
} catch {
|
|
54281
54429
|
return null;
|
|
54282
54430
|
}
|
|
54283
54431
|
}
|
|
54432
|
+
function isConfigPathInsideWorkspace(configPath, workspace) {
|
|
54433
|
+
if (typeof configPath !== "string" || !configPath) return false;
|
|
54434
|
+
const toPosix = (value) => value.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
54435
|
+
const ws = toPosix(workspace);
|
|
54436
|
+
const target = toPosix(configPath);
|
|
54437
|
+
return !!ws && (target === ws || target.startsWith(`${ws}/`));
|
|
54438
|
+
}
|
|
54439
|
+
function warnUnreadableRepoConfigForNode(node, providerType) {
|
|
54440
|
+
const workspace = typeof node?.workspace === "string" && node.workspace.trim() ? node.workspace.trim() : "";
|
|
54441
|
+
if (!workspace) return;
|
|
54442
|
+
const nodeId = readNonEmptyString(node?.id) || readNonEmptyString(node?.nodeId) || "unknown-node";
|
|
54443
|
+
LOG2.warn(
|
|
54444
|
+
"MeshQueue",
|
|
54445
|
+
`repo mesh.json unreadable from this daemon for node=${nodeId} workspace=${workspace} provider=${providerType || "unknown"} \u2014 delegated auto-approve MODE falls back to the provider default here; the worker daemon re-resolves it from its own checkout at launch`
|
|
54446
|
+
);
|
|
54447
|
+
}
|
|
54448
|
+
function delegatedWorkerAutoApproveSettingsForNode(mesh, node, provider, providerType) {
|
|
54449
|
+
const repoConfig = loadRepoConfigForNode(node);
|
|
54450
|
+
if (!repoConfig) warnUnreadableRepoConfigForNode(node, providerType);
|
|
54451
|
+
return delegatedWorkerAutoApproveSettings(mesh?.policy, node?.policy, provider, repoConfig, providerType);
|
|
54452
|
+
}
|
|
54284
54453
|
function getMeshWithCache(components, meshId) {
|
|
54285
54454
|
const localMesh = getMesh(meshId);
|
|
54286
54455
|
const cachedMesh = components.router?.getCachedInlineMesh(meshId);
|
|
@@ -54697,11 +54866,10 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
54697
54866
|
meshNodeFor: meshId,
|
|
54698
54867
|
meshNodeId: nodeId,
|
|
54699
54868
|
launchedByCoordinator: true,
|
|
54700
|
-
...
|
|
54701
|
-
mesh
|
|
54702
|
-
node
|
|
54869
|
+
...delegatedWorkerAutoApproveSettingsForNode(
|
|
54870
|
+
mesh,
|
|
54871
|
+
node,
|
|
54703
54872
|
components.providerLoader?.getMeta(providerType),
|
|
54704
|
-
loadRepoConfigForNode(node),
|
|
54705
54873
|
providerType
|
|
54706
54874
|
),
|
|
54707
54875
|
...localDaemonId ? { meshCoordinatorDaemonId: localDaemonId } : {},
|
|
@@ -55560,11 +55728,10 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
55560
55728
|
// Coordinator-dispatched worker: auto-approve unless mesh/node policy
|
|
55561
55729
|
// opts out (default true). Lands in settingsOverride and beats the
|
|
55562
55730
|
// global per-provider-type boolean/mode through explicit opposite-key clearing.
|
|
55563
|
-
...
|
|
55564
|
-
mesh
|
|
55565
|
-
node
|
|
55731
|
+
...delegatedWorkerAutoApproveSettingsForNode(
|
|
55732
|
+
mesh,
|
|
55733
|
+
node,
|
|
55566
55734
|
components.providerLoader?.getMeta(resolved.providerType),
|
|
55567
|
-
loadRepoConfigForNode(node),
|
|
55568
55735
|
resolved.providerType
|
|
55569
55736
|
),
|
|
55570
55737
|
launchedByCoordinator: true,
|
|
@@ -61514,7 +61681,15 @@ ${cleanBody}`;
|
|
|
61514
61681
|
try {
|
|
61515
61682
|
pendingEvents = drainPendingMeshCoordinatorEvents(
|
|
61516
61683
|
meshId,
|
|
61517
|
-
drainDaemonIds.length > 0 ? drainDaemonIds : localDaemonId
|
|
61684
|
+
drainDaemonIds.length > 0 ? drainDaemonIds : localDaemonId,
|
|
61685
|
+
{
|
|
61686
|
+
// AMBIGUOUS-UNICAST guard (REFINE-EVENT-SESSION-SCOPED-UNICAST): observability
|
|
61687
|
+
// only — it warns when a session-less unicast event is delivered while several
|
|
61688
|
+
// coordinator sessions are live and racing for it. Never changes delivery, so
|
|
61689
|
+
// an event can't be stranded by it. targetCoordinators is this daemon's live
|
|
61690
|
+
// coordinator set for the mesh, which is exactly the racing population.
|
|
61691
|
+
countLiveCoordinatorSessions: () => new Set(targetCoordinators.map((c) => c.sessionId).filter(Boolean)).size
|
|
61692
|
+
}
|
|
61518
61693
|
);
|
|
61519
61694
|
} catch (e) {
|
|
61520
61695
|
LOG2.warn("MeshReconcile", `Drain failed for mesh ${meshId}: ${e?.message || e}`);
|
|
@@ -85692,6 +85867,84 @@ ${body}
|
|
|
85692
85867
|
init_hash();
|
|
85693
85868
|
init_coordinator_registry();
|
|
85694
85869
|
init_mesh_duplicate_dispatch();
|
|
85870
|
+
init_mesh_json_config();
|
|
85871
|
+
init_logger();
|
|
85872
|
+
init_repo_mesh_types();
|
|
85873
|
+
function resolveDelegatedWorkerAutoApproveModeForLaunch(input) {
|
|
85874
|
+
const settings = input.settings;
|
|
85875
|
+
const envelopeMode = typeof settings?.autoApproveMode === "string" && settings.autoApproveMode.trim() ? settings.autoApproveMode.trim() : void 0;
|
|
85876
|
+
if (settings?.launchedByCoordinator !== true) {
|
|
85877
|
+
return { autoApproveMode: envelopeMode, changed: false, source: "not_delegated" };
|
|
85878
|
+
}
|
|
85879
|
+
if (settings.autoApprove === false) {
|
|
85880
|
+
return { autoApproveMode: void 0, changed: false, source: "enable_gate_off" };
|
|
85881
|
+
}
|
|
85882
|
+
const providerType = typeof input.providerType === "string" ? input.providerType.trim() : "";
|
|
85883
|
+
if (!providerType || !input.provider?.autoApproveModes) {
|
|
85884
|
+
return { autoApproveMode: envelopeMode, changed: false, source: "no_provider_modes" };
|
|
85885
|
+
}
|
|
85886
|
+
const workspace = typeof input.workspace === "string" ? input.workspace.trim() : "";
|
|
85887
|
+
if (!workspace) {
|
|
85888
|
+
return { autoApproveMode: envelopeMode, changed: false, source: "no_repo_config" };
|
|
85889
|
+
}
|
|
85890
|
+
let repoConfig = null;
|
|
85891
|
+
try {
|
|
85892
|
+
const result = loadRepoMeshJsonConfig(workspace);
|
|
85893
|
+
const fromThisWorkspace = result.sourceType === "repo_file" && typeof result.path === "string" && isPathInsideWorkspace(result.path, workspace);
|
|
85894
|
+
repoConfig = fromThisWorkspace && result.config ? result.config : null;
|
|
85895
|
+
} catch {
|
|
85896
|
+
repoConfig = null;
|
|
85897
|
+
}
|
|
85898
|
+
const requestedMode = repoConfig?.providerDefaults?.autoApproveModes?.[providerType];
|
|
85899
|
+
const requestedModeId = typeof requestedMode === "string" && requestedMode.trim() ? requestedMode.trim() : "";
|
|
85900
|
+
if (!requestedModeId) {
|
|
85901
|
+
return { autoApproveMode: envelopeMode, changed: false, source: "no_repo_config" };
|
|
85902
|
+
}
|
|
85903
|
+
const dangerousAllowed = settings.delegatedWorkerDangerousModeAllow === true;
|
|
85904
|
+
const resolved = resolveDelegatedWorkerAutoApprove(
|
|
85905
|
+
{ delegatedWorkerAutoApprove: true, delegatedWorkerDangerousModeAllow: dangerousAllowed },
|
|
85906
|
+
void 0,
|
|
85907
|
+
input.provider,
|
|
85908
|
+
repoConfig,
|
|
85909
|
+
providerType
|
|
85910
|
+
);
|
|
85911
|
+
if (typeof resolved !== "string") {
|
|
85912
|
+
return { autoApproveMode: envelopeMode, changed: false, source: "no_repo_config" };
|
|
85913
|
+
}
|
|
85914
|
+
return {
|
|
85915
|
+
autoApproveMode: resolved,
|
|
85916
|
+
changed: resolved !== envelopeMode,
|
|
85917
|
+
source: "worker_repo_file"
|
|
85918
|
+
};
|
|
85919
|
+
}
|
|
85920
|
+
function isPathInsideWorkspace(configPath, workspace) {
|
|
85921
|
+
const normalize4 = (value) => value.replace(/[\\/]+$/, "");
|
|
85922
|
+
const ws = normalize4(workspace);
|
|
85923
|
+
if (!ws) return false;
|
|
85924
|
+
const separatorAgnostic = (value) => value.replace(/\\/g, "/");
|
|
85925
|
+
const normalizedPath = separatorAgnostic(configPath);
|
|
85926
|
+
const normalizedWs = separatorAgnostic(ws);
|
|
85927
|
+
return normalizedPath === normalizedWs || normalizedPath.startsWith(`${normalizedWs}/`);
|
|
85928
|
+
}
|
|
85929
|
+
function logDelegatedWorkerModeDelivery(resolution, context) {
|
|
85930
|
+
if (resolution.source !== "worker_repo_file" && resolution.source !== "no_repo_config") return;
|
|
85931
|
+
const node = context.meshNodeId || "unknown-node";
|
|
85932
|
+
const workspace = context.workspace || "unknown-workspace";
|
|
85933
|
+
const provider = context.providerType || "unknown-provider";
|
|
85934
|
+
if (resolution.source === "worker_repo_file" && resolution.changed) {
|
|
85935
|
+
LOG2.info(
|
|
85936
|
+
"MeshWorker",
|
|
85937
|
+
`auto-approve mode re-resolved from worker repo config: node=${node} workspace=${workspace} provider=${provider} coordinatorMode=${context.envelopeMode ?? "(none)"} workerMode=${resolution.autoApproveMode}`
|
|
85938
|
+
);
|
|
85939
|
+
return;
|
|
85940
|
+
}
|
|
85941
|
+
if (resolution.source === "no_repo_config" && context.envelopeMode) {
|
|
85942
|
+
LOG2.warn(
|
|
85943
|
+
"MeshWorker",
|
|
85944
|
+
`auto-approve mode NOT confirmed by worker repo config (keeping coordinator value): node=${node} workspace=${workspace} provider=${provider} mode=${context.envelopeMode} \u2014 no readable .adhdev/mesh.json in this workspace`
|
|
85945
|
+
);
|
|
85946
|
+
}
|
|
85947
|
+
}
|
|
85695
85948
|
init_summary_metadata();
|
|
85696
85949
|
var os19 = __toESM2(require("os"));
|
|
85697
85950
|
var crypto5 = __toESM2(require("crypto"));
|
|
@@ -95044,7 +95297,29 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
95044
95297
|
if (!cliType) throw new Error("cliType required");
|
|
95045
95298
|
const providerType = this.providerLoader.resolveAlias(cliType);
|
|
95046
95299
|
const provLookup = this.providerLoader.getMeta(providerType);
|
|
95047
|
-
|
|
95300
|
+
let settingsOverride = args?.settings && typeof args.settings === "object" ? args.settings : void 0;
|
|
95301
|
+
if (settingsOverride?.launchedByCoordinator === true) {
|
|
95302
|
+
const envelopeMode = typeof settingsOverride.autoApproveMode === "string" ? settingsOverride.autoApproveMode : void 0;
|
|
95303
|
+
const modeResolution = resolveDelegatedWorkerAutoApproveModeForLaunch({
|
|
95304
|
+
workspace: dir,
|
|
95305
|
+
providerType,
|
|
95306
|
+
provider: provLookup,
|
|
95307
|
+
settings: settingsOverride
|
|
95308
|
+
});
|
|
95309
|
+
logDelegatedWorkerModeDelivery(modeResolution, {
|
|
95310
|
+
workspace: dir,
|
|
95311
|
+
providerType,
|
|
95312
|
+
meshNodeId: typeof settingsOverride.meshNodeId === "string" ? settingsOverride.meshNodeId : void 0,
|
|
95313
|
+
envelopeMode
|
|
95314
|
+
});
|
|
95315
|
+
if (modeResolution.changed && modeResolution.autoApproveMode) {
|
|
95316
|
+
settingsOverride = {
|
|
95317
|
+
...settingsOverride,
|
|
95318
|
+
autoApproveMode: modeResolution.autoApproveMode,
|
|
95319
|
+
autoApprove: void 0
|
|
95320
|
+
};
|
|
95321
|
+
}
|
|
95322
|
+
}
|
|
95048
95323
|
const delegatedLaunch = settingsOverride?.launchedByCoordinator === true ? buildCoordinatorDelegatedCliLaunchOptions({
|
|
95049
95324
|
cliType,
|
|
95050
95325
|
workspace: dir,
|
|
@@ -101143,7 +101418,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
101143
101418
|
}
|
|
101144
101419
|
return { success: true, mesh: meshRecord.mesh, sourceOfTruth };
|
|
101145
101420
|
},
|
|
101146
|
-
create_mesh: async (
|
|
101421
|
+
create_mesh: async (ctx, args) => {
|
|
101147
101422
|
const name = typeof args?.name === "string" ? args.name.trim() : "";
|
|
101148
101423
|
const repoIdentity = typeof args?.repoIdentity === "string" ? args.repoIdentity.trim() : "";
|
|
101149
101424
|
const repoRemoteUrl = typeof args?.repoRemoteUrl === "string" ? args.repoRemoteUrl.trim() : void 0;
|
|
@@ -101152,12 +101427,71 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
101152
101427
|
try {
|
|
101153
101428
|
const { createMesh: createMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
101154
101429
|
const meshHost = args?.meshHost && typeof args.meshHost === "object" && !Array.isArray(args.meshHost) ? args.meshHost : void 0;
|
|
101155
|
-
const
|
|
101430
|
+
const requestedHostDaemonId = typeof args?.hostDaemonId === "string" && args.hostDaemonId.trim() ? args.hostDaemonId.trim() : ctx.deps.statusInstanceId || "";
|
|
101431
|
+
const mesh = createMesh2({
|
|
101432
|
+
name,
|
|
101433
|
+
repoIdentity,
|
|
101434
|
+
repoRemoteUrl,
|
|
101435
|
+
defaultBranch,
|
|
101436
|
+
policy: args?.policy,
|
|
101437
|
+
meshHost,
|
|
101438
|
+
...requestedHostDaemonId ? { hostDaemonId: requestedHostDaemonId } : {}
|
|
101439
|
+
});
|
|
101156
101440
|
return { success: true, mesh };
|
|
101157
101441
|
} catch (e) {
|
|
101158
101442
|
return { success: false, error: e.message };
|
|
101159
101443
|
}
|
|
101160
101444
|
},
|
|
101445
|
+
// HOST-PIN-WRITER — establish this mesh's host daemon as a DELIBERATE operator act.
|
|
101446
|
+
//
|
|
101447
|
+
// The dashboard's first-setup flow lets the operator pick which connected daemon
|
|
101448
|
+
// becomes the host; this is the command that actually persists that choice. It is a
|
|
101449
|
+
// separate surface from coordinator launch on purpose: the pin is effectively
|
|
101450
|
+
// permanent ("Fixed when the mesh is created — it cannot be reassigned here"), so it
|
|
101451
|
+
// must not be an incidental side effect of a button whose stated job is launching a
|
|
101452
|
+
// session. A mis-click must not permanently re-home a mesh.
|
|
101453
|
+
//
|
|
101454
|
+
// Reassignment to a DIFFERENT daemon is refused unless the caller passes
|
|
101455
|
+
// force:true — the mutator returns code 'host_already_pinned' and changes nothing.
|
|
101456
|
+
// Re-pinning the same daemon is a no-op, so retries/races are safe.
|
|
101457
|
+
set_mesh_host: async (ctx, args) => {
|
|
101458
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
101459
|
+
const hostDaemonId = typeof args?.hostDaemonId === "string" ? args.hostDaemonId.trim() : "";
|
|
101460
|
+
const hostNodeId = typeof args?.hostNodeId === "string" ? args.hostNodeId.trim() : "";
|
|
101461
|
+
if (!meshId) return { success: false, error: "meshId required" };
|
|
101462
|
+
if (!hostDaemonId && !hostNodeId) return { success: false, error: "hostDaemonId or hostNodeId required" };
|
|
101463
|
+
try {
|
|
101464
|
+
const { setMeshHostPin: setMeshHostPin2, getMesh: getMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
101465
|
+
const result = setMeshHostPin2(meshId, {
|
|
101466
|
+
...hostDaemonId ? { hostDaemonId } : {},
|
|
101467
|
+
...hostNodeId ? { hostNodeId } : {},
|
|
101468
|
+
force: args?.force === true
|
|
101469
|
+
});
|
|
101470
|
+
if (!result) return { success: false, error: "Mesh not found" };
|
|
101471
|
+
if (!result.applied && result.reason !== "already_pinned_same") {
|
|
101472
|
+
return {
|
|
101473
|
+
success: false,
|
|
101474
|
+
code: result.reason,
|
|
101475
|
+
error: result.reason === "host_already_pinned" ? `Mesh host is already pinned to ${result.hostDaemonId}. Pass force:true to reassign it.` : result.reason === "not_host_role" ? "This daemon joined the mesh as a member; its host lives on the daemon it paired with." : "hostDaemonId or hostNodeId required",
|
|
101476
|
+
meshId,
|
|
101477
|
+
meshHost: resolveMeshHostStatus(result.mesh)
|
|
101478
|
+
};
|
|
101479
|
+
}
|
|
101480
|
+
const fresh = getMesh2(meshId) || result.mesh;
|
|
101481
|
+
if (ctx.getCachedInlineMesh(meshId)) ctx.inlineMeshCache.set(meshId, fresh);
|
|
101482
|
+
ctx.invalidateAggregateMeshStatus(meshId);
|
|
101483
|
+
return {
|
|
101484
|
+
success: true,
|
|
101485
|
+
code: result.reason,
|
|
101486
|
+
meshId,
|
|
101487
|
+
applied: result.applied,
|
|
101488
|
+
meshHost: resolveMeshHostStatus(fresh),
|
|
101489
|
+
mesh: fresh
|
|
101490
|
+
};
|
|
101491
|
+
} catch (e) {
|
|
101492
|
+
return { success: false, error: e.message };
|
|
101493
|
+
}
|
|
101494
|
+
},
|
|
101161
101495
|
update_mesh: async (ctx, args) => {
|
|
101162
101496
|
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
101163
101497
|
if (!meshId) return { success: false, error: "meshId required" };
|
|
@@ -103102,6 +103436,26 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
103102
103436
|
init_mesh_coordinator();
|
|
103103
103437
|
init_dist();
|
|
103104
103438
|
init_repo_mesh_types();
|
|
103439
|
+
async function backfillMeshHostPinAfterLaunch(opts) {
|
|
103440
|
+
try {
|
|
103441
|
+
const existingPin = typeof opts.mesh?.meshHost?.hostDaemonId === "string" ? opts.mesh.meshHost.hostDaemonId.trim() : "";
|
|
103442
|
+
if (existingPin) return;
|
|
103443
|
+
const { getMesh: getMesh2, setMeshHostPin: setMeshHostPin2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
103444
|
+
if (!getMesh2(opts.meshId)) return;
|
|
103445
|
+
const nodeDaemonId = typeof opts.coordinatorNode?.daemonId === "string" && opts.coordinatorNode.daemonId.trim() ? opts.coordinatorNode.daemonId.trim() : typeof opts.coordinatorNode?.daemon_id === "string" && opts.coordinatorNode.daemon_id.trim() ? opts.coordinatorNode.daemon_id.trim() : opts.localDaemonId || "";
|
|
103446
|
+
const nodeId = String(normalizeMeshNodeId(opts.coordinatorNode) || "");
|
|
103447
|
+
if (!nodeDaemonId && !nodeId) return;
|
|
103448
|
+
const result = setMeshHostPin2(opts.meshId, {
|
|
103449
|
+
...nodeDaemonId ? { hostDaemonId: nodeDaemonId } : {},
|
|
103450
|
+
...nodeId ? { hostNodeId: nodeId } : {}
|
|
103451
|
+
});
|
|
103452
|
+
if (result?.applied) {
|
|
103453
|
+
LOG2.info("MeshCoordinator", `Pinned mesh ${opts.meshId} host to ${result.hostDaemonId || nodeDaemonId} (node ${result.hostNodeId || nodeId}) after coordinator launch`);
|
|
103454
|
+
}
|
|
103455
|
+
} catch (error48) {
|
|
103456
|
+
LOG2.warn("MeshCoordinator", `Host pin backfill skipped for mesh ${opts.meshId}: ${error48?.message || String(error48)}`);
|
|
103457
|
+
}
|
|
103458
|
+
}
|
|
103105
103459
|
var meshCoordinatorLaunchHandlers = {
|
|
103106
103460
|
launch_mesh_coordinator: async (ctx, args) => {
|
|
103107
103461
|
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
@@ -103461,6 +103815,12 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
103461
103815
|
});
|
|
103462
103816
|
} catch {
|
|
103463
103817
|
}
|
|
103818
|
+
await backfillMeshHostPinAfterLaunch({
|
|
103819
|
+
meshId,
|
|
103820
|
+
mesh,
|
|
103821
|
+
coordinatorNode,
|
|
103822
|
+
localDaemonId: ctx.deps.statusInstanceId
|
|
103823
|
+
});
|
|
103464
103824
|
return {
|
|
103465
103825
|
success: true,
|
|
103466
103826
|
meshId,
|
|
@@ -103659,6 +104019,12 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
103659
104019
|
});
|
|
103660
104020
|
} catch {
|
|
103661
104021
|
}
|
|
104022
|
+
await backfillMeshHostPinAfterLaunch({
|
|
104023
|
+
meshId,
|
|
104024
|
+
mesh,
|
|
104025
|
+
coordinatorNode,
|
|
104026
|
+
localDaemonId: ctx.deps.statusInstanceId
|
|
104027
|
+
});
|
|
103662
104028
|
return {
|
|
103663
104029
|
success: true,
|
|
103664
104030
|
meshId,
|
|
@@ -106061,6 +106427,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
106061
106427
|
...args.completedAt ? { completedAt: args.completedAt } : {},
|
|
106062
106428
|
...args.retryOfJobId ? { retryOfJobId: args.retryOfJobId } : {},
|
|
106063
106429
|
...args.coordinatorDaemonId ? { targetCoordinatorDaemonId: args.coordinatorDaemonId } : {},
|
|
106430
|
+
...args.coordinatorSessionId ? { targetCoordinatorSessionId: args.coordinatorSessionId } : {},
|
|
106064
106431
|
eventDelivery: { pendingEvents: true, ledger: true },
|
|
106065
106432
|
evidence: {
|
|
106066
106433
|
pendingEventsCommand: "get_pending_mesh_events",
|
|
@@ -106159,9 +106526,23 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
106159
106526
|
nodeLabel: handle.targetNodeId,
|
|
106160
106527
|
nodeId: handle.targetNodeId,
|
|
106161
106528
|
workspace: handle.workspace,
|
|
106162
|
-
metadataEvent
|
|
106529
|
+
metadataEvent: {
|
|
106530
|
+
...metadataEvent,
|
|
106531
|
+
// REFINE-EVENT-SESSION-SCOPED-UNICAST: mirror the session INSIDE
|
|
106532
|
+
// metadataEvent too. handleMeshForwardEvent reads the coordinator session
|
|
106533
|
+
// anchor from `metadataEvent.meshCoordinatorSessionId` (a top-level field
|
|
106534
|
+
// alone is dropped when the event crosses a machine boundary), so this is
|
|
106535
|
+
// what survives the P2P relay for a remote-executing refine.
|
|
106536
|
+
...handle.targetCoordinatorSessionId ? { meshCoordinatorSessionId: handle.targetCoordinatorSessionId } : {}
|
|
106537
|
+
},
|
|
106163
106538
|
queuedAt: Date.now(),
|
|
106164
|
-
...handle.targetCoordinatorDaemonId ? { targetCoordinatorDaemonId: handle.targetCoordinatorDaemonId } : {}
|
|
106539
|
+
...handle.targetCoordinatorDaemonId ? { targetCoordinatorDaemonId: handle.targetCoordinatorDaemonId } : {},
|
|
106540
|
+
// THE FIX: address the terminal event to the requesting coordinator SESSION,
|
|
106541
|
+
// not just its daemon. stampPendingEventV2 folds this into the v2 unicast
|
|
106542
|
+
// `intendedFor`, so identityDeliversTo's both-sides-session branch excludes a
|
|
106543
|
+
// sibling coordinator session on the same daemon. Absent (legacy requester) →
|
|
106544
|
+
// session-less intendedFor → daemon-level delivery exactly as before.
|
|
106545
|
+
...handle.targetCoordinatorSessionId ? { targetCoordinatorSessionId: handle.targetCoordinatorSessionId } : {}
|
|
106165
106546
|
};
|
|
106166
106547
|
if (typeof self.deps.instanceManager?.getByCategory === "function") {
|
|
106167
106548
|
const forwarded = handleMeshForwardEvent(
|
|
@@ -106185,6 +106566,14 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
106185
106566
|
// re-queued event self-fallbacks to THIS (the executing/worker)
|
|
106186
106567
|
// daemon and the real coordinator's drain excludes it.
|
|
106187
106568
|
...handle.targetCoordinatorDaemonId ? { targetCoordinatorDaemonId: handle.targetCoordinatorDaemonId } : {},
|
|
106569
|
+
// REFINE-EVENT-SESSION-SCOPED-UNICAST: carry the SESSION half of the
|
|
106570
|
+
// return address across the relay as well. buildRelayMetadataEvent
|
|
106571
|
+
// reads meshCoordinatorSessionId (falling back to
|
|
106572
|
+
// targetCoordinatorSessionId), so both spellings are supplied.
|
|
106573
|
+
...handle.targetCoordinatorSessionId ? {
|
|
106574
|
+
targetCoordinatorSessionId: handle.targetCoordinatorSessionId,
|
|
106575
|
+
meshCoordinatorSessionId: handle.targetCoordinatorSessionId
|
|
106576
|
+
} : {},
|
|
106188
106577
|
...slimResult ? { result: slimResult } : {}
|
|
106189
106578
|
}
|
|
106190
106579
|
);
|
|
@@ -107609,6 +107998,7 @@ ${e?.stderr || ""}`;
|
|
|
107609
107998
|
startedAt: args.startedAt || (/* @__PURE__ */ new Date()).toISOString(),
|
|
107610
107999
|
...args.completedAt ? { completedAt: args.completedAt } : {},
|
|
107611
108000
|
...args.coordinatorDaemonId ? { targetCoordinatorDaemonId: args.coordinatorDaemonId } : {},
|
|
108001
|
+
...args.coordinatorSessionId ? { targetCoordinatorSessionId: args.coordinatorSessionId } : {},
|
|
107612
108002
|
eventDelivery: { pendingEvents: true, ledger: true },
|
|
107613
108003
|
evidence: {
|
|
107614
108004
|
pendingEventsCommand: "get_pending_mesh_events",
|
|
@@ -107638,9 +108028,16 @@ ${e?.stderr || ""}`;
|
|
|
107638
108028
|
meshId: handle.meshId,
|
|
107639
108029
|
nodeLabel: handle.batchLabel,
|
|
107640
108030
|
nodeId: handle.batchLabel,
|
|
107641
|
-
metadataEvent
|
|
108031
|
+
metadataEvent: {
|
|
108032
|
+
...metadataEvent,
|
|
108033
|
+
// REFINE-EVENT-SESSION-SCOPED-UNICAST — see queueRefineJobEvent.
|
|
108034
|
+
...handle.targetCoordinatorSessionId ? { meshCoordinatorSessionId: handle.targetCoordinatorSessionId } : {}
|
|
108035
|
+
},
|
|
107642
108036
|
queuedAt: Date.now(),
|
|
107643
|
-
...handle.targetCoordinatorDaemonId ? { targetCoordinatorDaemonId: handle.targetCoordinatorDaemonId } : {}
|
|
108037
|
+
...handle.targetCoordinatorDaemonId ? { targetCoordinatorDaemonId: handle.targetCoordinatorDaemonId } : {},
|
|
108038
|
+
// THE FIX (batch half) — address the batch terminal event to the requesting
|
|
108039
|
+
// coordinator SESSION so a sibling session cannot consume it.
|
|
108040
|
+
...handle.targetCoordinatorSessionId ? { targetCoordinatorSessionId: handle.targetCoordinatorSessionId } : {}
|
|
107644
108041
|
};
|
|
107645
108042
|
if (typeof self.deps.instanceManager?.getByCategory === "function") {
|
|
107646
108043
|
const forwarded = handleMeshForwardEvent(
|
|
@@ -107658,6 +108055,12 @@ ${e?.stderr || ""}`;
|
|
|
107658
108055
|
// the sessionless batch job's terminal event must stay targeted
|
|
107659
108056
|
// at the originating coordinator, not self-fallback to this daemon.
|
|
107660
108057
|
...handle.targetCoordinatorDaemonId ? { targetCoordinatorDaemonId: handle.targetCoordinatorDaemonId } : {},
|
|
108058
|
+
// REFINE-EVENT-SESSION-SCOPED-UNICAST — session half of the return
|
|
108059
|
+
// address, both spellings (see queueRefineJobEvent).
|
|
108060
|
+
...handle.targetCoordinatorSessionId ? {
|
|
108061
|
+
targetCoordinatorSessionId: handle.targetCoordinatorSessionId,
|
|
108062
|
+
meshCoordinatorSessionId: handle.targetCoordinatorSessionId
|
|
108063
|
+
} : {},
|
|
107661
108064
|
...result ? { result } : {}
|
|
107662
108065
|
}
|
|
107663
108066
|
);
|
|
@@ -107730,7 +108133,10 @@ ${e?.stderr || ""}`;
|
|
|
107730
108133
|
completedAt,
|
|
107731
108134
|
jobId: handle.jobId,
|
|
107732
108135
|
interactionId: handle.interactionId,
|
|
107733
|
-
coordinatorDaemonId: handle.targetCoordinatorDaemonId
|
|
108136
|
+
coordinatorDaemonId: handle.targetCoordinatorDaemonId,
|
|
108137
|
+
// REFINE-EVENT-SESSION-SCOPED-UNICAST — carry the requester's session onto the
|
|
108138
|
+
// terminal batch handle (see the single-node path).
|
|
108139
|
+
coordinatorSessionId: handle.targetCoordinatorSessionId
|
|
107734
108140
|
});
|
|
107735
108141
|
const terminal = { ...terminalHandle, result: normalizedResult };
|
|
107736
108142
|
self.terminalRefineBatchJobs.set(key2, terminal);
|
|
@@ -107764,7 +108170,8 @@ ${e?.stderr || ""}`;
|
|
|
107764
108170
|
rationale: planRecord.orderingRationale
|
|
107765
108171
|
};
|
|
107766
108172
|
const coordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : self.deps.statusInstanceId || void 0;
|
|
107767
|
-
const
|
|
108173
|
+
const coordinatorSessionId = typeof args?.coordinatorSessionId === "string" && args.coordinatorSessionId.trim() ? args.coordinatorSessionId.trim() : void 0;
|
|
108174
|
+
const handle = buildRefineBatchJobHandle(self, { meshId, nodeIds, order, coordinatorDaemonId, coordinatorSessionId });
|
|
107768
108175
|
self.runningRefineBatchJobs.set(key2, handle);
|
|
107769
108176
|
await appendRefineBatchJobLedger(self, "task_dispatched", handle);
|
|
107770
108177
|
queueRefineBatchJobEvent(self, "refine:accepted", handle);
|
|
@@ -107855,7 +108262,12 @@ ${e?.stderr || ""}`;
|
|
|
107855
108262
|
interactionId: handle.interactionId,
|
|
107856
108263
|
retryOfJobId: handle.retryOfJobId,
|
|
107857
108264
|
node: { daemonId: handle.targetDaemonId, workspace: handle.workspace },
|
|
107858
|
-
coordinatorDaemonId: handle.targetCoordinatorDaemonId
|
|
108265
|
+
coordinatorDaemonId: handle.targetCoordinatorDaemonId,
|
|
108266
|
+
// REFINE-EVENT-SESSION-SCOPED-UNICAST: carry the requester's session from the
|
|
108267
|
+
// accepted handle onto the TERMINAL handle. Dropping it here would leave the
|
|
108268
|
+
// completed/failed event — the one the coordinator actually waits on — back at
|
|
108269
|
+
// daemon-level addressing, i.e. the original defect.
|
|
108270
|
+
coordinatorSessionId: handle.targetCoordinatorSessionId
|
|
107859
108271
|
});
|
|
107860
108272
|
const terminal = { ...terminalHandle, result: normalizedResult };
|
|
107861
108273
|
self.terminalRefineJobs.set(key2, terminal);
|
|
@@ -107875,7 +108287,8 @@ ${e?.stderr || ""}`;
|
|
|
107875
108287
|
if (!node) return { success: false, error: `Node '${nodeId}' not found in mesh` };
|
|
107876
108288
|
if (!node.isLocalWorktree || !node.workspace) return { success: false, error: `Refinery requires a local worktree node` };
|
|
107877
108289
|
const coordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : self.deps.statusInstanceId || void 0;
|
|
107878
|
-
const
|
|
108290
|
+
const coordinatorSessionId = typeof args?.coordinatorSessionId === "string" && args.coordinatorSessionId.trim() ? args.coordinatorSessionId.trim() : void 0;
|
|
108291
|
+
const handle = buildRefineJobHandle(self, { meshId, nodeId, node, retryOfJobId: terminal?.jobId, coordinatorDaemonId, coordinatorSessionId });
|
|
107879
108292
|
self.runningRefineJobs.set(key2, handle);
|
|
107880
108293
|
await appendRefineJobLedger(self, "task_dispatched", handle);
|
|
107881
108294
|
queueRefineJobEvent(self, "refine:accepted", handle);
|