@lmzhen/dsh-evolution-curator 0.1.0 → 0.2.0-rc.2
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/lib/index.js +45 -3
- package/lib/types/index.d.ts +23 -1
- package/package.json +7 -7
package/lib/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { randomUUID } from "node:crypto";
|
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { BlockAssembler, createUserMessage } from "@deepseek-ai/dsh-llm";
|
|
5
5
|
import z from "@deepseek-ai/schemastery";
|
|
6
|
-
import { CURATOR_DRY_RUN_BANNER, CURATOR_PROMPT, DEFAULT_ARCHIVE_AFTER_DAYS, DEFAULT_CURATOR_INTERVAL_HOURS, DEFAULT_MIN_IDLE_HOURS, DEFAULT_STALE_AFTER_DAYS, EvolutionGateSet, SkillLibrary, buildCuratorRunReport, computeDedupGroups, computeLifecycleTransitions, computePrefixClusters, computeQualityScores, computeScopeView, emptyRecord, evolutionHome, evolutionIoAdapter, foldCuratorFields, loadSuppressedNames, loadUsage, mutateUsage, parseCuratorNominations, relatedSkillNames, renderCuratorReportMarkdown, updateSuppressedNames } from "@lmzhen/dsh-evolution-core";
|
|
6
|
+
import { CURATOR_DRY_RUN_BANNER, CURATOR_PROMPT, DEFAULT_ARCHIVE_AFTER_DAYS, DEFAULT_CURATOR_INTERVAL_HOURS, DEFAULT_HEALTH_THRESHOLDS, DEFAULT_MIN_IDLE_HOURS, DEFAULT_STALE_AFTER_DAYS, EvolutionGateSet, SkillLibrary, buildCuratorRunReport, computeDedupGroups, computeLifecycleTransitions, computePrefixClusters, computeQualityScores, computeScopeView, emptyRecord, evolutionHome, evolutionIoAdapter, foldCuratorFields, loadSuppressedNames, loadUsage, mutateUsage, parseCuratorNominations, relatedSkillNames, renderCuratorReportMarkdown, updateSuppressedNames, usageObserved } from "@lmzhen/dsh-evolution-core";
|
|
7
7
|
//#region lib/types/index.js
|
|
8
8
|
/**
|
|
9
9
|
* Deterministic skill lifecycle curator with interval gate and archive.
|
|
@@ -38,7 +38,10 @@ var EvolutionCurator = class extends Service {
|
|
|
38
38
|
referencedSkillNames: z.array(z.string()).default([]),
|
|
39
39
|
autoStart: z.boolean().default(true),
|
|
40
40
|
bootGraceSeconds: z.number().default(10),
|
|
41
|
-
curatorReviewMaxTokens: z.number().default(2048)
|
|
41
|
+
curatorReviewMaxTokens: z.number().default(2048),
|
|
42
|
+
healthSoftBodyChars: z.number().default(DEFAULT_HEALTH_THRESHOLDS.softBodyChars),
|
|
43
|
+
healthStampDensityPerKb: z.number().default(DEFAULT_HEALTH_THRESHOLDS.stampDensityPerKb),
|
|
44
|
+
healthChurnMinPatches: z.number().default(DEFAULT_HEALTH_THRESHOLDS.churnMinPatches)
|
|
42
45
|
});
|
|
43
46
|
skills;
|
|
44
47
|
io;
|
|
@@ -56,6 +59,9 @@ var EvolutionCurator = class extends Service {
|
|
|
56
59
|
referencedSkillNames;
|
|
57
60
|
bootGraceSeconds;
|
|
58
61
|
curatorReviewMaxTokens;
|
|
62
|
+
healthSoftBodyChars;
|
|
63
|
+
healthStampDensityPerKb;
|
|
64
|
+
healthChurnMinPatches;
|
|
59
65
|
lastRun = 0;
|
|
60
66
|
timer;
|
|
61
67
|
bootCheck;
|
|
@@ -80,6 +86,9 @@ var EvolutionCurator = class extends Service {
|
|
|
80
86
|
this.referencedSkillNames = new Set(config.referencedSkillNames ?? []);
|
|
81
87
|
this.bootGraceSeconds = config.bootGraceSeconds ?? 10;
|
|
82
88
|
this.curatorReviewMaxTokens = config.curatorReviewMaxTokens ?? 2048;
|
|
89
|
+
this.healthSoftBodyChars = config.healthSoftBodyChars ?? DEFAULT_HEALTH_THRESHOLDS.softBodyChars;
|
|
90
|
+
this.healthStampDensityPerKb = config.healthStampDensityPerKb ?? DEFAULT_HEALTH_THRESHOLDS.stampDensityPerKb;
|
|
91
|
+
this.healthChurnMinPatches = config.healthChurnMinPatches ?? DEFAULT_HEALTH_THRESHOLDS.churnMinPatches;
|
|
83
92
|
this.lastRun = Date.now();
|
|
84
93
|
this.ctx.effect(() => {
|
|
85
94
|
return () => {
|
|
@@ -545,7 +554,7 @@ var EvolutionCurator = class extends Service {
|
|
|
545
554
|
errors.push(`${nomination.from}: consolidation nomination outside the candidate pool — refused (advisory text has no executability authority)`);
|
|
546
555
|
continue;
|
|
547
556
|
}
|
|
548
|
-
const consolidated = await this.skills.consolidate(nomination.into, [nomination.from], "background_review");
|
|
557
|
+
const consolidated = await this.skills.consolidate(nomination.into, [nomination.from], "background_review", { ...nomination.mode === void 0 ? {} : { mode: nomination.mode } });
|
|
549
558
|
if (!consolidated.ok) {
|
|
550
559
|
errors.push(`${nomination.from}: ${consolidated.message}`);
|
|
551
560
|
continue;
|
|
@@ -691,6 +700,39 @@ var EvolutionCurator = class extends Service {
|
|
|
691
700
|
bundledNames
|
|
692
701
|
}, await this.protectedNameMap(), gates);
|
|
693
702
|
}
|
|
703
|
+
/**
|
|
704
|
+
* Structure-health view (rc.73 A1, 008 design): degraded skills only,
|
|
705
|
+
* derived on demand — never persisted. Signals for review/curate proposals;
|
|
706
|
+
* the deterministic assessment stays here, refinement stays in the judgment
|
|
707
|
+
* layer.
|
|
708
|
+
*/
|
|
709
|
+
async healthView() {
|
|
710
|
+
const thresholds = {
|
|
711
|
+
softBodyChars: this.healthSoftBodyChars,
|
|
712
|
+
stampDensityPerKb: this.healthStampDensityPerKb,
|
|
713
|
+
churnMinPatches: this.healthChurnMinPatches
|
|
714
|
+
};
|
|
715
|
+
const usage = await loadUsage(this.skills.root, this.io);
|
|
716
|
+
const observed = usageObserved(usage);
|
|
717
|
+
const rows = [];
|
|
718
|
+
for (const summary of await this.skills.list()) {
|
|
719
|
+
const record = usage.get(summary.name);
|
|
720
|
+
const assessment = await this.skills.assessHealth(summary.name, thresholds, observed && record ? {
|
|
721
|
+
patchCount: record.patch_count,
|
|
722
|
+
readCount: record.view_count
|
|
723
|
+
} : void 0);
|
|
724
|
+
if (assessment && assessment.verdict !== "healthy") rows.push({
|
|
725
|
+
name: summary.name,
|
|
726
|
+
verdict: assessment.verdict,
|
|
727
|
+
reasons: assessment.reasons
|
|
728
|
+
});
|
|
729
|
+
}
|
|
730
|
+
return rows;
|
|
731
|
+
}
|
|
732
|
+
/** Whether the library has ANY observed read evidence (C observation-window gate for churn signals). */
|
|
733
|
+
async usageObserved() {
|
|
734
|
+
return usageObserved(await loadUsage(this.skills.root, this.io));
|
|
735
|
+
}
|
|
694
736
|
/** marker info (pinned/bundled/hub-installed) per skill, from the library list. */
|
|
695
737
|
async protectedNameMap() {
|
|
696
738
|
const map = /* @__PURE__ */ new Map();
|
package/lib/types/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { Context, Service } from '@deepseek-ai/cordis';
|
|
6
6
|
import type Schema from '@deepseek-ai/schemastery';
|
|
7
7
|
import { EvolutionGateSet, SkillLibrary } from '@deepseek-ai/dsh-evolution-core';
|
|
8
|
-
import { type CuratorConsolidation, type CuratorNominations, type CuratorRunReport, type ScopeView, type SkillActionResult } from '@deepseek-ai/dsh-evolution-core';
|
|
8
|
+
import { type CuratorConsolidation, type CuratorNominations, type CuratorRunReport, type ScopeView, type SkillActionResult, type SkillHealthVerdict } from '@deepseek-ai/dsh-evolution-core';
|
|
9
9
|
declare module '@deepseek-ai/cordis' {
|
|
10
10
|
interface Context {
|
|
11
11
|
evolutionCurator: EvolutionCurator;
|
|
@@ -37,6 +37,12 @@ export interface Config {
|
|
|
37
37
|
bootGraceSeconds?: number;
|
|
38
38
|
/** Max tokens for the optional LLM nomination pass. */
|
|
39
39
|
curatorReviewMaxTokens?: number;
|
|
40
|
+
/** Structure-health soft body limit (chars) — see DEFAULT_HEALTH_THRESHOLDS (rc.73 A1). */
|
|
41
|
+
healthSoftBodyChars?: number;
|
|
42
|
+
/** Structure-health stamp-density ceiling per KB — see DEFAULT_HEALTH_THRESHOLDS. */
|
|
43
|
+
healthStampDensityPerKb?: number;
|
|
44
|
+
/** Structure-health write-ghost floor: patches at/above with zero reads (A2). */
|
|
45
|
+
healthChurnMinPatches?: number;
|
|
40
46
|
}
|
|
41
47
|
/** Outcome of one curator run pass. */
|
|
42
48
|
export interface CuratorRunOutcome {
|
|
@@ -86,6 +92,9 @@ export declare class EvolutionCurator extends Service {
|
|
|
86
92
|
private readonly referencedSkillNames;
|
|
87
93
|
private readonly bootGraceSeconds;
|
|
88
94
|
private readonly curatorReviewMaxTokens;
|
|
95
|
+
private readonly healthSoftBodyChars;
|
|
96
|
+
private readonly healthStampDensityPerKb;
|
|
97
|
+
private readonly healthChurnMinPatches;
|
|
89
98
|
private lastRun;
|
|
90
99
|
private timer;
|
|
91
100
|
private bootCheck;
|
|
@@ -201,6 +210,19 @@ export declare class EvolutionCurator extends Service {
|
|
|
201
210
|
* so the view always predicts what a curator pass may touch.
|
|
202
211
|
*/
|
|
203
212
|
scopeView(): Promise<ScopeView>;
|
|
213
|
+
/**
|
|
214
|
+
* Structure-health view (rc.73 A1, 008 design): degraded skills only,
|
|
215
|
+
* derived on demand — never persisted. Signals for review/curate proposals;
|
|
216
|
+
* the deterministic assessment stays here, refinement stays in the judgment
|
|
217
|
+
* layer.
|
|
218
|
+
*/
|
|
219
|
+
healthView(): Promise<Array<{
|
|
220
|
+
name: string;
|
|
221
|
+
verdict: SkillHealthVerdict;
|
|
222
|
+
reasons: string[];
|
|
223
|
+
}>>;
|
|
224
|
+
/** Whether the library has ANY observed read evidence (C observation-window gate for churn signals). */
|
|
225
|
+
usageObserved(): Promise<boolean>;
|
|
204
226
|
/** marker info (pinned/bundled/hub-installed) per skill, from the library list. */
|
|
205
227
|
private protectedNameMap;
|
|
206
228
|
/**
|
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.
|
|
4
|
+
"version": "0.2.0-rc.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -33,20 +33,20 @@
|
|
|
33
33
|
"license": "MIT",
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@deepseek-ai/schemastery": "^3.18.1",
|
|
36
|
-
"@lmzhen/dsh-evolution-core": "^0.
|
|
36
|
+
"@lmzhen/dsh-evolution-core": "^0.2.0-rc.2"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
40
40
|
"@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
|
|
41
41
|
"@deepseek-ai/dsh-llm": "^0.1.1-rc.2",
|
|
42
|
-
"@lmzhen/dsh-evolution-io": "^0.
|
|
43
|
-
"@lmzhen/dsh-evolution-state": "^0.
|
|
42
|
+
"@lmzhen/dsh-evolution-io": "^0.2.0-rc.2",
|
|
43
|
+
"@lmzhen/dsh-evolution-state": "^0.2.0-rc.2"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
|
|
47
47
|
"@deepseek-ai/dsh-llm": "^0.1.1-rc.2",
|
|
48
|
-
"@lmzhen/dsh-evolution-core": "^0.
|
|
49
|
-
"@lmzhen/dsh-evolution-io": "^0.
|
|
50
|
-
"@lmzhen/dsh-evolution-state": "^0.
|
|
48
|
+
"@lmzhen/dsh-evolution-core": "^0.2.0-rc.2",
|
|
49
|
+
"@lmzhen/dsh-evolution-io": "^0.2.0-rc.2",
|
|
50
|
+
"@lmzhen/dsh-evolution-state": "^0.2.0-rc.2"
|
|
51
51
|
}
|
|
52
52
|
}
|