@lmzhen/dsh-evolution-maintenance 0.3.81 → 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 CHANGED
@@ -1,4 +1,4 @@
1
- # @deepseek-ai/dsh-evolution-maintenance
1
+ # @lmzhen/dsh-evolution-maintenance
2
2
 
3
3
  Skill-library drift-scanning determinism surface for the maintenance subagent
4
4
  (design 011 — the maintenance-subagent design paper, archived in git history).
@@ -6,7 +6,7 @@ Skill-library drift-scanning determinism surface for the maintenance subagent
6
6
  - `snapshotFromLibrary` — assemble a plain skill snapshot from a SkillLibrary-like reader.
7
7
  - `renderFacts` — canonical `MECHANICAL_FACTS` block (version + joint signature + redaction).
8
8
 
9
- Signal computation lives in `@deepseek-ai/dsh-evolution-core` (`drift-signals`); this
9
+ Signal computation lives in `@lmzhen/dsh-evolution-core` (`drift-signals`); this
10
10
  package owns assembly and rendering only.
11
11
 
12
12
  ## Known Limitations and Deferred Work
@@ -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") return result(signal, computeDedupGroups({ contents: new Map(snapshots.map((snapshot) => [snapshot.name, snapshot.body])) }).map((group) => group.join(" ~ ")));
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-0HDS4Bed.js";
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 overSignals = /* @__PURE__ */ new Set();
236
- for (const signal of report.library) if (signal.verdict === "over") overSignals.add(signal.id);
237
- for (const skill of report.skills) for (const signal of skill.signals) if (signal.verdict === "over") overSignals.add(signal.id);
238
- const covered = new Set(plan.flatMap((item) => item.evidence.map((ev) => ev.signal)));
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 && overSignals.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)");
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 = [...overSignals].filter((id) => !covered.has(id) && !notesText.includes(id));
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" && overSignals.size > 0) {
246
- const uncovered = [...overSignals].filter((id) => !notesText.includes(id));
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-0HDS4Bed.js";
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.3.81",
4
+ "version": "0.3.83",
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.3.81"
34
+ "@lmzhen/dsh-evolution-core": "^0.3.83"
35
35
  },
36
36
  "peerDependencies": {
37
37
  "@deepseek-ai/dsh-agent": "^0.1.5-rc.2",