@lmzhen/dsh-evolution-curator 0.3.82 → 0.3.83
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/README.md +2 -2
- package/lib/index.js +27 -3
- package/lib/types/index.d.ts +16 -0
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# @
|
|
1
|
+
# @lmzhen/dsh-evolution-curator
|
|
2
2
|
|
|
3
3
|
Deterministic skill lifecycle and recovery
|
|
4
4
|
|
|
@@ -8,7 +8,7 @@ Deterministic skill lifecycle and recovery
|
|
|
8
8
|
|
|
9
9
|
#### What the model sees
|
|
10
10
|
|
|
11
|
-
`@
|
|
11
|
+
`@lmzhen/dsh-evolution-curator` registers no direct prompt or tool schema itself. Model-visible effects are owned by the packages that consume this service.
|
|
12
12
|
|
|
13
13
|
#### Token effect
|
|
14
14
|
|
package/lib/index.js
CHANGED
|
@@ -355,6 +355,7 @@ var EvolutionCurator = class extends Service {
|
|
|
355
355
|
async restoreSnapshot() {
|
|
356
356
|
const release = await this.acquireMutex();
|
|
357
357
|
try {
|
|
358
|
+
if (!this.holdsInstance) return this.instanceHeldRefusal("restoreSnapshot");
|
|
358
359
|
return await this.restoreSnapshotCore();
|
|
359
360
|
} finally {
|
|
360
361
|
release();
|
|
@@ -468,6 +469,27 @@ var EvolutionCurator = class extends Service {
|
|
|
468
469
|
};
|
|
469
470
|
return prev.then(() => release);
|
|
470
471
|
}
|
|
472
|
+
/**
|
|
473
|
+
* PLAN S4.5 (2026-09-16) (audit P2-16): the manual control-plane entries
|
|
474
|
+
* (restore/consolidate/restoreSnapshot) honor the same per-home instance
|
|
475
|
+
* claim `run()` checks before every pass. The claim is taken at MOUNT and
|
|
476
|
+
* released at DISPOSE (core/instance-scope.ts), so `holdsInstance` is
|
|
477
|
+
* stable for this instance's lifetime: a single-instance deployment always
|
|
478
|
+
* holds it and every manual entry behaves exactly as before. The refusal
|
|
479
|
+
* fires only on a YIELDING second row of one process, whose manual mutation
|
|
480
|
+
* would otherwise race the holder row's in-flight run over the same tree —
|
|
481
|
+
* this instance's control-plane mutex cannot see the holder's chain. The
|
|
482
|
+
* shape is the plain `SkillActionResult` failure the command face already
|
|
483
|
+
* renders through `err(result.message)` — no new error type — and the
|
|
484
|
+
* leading `instance-held` token names the same outcome run() reports via
|
|
485
|
+
* its `skipped` field.
|
|
486
|
+
*/
|
|
487
|
+
instanceHeldRefusal(operation) {
|
|
488
|
+
return {
|
|
489
|
+
ok: false,
|
|
490
|
+
message: `instance-held: this curator row yielded the per-home claim to another curator row of this process — ${operation} is refused alongside run() so the holder row stays the only control-plane writer (run it on the holder row)`
|
|
491
|
+
};
|
|
492
|
+
}
|
|
471
493
|
async runCore(options = {}) {
|
|
472
494
|
const { ignoreGates = false, dryRun = false } = options;
|
|
473
495
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -498,13 +520,13 @@ var EvolutionCurator = class extends Service {
|
|
|
498
520
|
};
|
|
499
521
|
if (!ignoreGates && persisted === null && (stateService !== void 0 || !this.statelessFirstRunDeferred)) {
|
|
500
522
|
if (stateService) try {
|
|
501
|
-
await stateService.
|
|
523
|
+
await stateService.transactCuratorState((current) => current === null ? {
|
|
502
524
|
schemaVersion: 1,
|
|
503
525
|
lastRunAt: Date.now(),
|
|
504
526
|
runCount: 0,
|
|
505
527
|
lastSummary: "first-run-deferred",
|
|
506
528
|
paused: false
|
|
507
|
-
});
|
|
529
|
+
} : null);
|
|
508
530
|
} catch (error) {
|
|
509
531
|
this.ctx.logger.warn(`evolution-curator: failed to persist the first-run baseline: ${error instanceof Error ? error.message : String(error)}`);
|
|
510
532
|
}
|
|
@@ -547,7 +569,7 @@ var EvolutionCurator = class extends Service {
|
|
|
547
569
|
if (text) contents.set(name, text);
|
|
548
570
|
}
|
|
549
571
|
const protectedNames = await this.protectedNameMap();
|
|
550
|
-
const dedupMembers = [...new Set(computeDedupGroups({ contents }).filter((group) => group.length >= 2).flat())].filter((name) => !protectedNames.has(name));
|
|
572
|
+
const dedupMembers = [...new Set(computeDedupGroups({ contents }).groups.filter((group) => group.length >= 2).flat())].filter((name) => !protectedNames.has(name));
|
|
551
573
|
await this.scoreTree(usage, treeNames, contents);
|
|
552
574
|
const result = computeLifecycleTransitions(usage, {
|
|
553
575
|
staleAfterDays: lifecycle.staleAfterDays,
|
|
@@ -1111,6 +1133,7 @@ var EvolutionCurator = class extends Service {
|
|
|
1111
1133
|
async consolidate(target, sources) {
|
|
1112
1134
|
const release = await this.acquireMutex();
|
|
1113
1135
|
try {
|
|
1136
|
+
if (!this.holdsInstance) return this.instanceHeldRefusal("consolidate");
|
|
1114
1137
|
return await this.consolidateMutate(target, sources);
|
|
1115
1138
|
} finally {
|
|
1116
1139
|
release();
|
|
@@ -1155,6 +1178,7 @@ var EvolutionCurator = class extends Service {
|
|
|
1155
1178
|
async restore(name) {
|
|
1156
1179
|
const release = await this.acquireMutex();
|
|
1157
1180
|
try {
|
|
1181
|
+
if (!this.holdsInstance) return this.instanceHeldRefusal("restore");
|
|
1158
1182
|
return await this.restoreMutate(name);
|
|
1159
1183
|
} finally {
|
|
1160
1184
|
release();
|
package/lib/types/index.d.ts
CHANGED
|
@@ -243,6 +243,22 @@ export declare class EvolutionCurator extends Service {
|
|
|
243
243
|
private mutexDepth;
|
|
244
244
|
private mutexTail;
|
|
245
245
|
private acquireMutex;
|
|
246
|
+
/**
|
|
247
|
+
* PLAN S4.5 (2026-09-16) (audit P2-16): the manual control-plane entries
|
|
248
|
+
* (restore/consolidate/restoreSnapshot) honor the same per-home instance
|
|
249
|
+
* claim `run()` checks before every pass. The claim is taken at MOUNT and
|
|
250
|
+
* released at DISPOSE (core/instance-scope.ts), so `holdsInstance` is
|
|
251
|
+
* stable for this instance's lifetime: a single-instance deployment always
|
|
252
|
+
* holds it and every manual entry behaves exactly as before. The refusal
|
|
253
|
+
* fires only on a YIELDING second row of one process, whose manual mutation
|
|
254
|
+
* would otherwise race the holder row's in-flight run over the same tree —
|
|
255
|
+
* this instance's control-plane mutex cannot see the holder's chain. The
|
|
256
|
+
* shape is the plain `SkillActionResult` failure the command face already
|
|
257
|
+
* renders through `err(result.message)` — no new error type — and the
|
|
258
|
+
* leading `instance-held` token names the same outcome run() reports via
|
|
259
|
+
* its `skipped` field.
|
|
260
|
+
*/
|
|
261
|
+
private instanceHeldRefusal;
|
|
246
262
|
private runCore;
|
|
247
263
|
/**
|
|
248
264
|
* Seed baseline records for tree skills the sidecar has not seen yet, so
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lmzhen/dsh-evolution-curator",
|
|
3
3
|
"description": "Deterministic skill lifecycle and recovery (community build)",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.83",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -27,20 +27,20 @@
|
|
|
27
27
|
"license": "MIT",
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@deepseek-ai/schemastery": "^3.18.1",
|
|
30
|
-
"@lmzhen/dsh-evolution-core": "^0.3.
|
|
30
|
+
"@lmzhen/dsh-evolution-core": "^0.3.83"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
34
34
|
"@deepseek-ai/dsh-llm": "^0.1.5-rc.2",
|
|
35
35
|
"@deepseek-ai/dsh-session": "^0.1.5-rc.2",
|
|
36
|
-
"@lmzhen/dsh-evolution-io": "^0.3.
|
|
37
|
-
"@lmzhen/dsh-evolution-state": "^0.3.
|
|
36
|
+
"@lmzhen/dsh-evolution-io": "^0.3.83",
|
|
37
|
+
"@lmzhen/dsh-evolution-state": "^0.3.83"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@deepseek-ai/dsh-llm": "^0.1.5-rc.2",
|
|
41
41
|
"@deepseek-ai/dsh-session": "^0.1.5-rc.2",
|
|
42
|
-
"@lmzhen/dsh-evolution-core": "^0.3.
|
|
43
|
-
"@lmzhen/dsh-evolution-io": "^0.3.
|
|
44
|
-
"@lmzhen/dsh-evolution-state": "^0.3.
|
|
42
|
+
"@lmzhen/dsh-evolution-core": "^0.3.83",
|
|
43
|
+
"@lmzhen/dsh-evolution-io": "^0.3.83",
|
|
44
|
+
"@lmzhen/dsh-evolution-state": "^0.3.83"
|
|
45
45
|
}
|
|
46
46
|
}
|