@lmzhen/dsh-evolution-review 0.9.0 → 0.11.1

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.
Files changed (3) hide show
  1. package/README.md +1 -0
  2. package/lib/index.js +5 -1
  3. package/package.json +11 -11
package/README.md CHANGED
@@ -23,6 +23,7 @@ own, and the delivery mode lives on the `evolution-policy` row, not here.
23
23
  - When the `evolution-state` service is not mounted, the memory/skill cadence state is not persisted and every turn restarts from a clean `{ turnsSinceMemory: 0, turnsSinceSkill: 0 }` baseline: the review schedule is stateless and re-decided each turn rather than accumulating across the conversation. The loss is surfaced once per process as a logger warning at the first turn/end.
24
24
  - Read-before-write can see the review subagent's own `skill` reads only when the subagent backend exposes `localAgent` (the in-process driver does; out-of-process backends such as ACP and the CLI providers set `localAgent: undefined`). With a remote backend the subagent's reads are invisible, so a plan item patching a skill the subagent itself loaded is dropped as "unread": the review then falls back to the parent session's reads only.
25
25
  - **The default `reviewMode: 'inject'` produces no plan ledger.** The review runs in the parent session and emits no `evolution/plan-applied` event, so `evolution-activity`'s `activity.json` and the `evolution-replay` leaderboard never grow in this mode: the only production emit point sits inside the subagent path. Set `reviewMode: 'subagent'` on the `evolution-policy` row when the plan audit trail is required; the plugin states this once at load instead of leaving an empty ledger to be read as "no reviews happened" (v37 S2.2, plan decision (c)).
26
+ - **Evidence that cites only bookkeeping frames is REPORTED, never refused (phase 1).** `EVIDENCE_CLASS` (`evolution-plan-validator`) counts the ops whose entire `evidence` list points at turn/step boundary frames — a seq the range rule accepts but that carries no content — and this plugin logs one `dsh-evolution-review:` warning per plan; the count rides `evolution/plan-applied` as `evidenceClassReports` and appears in no model-visible text. Nothing is dropped: `EVIDENCE_RANGE` remains the only evidence gate, and a session log whose frames carry no `seq` leaves the report silent (`undefined` is not an empty index) instead of reporting every op.
26
27
  - **`.pinned` protection in the `'inject'` channel rides a family-internal session mark.** The review prompt marks the parent session, `tool-skill-manage` reads that mark and resolves both origin surfaces (approval + library) to `background_review`, and the next REAL user message (`source.kind === 'user'`) clears it (plugin notices, including the review prompt itself, do not). Two bounds follow from the platform's inject contract (no driver wake; a prompt is dropped on cancel/dispose and may be missed with an already-claimed batch): with `reviewWakeInject: false`, or on a host without `followup`, (a) a pending prompt may never execute while the session stays idle, and (b) when the user's next message wakes the session, the mark is cleared before that pending prompt reaches the model (its writes are then attributed `foreground` and the pinned guard does not cover them). A prompt delivered while a HUMAN message is already queued is not marked at all: the platform claims that human turn first, so a session-level window would attribute the user's own writes to `background_review` (S2-8, FLOW1-3): the plugin reads the pre-claim queue (`agent.inbox`) because the platform exposes no claim identity, and warns once per mount when it withholds the mark.
27
28
 
28
29
  ## Configuration
package/lib/index.js CHANGED
@@ -2,7 +2,7 @@ import { createHash, randomUUID } from "node:crypto";
2
2
  import z from "@deepseek-ai/schemastery";
3
3
  import { createUserMessage } from "@deepseek-ai/dsh-llm";
4
4
  import { SessionId } from "@deepseek-ai/dsh-session";
5
- import { COMPLETION_SKILL_REVIEW_PROMPT, DEFAULT_MAX_OPS_PER_PLAN, DEFAULT_MEMORY_CHAR_LIMIT, DEFAULT_MEMORY_REVIEW_MODEL, DEFAULT_REVIEW_CONTEXT_MESSAGES, DEFAULT_REVIEW_MEMORY_INTERVAL, DEFAULT_REVIEW_MESSAGE_CHARS, DEFAULT_REVIEW_SKILL_INTERVAL, DEFAULT_REVIEW_TIMEOUT_MS, DEFAULT_SKILL_CONTENT_CHARS, DEFAULT_SKILL_LIMITS, DEFAULT_SKILL_REVIEW_COMPLETION_MIN_TOOL_CALLS, DEFAULT_SKILL_REVIEW_MODEL, DEFAULT_SKILL_REVIEW_TRIGGER, DEFAULT_SUBSTANTIVE_MIN_AGENT_CHARS, DEFAULT_SUBSTANTIVE_MIN_TOOL_CALLS, DEFAULT_SUBSTANTIVE_MIN_USER_CHARS, DEFAULT_USER_CHAR_LIMIT, MAX_TIMER_DELAY_MS, PROMPT_BUNDLE, advanceReview, assertSkillsRootAliasRetired, clampedNumber, clearReviewChannel, collectReadSkillNames, contentHash, evolutionIoAdapter, filterUnreadSkillOps, filterUnreadSkillOps as filterUnreadSkillOps$1, foldTurn, installParamSection, markReviewChannel, newSkillLibrary, paramNamespace, policyStageLimits, readDispatchSignal, readNumberParam, redactSecrets, resolveOrigins, resolveRootConfig, reviewPrompt, sessionAudited, sweepReviewChannelSessions, verifyPromptBundle } from "@lmzhen/dsh-evolution-core";
5
+ import { COMPLETION_SKILL_REVIEW_PROMPT, DEFAULT_MAX_OPS_PER_PLAN, DEFAULT_MEMORY_CHAR_LIMIT, DEFAULT_MEMORY_REVIEW_MODEL, DEFAULT_REVIEW_CONTEXT_MESSAGES, DEFAULT_REVIEW_MEMORY_INTERVAL, DEFAULT_REVIEW_MESSAGE_CHARS, DEFAULT_REVIEW_SKILL_INTERVAL, DEFAULT_REVIEW_TIMEOUT_MS, DEFAULT_SKILL_CONTENT_CHARS, DEFAULT_SKILL_LIMITS, DEFAULT_SKILL_REVIEW_COMPLETION_MIN_TOOL_CALLS, DEFAULT_SKILL_REVIEW_MODEL, DEFAULT_SKILL_REVIEW_TRIGGER, DEFAULT_SUBSTANTIVE_MIN_AGENT_CHARS, DEFAULT_SUBSTANTIVE_MIN_TOOL_CALLS, DEFAULT_SUBSTANTIVE_MIN_USER_CHARS, DEFAULT_USER_CHAR_LIMIT, MAX_TIMER_DELAY_MS, PROMPT_BUNDLE, advanceReview, assertSkillsRootAliasRetired, clampedNumber, clearReviewChannel, collectReadSkillNames, contentHash, evidenceKindIndex, evolutionIoAdapter, filterUnreadSkillOps, filterUnreadSkillOps as filterUnreadSkillOps$1, foldTurn, installParamSection, markReviewChannel, newSkillLibrary, paramNamespace, policyStageLimits, readDispatchSignal, readNumberParam, redactSecrets, resolveOrigins, resolveRootConfig, reviewPrompt, sessionAudited, sweepReviewChannelSessions, verifyPromptBundle } from "@lmzhen/dsh-evolution-core";
6
6
  import { validateEvolutionPlan } from "@lmzhen/dsh-evolution-plan-validator";
7
7
  //#region lib/types/session-state.js
8
8
  /**
@@ -634,6 +634,7 @@ function apply(ctx, rawConfig = {}) {
634
634
  }
635
635
  const preRunHashes = await treeSkillHashes();
636
636
  const sessionSeqAtPlanTime = session.seq - 1;
637
+ const substantiveEvidenceSeqs = evidenceKindIndex(session.snapshotEvents());
637
638
  const run = await subagents.start("spawn", {
638
639
  label: "dsh-evolution-review",
639
640
  prompt: [{
@@ -666,12 +667,14 @@ function apply(ctx, rawConfig = {}) {
666
667
  const policyFingerprint = fingerprintPolicy(snapshot);
667
668
  const validation = validateEvolutionPlan(plan, {
668
669
  sessionSeq: sessionSeqAtPlanTime,
670
+ substantiveEvidenceSeqs,
669
671
  maxOpsPerPlan: snapshot?.maxOpsPerPlan ?? DEFAULT_MAX_OPS_PER_PLAN,
670
672
  protectedSkillNames: new Set(snapshot?.protectedSkillNames ?? []),
671
673
  maxMemoryChars: snapshot?.memoryChars ?? DEFAULT_MEMORY_CHAR_LIMIT,
672
674
  maxUserChars: snapshot?.userChars ?? DEFAULT_USER_CHAR_LIMIT,
673
675
  maxSkillContentChars: snapshot?.skillContentChars ?? DEFAULT_SKILL_CONTENT_CHARS
674
676
  });
677
+ if (validation.reports.length > 0) ctx.logger.warn(`dsh-evolution-review: ${validation.reports.length} op(s) cite only bookkeeping frames as evidence: ${validation.reports.map((report) => report.reason).join("; ")}`);
675
678
  const acceptedSkillOps = validation.accepted.skillOps ?? [];
676
679
  const skippedUnread = filterUnreadSkillOps$1(acceptedSkillOps, new Set([...collectReadSkillNames(session.snapshotEvents()), ...childReads]));
677
680
  const evidenceQuotes = [...validation.accepted.memoryOps ?? [], ...acceptedSkillOps].reduce((total, op) => total + (Array.isArray(op.evidence) ? op.evidence.length : 0), 0);
@@ -685,6 +688,7 @@ function apply(ctx, rawConfig = {}) {
685
688
  skillApplied: report.actions.filter((action) => action.startsWith("Skill ")).length,
686
689
  rejectedOps: validation.rejected.length,
687
690
  ...skippedUnread > 0 ? { skippedUnread } : {},
691
+ ...validation.reports.length > 0 ? { evidenceClassReports: validation.reports.length } : {},
688
692
  executionFailures: report.failedOps?.length ?? 0,
689
693
  ...report.executionError !== void 0 ? { executionError: report.executionError } : {},
690
694
  evidenceQuotes,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lmzhen/dsh-evolution-review",
3
3
  "description": "Background review orchestration (community build)",
4
- "version": "0.9.0",
4
+ "version": "0.11.1",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -27,9 +27,9 @@
27
27
  "license": "MIT",
28
28
  "dependencies": {
29
29
  "@deepseek-ai/schemastery": "^3.18.1",
30
- "@lmzhen/dsh-evolution-approval": "^0.9.0",
31
- "@lmzhen/dsh-evolution-core": "^0.9.0",
32
- "@lmzhen/dsh-evolution-plan-validator": "^0.9.0"
30
+ "@lmzhen/dsh-evolution-approval": "^0.11.1",
31
+ "@lmzhen/dsh-evolution-core": "^0.11.1",
32
+ "@lmzhen/dsh-evolution-plan-validator": "^0.11.1"
33
33
  },
34
34
  "peerDependencies": {
35
35
  "@deepseek-ai/cordis": "^4.0.1",
@@ -37,8 +37,8 @@
37
37
  "@deepseek-ai/dsh-llm": "^0.1.5-rc.2",
38
38
  "@deepseek-ai/dsh-session": "^0.1.5-rc.2",
39
39
  "@deepseek-ai/dsh-tools": "^0.1.5-rc.2",
40
- "@lmzhen/dsh-evolution-state": "^0.9.0",
41
- "@lmzhen/dsh-evolution-policy": "^0.9.0"
40
+ "@lmzhen/dsh-evolution-state": "^0.11.1",
41
+ "@lmzhen/dsh-evolution-policy": "^0.11.1"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@deepseek-ai/dsh-agent": "^0.1.5-rc.2",
@@ -48,10 +48,10 @@
48
48
  "@deepseek-ai/dsh-session-persistence": "^0.1.5-rc.2",
49
49
  "@deepseek-ai/dsh-session-persistence-jsonl": "^0.1.5-rc.2",
50
50
  "@deepseek-ai/dsh-tools": "^0.1.5-rc.2",
51
- "@lmzhen/dsh-evolution-approval": "^0.9.0",
52
- "@lmzhen/dsh-evolution-core": "^0.9.0",
53
- "@lmzhen/dsh-evolution-curator": "^0.9.0",
54
- "@lmzhen/dsh-evolution-plan-validator": "^0.9.0",
55
- "@lmzhen/dsh-evolution-state": "^0.9.0"
51
+ "@lmzhen/dsh-evolution-approval": "^0.11.1",
52
+ "@lmzhen/dsh-evolution-core": "^0.11.1",
53
+ "@lmzhen/dsh-evolution-curator": "^0.11.1",
54
+ "@lmzhen/dsh-evolution-plan-validator": "^0.11.1",
55
+ "@lmzhen/dsh-evolution-state": "^0.11.1"
56
56
  }
57
57
  }