@lmzhen/dsh-evolution-maintenance 0.3.82 → 0.4.0
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 +29 -28
- package/lib/{enrichment-0HDS4Bed.js → enrichment-31K43lVa.js} +6 -1
- package/lib/index.js +13 -9
- package/lib/tools.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,30 +1,31 @@
|
|
|
1
|
-
# @
|
|
2
|
-
|
|
3
|
-
Skill-library drift-scanning determinism surface for the maintenance subagent
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
- `
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
in the subagent prompt) when the tool row is not mounted, instead of failing
|
|
24
|
-
the spawn; an explicit `toolAllow` option bypasses the probe.
|
|
25
|
-
- The model-visible template (`MAINTAIN_PROMPT`) and the subagent output
|
|
26
|
-
instruction (`MAINTAIN_OUTPUT_INSTRUCTION`, V10 F-16) ship in `evolution-core`
|
|
27
|
-
`PROMPT_BUNDLE`; the joint-signature mismatch protocol is honored by
|
|
28
|
-
`renderFacts` callers, not by this package alone.
|
|
1
|
+
# @lmzhen/dsh-evolution-maintenance
|
|
2
|
+
|
|
3
|
+
Skill-library drift-scanning determinism surface for the maintenance subagent: it assembles the
|
|
4
|
+
skill snapshot, renders the mechanical-facts block and runs the scan → subagent → validate
|
|
5
|
+
chain behind `/evolution maintain` (`evolution-core` `drift-signals`).
|
|
6
|
+
|
|
7
|
+
- `snapshotFromLibrary`: assemble a plain skill snapshot from a SkillLibrary-like reader.
|
|
8
|
+
- `renderFacts`: canonical `MECHANICAL_FACTS` block (version + joint signature + redaction).
|
|
9
|
+
|
|
10
|
+
## Model surface
|
|
11
|
+
|
|
12
|
+
- **Model-visible:** the read-only `maintenance_probe` tool schema (`evolution-maintenance/tools`), mounted for every session.
|
|
13
|
+
- **Prompt prefix / KV cache:** no system-prompt section of its own; family-level rules: `packages/README.md` §"Model-visible prompt prefix and the KV cache".
|
|
14
|
+
- **Mount it?** yes — the `evolution-maintenance/tools` row (host/all/preset); the orchestration is consumed by `evolution-commands` (`/evolution maintain`).
|
|
15
|
+
|
|
16
|
+
## Known limitations
|
|
17
|
+
|
|
18
|
+
- Phase 1-2 expose no service beyond the command surface: the chain (scan → render → subagent → validate) is wired through `/evolution maintain`.
|
|
19
|
+
- **Plan validation is instance-granular (§3 completeness).** Notes stay id-level: one mention explains away every instance of that id.
|
|
20
|
+
- **A budget-capped dedup scan is reported, never silently shortened.**
|
|
21
|
+
- `maintenance_probe` is readable by every session; maintenance subagents reach it through the orchestrate `toolFilter` allow-list.
|
|
22
|
+
- The model-visible template (`MAINTAIN_PROMPT`) and the subagent output instruction (`MAINTAIN_OUTPUT_INSTRUCTION`, V10 F-16) ship in `evolution-core` `PROMPT_BUNDLE`; the joint-signature mismatch protocol is honored by `renderFacts` callers, not by this package alone.
|
|
29
23
|
|
|
30
24
|
**Runtime invariant:** No companion is published. The platform auto-assembles nothing and the family mounts no `<pkg>/invariant` cordis row, so a companion here would never execute (v37 S2.1 / I-3).
|
|
25
|
+
|
|
26
|
+
## Notes and history
|
|
27
|
+
|
|
28
|
+
- (design 011: the maintenance-subagent design paper, archived in git history).
|
|
29
|
+
- The facts block renders one line per skill, so ONE signal id can be `over` on several skills: every `over` instance (`skill::id`; a library-level signal renders once and keeps the bare id) must be covered by plan evidence or named in a note, so a plan that advises one skill no longer zero-explains the same signal on its siblings (P2-4, 0.3.83).
|
|
30
|
+
- `maintenance_probe` appends "note: dedup scan truncated at the pair-comparison budget; groups may be incomplete" and the `dedup_group` signal value carries the same qualification (P2-8, 0.3.83).
|
|
31
|
+
- V10 (F-02): orchestrate soft-probes the tools registry before spawning and degrades the filter to `skill`-only (declared in the subagent prompt) when the tool row is not mounted, instead of failing the spawn; an explicit `toolAllow` option bypasses the probe.
|
|
@@ -84,7 +84,12 @@ function findSnapshot(snapshots, name) {
|
|
|
84
84
|
*/
|
|
85
85
|
function computeProbe(signal, target, snapshots) {
|
|
86
86
|
if (!PROBE_SIGNALS.includes(signal)) return result(signal, [`unknown-signal '${signal}' (allowed: ${PROBE_SIGNALS.join(", ")})`], target);
|
|
87
|
-
if (signal === "dedup_group")
|
|
87
|
+
if (signal === "dedup_group") {
|
|
88
|
+
const dedup = computeDedupGroups({ contents: new Map(snapshots.map((snapshot) => [snapshot.name, snapshot.body])) });
|
|
89
|
+
const details = dedup.groups.map((group) => group.join(" ~ "));
|
|
90
|
+
if (dedup.truncated) details.push("note: dedup scan truncated at the pair-comparison budget; groups may be incomplete");
|
|
91
|
+
return result(signal, details);
|
|
92
|
+
}
|
|
88
93
|
if (signal === "prefix_cluster") return result(signal, computePrefixClusters(snapshots.map((snapshot) => snapshot.name)).map((cluster) => `${cluster.key}: ${cluster.members.join(", ")}`));
|
|
89
94
|
if (signal === "usage_observed") {
|
|
90
95
|
if (!(snapshots.length > 0 && snapshots.every((snapshot) => snapshot.usageObserved !== null && snapshot.usageObserved !== void 0))) return result(signal, ["usage_observed=unknown"]);
|
package/lib/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as snapshotFromLibrary, n as PROBE_SIGNALS, r as computeProbe, t as buildEnrichment } from "./enrichment-
|
|
1
|
+
import { i as snapshotFromLibrary, n as PROBE_SIGNALS, r as computeProbe, t as buildEnrichment } from "./enrichment-31K43lVa.js";
|
|
2
2
|
import { AUTHORING_DESCRIPTION_BAR, DEFAULT_CURATOR_MODEL, DEFAULT_HEALTH_THRESHOLDS, DRIFT_MAX_LINE_CHARS, DRIFT_SIGNALS_VERSION, DRIFT_SIGNAL_NOUNS, LOW_QUALITY_THRESHOLD, MAINTAIN_OUTPUT_INSTRUCTION, MAINTAIN_PROMPT, MAX_TIMER_DELAY_MS, MIN_STAMP_BODY_CHARS, PROMPT_BUNDLE, PROMPT_BUNDLE_ID, computeDriftSignals, findDriftSignal, redactSecrets, verifyPromptBundle } from "@lmzhen/dsh-evolution-core";
|
|
3
3
|
import { createHash, randomUUID } from "node:crypto";
|
|
4
4
|
//#region lib/types/render-facts.js
|
|
@@ -232,18 +232,22 @@ function validateAndNormalizeMaintainPlan(raw, report, validSignals) {
|
|
|
232
232
|
}
|
|
233
233
|
}
|
|
234
234
|
const notes = Array.isArray(raw.notes) ? raw.notes.filter((note) => isNonEmptyString(note)) : [];
|
|
235
|
-
const
|
|
236
|
-
for (const signal of report.library) if (signal.verdict === "over")
|
|
237
|
-
for (const skill of report.skills) for (const signal of skill.signals) if (signal.verdict === "over")
|
|
238
|
-
const covered = new Set(
|
|
235
|
+
const overInstances = /* @__PURE__ */ new Map();
|
|
236
|
+
for (const signal of report.library) if (signal.verdict === "over") overInstances.set(signal.id, signal.id);
|
|
237
|
+
for (const skill of report.skills) for (const signal of skill.signals) if (signal.verdict === "over") overInstances.set(`${skill.name.trim()}::${signal.id}`, signal.id);
|
|
238
|
+
const covered = /* @__PURE__ */ new Set();
|
|
239
|
+
for (const item of plan) for (const ev of item.evidence) {
|
|
240
|
+
covered.add(ev.signal);
|
|
241
|
+
for (const name of item.names) covered.add(`${name}::${ev.signal}`);
|
|
242
|
+
}
|
|
239
243
|
const notesText = notes.join("\n");
|
|
240
|
-
if (verdict === "issues") if (plan.length === 0 && notes.length === 0 &&
|
|
244
|
+
if (verdict === "issues") if (plan.length === 0 && notes.length === 0 && overInstances.size > 0) errors.push("completeness: verdict=issues with an empty plan AND no notes — every over signal must be covered by evidence or named in a note (§3)");
|
|
241
245
|
else {
|
|
242
|
-
const uncovered = [...
|
|
246
|
+
const uncovered = [...overInstances].filter(([instance, id]) => !covered.has(instance) && !notesText.includes(id)).map(([instance]) => instance);
|
|
243
247
|
if (uncovered.length > 0) errors.push(`completeness: over signal(s) not covered by any plan evidence nor named in a note (${uncovered.join(", ")}) — §3 requires each over signal to be addressed or explicitly explained away`);
|
|
244
248
|
}
|
|
245
|
-
else if (verdict === "no_issues" &&
|
|
246
|
-
const uncovered = [...
|
|
249
|
+
else if (verdict === "no_issues" && overInstances.size > 0) {
|
|
250
|
+
const uncovered = [...overInstances].filter(([, id]) => !notesText.includes(id)).map(([instance]) => instance);
|
|
247
251
|
if (uncovered.length > 0) errors.push(`completeness: verdict=no_issues while the facts block carries over signal(s) not named in any note (${uncovered.join(", ")}) — each signal must be explicitly explained away in notes (§3/§7)`);
|
|
248
252
|
}
|
|
249
253
|
if (errors.length > 0) return {
|
package/lib/tools.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as snapshotFromLibrary, n as PROBE_SIGNALS, r as computeProbe, t as buildEnrichment } from "./enrichment-
|
|
1
|
+
import { i as snapshotFromLibrary, n as PROBE_SIGNALS, r as computeProbe, t as buildEnrichment } from "./enrichment-31K43lVa.js";
|
|
2
2
|
import { assertSkillsRootAliasRetired, newSkillLibrary, redactSecrets, resolveRootConfig } from "@lmzhen/dsh-evolution-core";
|
|
3
3
|
import z from "@deepseek-ai/schemastery";
|
|
4
4
|
import { defineTool } from "@deepseek-ai/dsh-tools";
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lmzhen/dsh-evolution-maintenance",
|
|
3
3
|
"description": "Deterministic maintenance-scan surface: skill-library snapshot assembly, drift signals and mechanical-facts rendering (design 011) (community build)",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.4.0",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"license": "MIT",
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@deepseek-ai/schemastery": "^3.18.1",
|
|
34
|
-
"@lmzhen/dsh-evolution-core": "^0.
|
|
34
|
+
"@lmzhen/dsh-evolution-core": "^0.4.0"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
37
|
"@deepseek-ai/dsh-agent": "^0.1.5-rc.2",
|