@lmzhen/dsh-evolution-review 0.1.0-rc.4 → 0.1.0-rc.6

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
@@ -21,4 +21,10 @@ Independent of request-prefix construction. This package does not alter the asse
21
21
  ## Known Limitations and Deferred Work
22
22
 
23
23
 
24
- - - Review subagents inherit the host preset; Anchored Standard deployments rely on the default `skill_search`/`skill_load` allow-list.
24
+ - Review subagents inherit the host preset; Anchored Standard deployments rely on the default `skill_search`/`skill_load` allow-list.
25
+ - Review subagents run as `spawn` children on the deployment default preset rather than inheriting the parent agent's composition (`fork`): a fork child is always promoted by the Anchored Standard bootstrap and its narrowed resident catalog would drop the plain `skill` tool from the review allow-list.
26
+ - The review request text is redacted for credential-shaped patterns before it reaches the subagent, but redaction is pattern-based and best-effort, not a security boundary.
27
+
28
+ ## Configuration
29
+
30
+ `reviewProvider` selects the LLM provider for review subagents. When omitted, the subagent inherits the deployment default route instead of a hardcoded provider name. Model selection stays on the policy (`memoryReviewModel` / `skillReviewModel`).
package/lib/index.js CHANGED
@@ -3,6 +3,35 @@ import z from "@deepseek-ai/schemastery";
3
3
  import { CallId, createUserMessage } from "@deepseek-ai/dsh-llm";
4
4
  import { PROMPT_BUNDLE, advanceReview, foldTurn, reviewPrompt, verifyPromptBundle } from "@lmzhen/dsh-evolution-core";
5
5
  import { validateEvolutionPlan } from "@lmzhen/dsh-evolution-plan-validator";
6
+ //#region lib/types/redact.js
7
+ /**
8
+ * Review-input redaction. Review/curator subagents are the one place where a
9
+ * cross-session conversation snapshot leaves the owning session's context, so
10
+ * credential-shaped text is masked before it is sent. Redaction is best-effort
11
+ * and conservative: it targets well-known secret shapes and inline
12
+ * assignment patterns, never wholesale content.
13
+ */
14
+ const SECRET_PATTERNS = [
15
+ ["openai-style key", /sk-[A-Za-z0-9_-]{16,}/g],
16
+ ["aws access key", /AKIA[0-9A-Z]{16}/g],
17
+ ["github token", /gh[pousr]_[A-Za-z0-9]{20,}/g],
18
+ ["gitlab token", /glpat-[A-Za-z0-9_-]{16,}/g],
19
+ ["slack token", /xox[baprs]-[A-Za-z0-9-]{10,}/g],
20
+ ["jwt", /eyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}/g],
21
+ ["bearer credential", /Bearer [A-Za-z0-9._~+/=\-]{16,}/g],
22
+ ["inline assignment", /(\b(?:token|api[_-]?key|secret|password|passwd)\b[\s]*[:=][\s]*[\"\x27]?)([A-Z0-9._~+/=\-]{12,})/gi]
23
+ ];
24
+ /**
25
+ * Mask credential-shaped text in a review request.
26
+ * @param text - the assembled review request text.
27
+ * @returns the text with matched secrets replaced by `<redacted>`.
28
+ */
29
+ function redactReviewSecrets(text) {
30
+ let out = text;
31
+ for (const [, pattern] of SECRET_PATTERNS) out = out.replace(pattern, (_match, p1) => p1 === void 0 ? "<redacted>" : `${p1}<redacted>`);
32
+ return out;
33
+ }
34
+ //#endregion
6
35
  //#region lib/types/index.js
7
36
  /**
8
37
  * Background review orchestration: signal gate → one-shot subagent → trusted plan execution.
@@ -24,7 +53,8 @@ const Config = z.object({
24
53
  executionTimeoutMs: z.number().default(3e4),
25
54
  reviewContextMessages: z.number().default(60),
26
55
  reviewMessageChars: z.number().default(2e3),
27
- reviewMaxDepth: z.number().default(0)
56
+ reviewMaxDepth: z.number().default(0),
57
+ reviewProvider: z.string()
28
58
  });
29
59
  function apply(ctx, rawConfig) {
30
60
  if (!verifyPromptBundle(PROMPT_BUNDLE)) throw new Error("dsh-evolution prompt bundle integrity check failed; refusing to schedule review work");
@@ -79,7 +109,9 @@ function apply(ctx, rawConfig) {
79
109
  try {
80
110
  const routingPolicy = ctx.get("evolutionPolicy");
81
111
  const model = kind === "memory" ? routingPolicy?.get().memoryReviewModel ?? "deepseek-v4-flash" : routingPolicy?.get().skillReviewModel ?? "deepseek-v4-pro";
82
- const reviewText = buildReviewRequest(session, kind, signal, config.reviewContextMessages, config.reviewMessageChars);
112
+ const reviewText = redactReviewSecrets(buildReviewRequest(session, kind, signal, config.reviewContextMessages, config.reviewMessageChars));
113
+ const agentOptions = { model };
114
+ if (config.reviewProvider) agentOptions.provider = config.reviewProvider;
83
115
  const run = await subagents.start("spawn", {
84
116
  label: "dsh-evolution-review",
85
117
  prompt: [{
@@ -89,10 +121,7 @@ function apply(ctx, rawConfig) {
89
121
  parent: agent,
90
122
  signal: AbortSignal.timeout(config.reviewTimeoutMs),
91
123
  maxDepth: config.reviewMaxDepth,
92
- agentOptions: {
93
- provider: "deepseek-official",
94
- model
95
- },
124
+ agentOptions,
96
125
  persona: reviewPrompt(kind),
97
126
  toolFilter: { allow: [...config.reviewToolAllow] },
98
127
  outputSchema: {
@@ -18,6 +18,8 @@ export interface Config {
18
18
  reviewContextMessages?: number;
19
19
  reviewMessageChars?: number;
20
20
  reviewMaxDepth?: number;
21
+ /** LLM provider for review subagents. Omit to inherit the deployment default route. */
22
+ reviewProvider?: string;
21
23
  }
22
24
  export declare const Config: z<Config>;
23
25
  export declare function apply(ctx: Context, rawConfig: Config): void;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Review-input redaction. Review/curator subagents are the one place where a
3
+ * cross-session conversation snapshot leaves the owning session's context, so
4
+ * credential-shaped text is masked before it is sent. Redaction is best-effort
5
+ * and conservative: it targets well-known secret shapes and inline
6
+ * assignment patterns, never wholesale content.
7
+ */
8
+ /**
9
+ * Mask credential-shaped text in a review request.
10
+ * @param text - the assembled review request text.
11
+ * @returns the text with matched secrets replaced by `<redacted>`.
12
+ */
13
+ export declare function redactReviewSecrets(text: string): string;
14
+ //# sourceMappingURL=redact.d.ts.map
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.1.0-rc.4",
4
+ "version": "0.1.0-rc.6",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -33,8 +33,8 @@
33
33
  "license": "MIT",
34
34
  "dependencies": {
35
35
  "@deepseek-ai/schemastery": "^3.18.1",
36
- "@lmzhen/dsh-evolution-core": "^0.1.0-rc.4",
37
- "@lmzhen/dsh-evolution-plan-validator": "^0.1.0-rc.4"
36
+ "@lmzhen/dsh-evolution-core": "^0.1.0-rc.6",
37
+ "@lmzhen/dsh-evolution-plan-validator": "^0.1.0-rc.6"
38
38
  },
39
39
  "peerDependencies": {
40
40
  "@deepseek-ai/cordis": "^4.0.1",
@@ -43,7 +43,7 @@
43
43
  "@deepseek-ai/dsh-llm": "^0.1.0-rc.6",
44
44
  "@deepseek-ai/dsh-session": "^0.1.0-rc.6",
45
45
  "@deepseek-ai/dsh-tools": "^0.1.0-rc.6",
46
- "@lmzhen/dsh-evolution-state": "^0.1.0-rc.4"
46
+ "@lmzhen/dsh-evolution-state": "^0.1.0-rc.6"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@deepseek-ai/dsh-agent": "^0.1.0-rc.6",
@@ -52,8 +52,8 @@
52
52
  "@deepseek-ai/dsh-llm": "^0.1.0-rc.6",
53
53
  "@deepseek-ai/dsh-session": "^0.1.0-rc.6",
54
54
  "@deepseek-ai/dsh-tools": "^0.1.0-rc.6",
55
- "@lmzhen/dsh-evolution-core": "^0.1.0-rc.4",
56
- "@lmzhen/dsh-evolution-plan-validator": "^0.1.0-rc.4",
57
- "@lmzhen/dsh-evolution-state": "^0.1.0-rc.4"
55
+ "@lmzhen/dsh-evolution-core": "^0.1.0-rc.6",
56
+ "@lmzhen/dsh-evolution-plan-validator": "^0.1.0-rc.6",
57
+ "@lmzhen/dsh-evolution-state": "^0.1.0-rc.6"
58
58
  }
59
59
  }