dsh-continual-evolve 0.11.0 → 0.12.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.
Files changed (154) hide show
  1. package/README.md +35 -115
  2. package/README.zh.md +26 -93
  3. package/cordis.patch.yml +2 -2
  4. package/lib/index.d.ts +44 -225
  5. package/lib/index.js +30 -239
  6. package/lib/memory-guide.d.ts +13 -14
  7. package/lib/memory-guide.js +32 -21
  8. package/lib/memory-section.d.ts +77 -0
  9. package/lib/memory-section.js +189 -0
  10. package/package.json +2 -17
  11. package/lib/apply.d.ts +0 -22
  12. package/lib/apply.js +0 -157
  13. package/lib/approval.d.ts +0 -73
  14. package/lib/approval.js +0 -127
  15. package/lib/audit-log.d.ts +0 -19
  16. package/lib/audit-log.js +0 -52
  17. package/lib/auto.d.ts +0 -236
  18. package/lib/auto.js +0 -773
  19. package/lib/autocase.d.ts +0 -38
  20. package/lib/autocase.js +0 -76
  21. package/lib/benchmark-command.d.ts +0 -9
  22. package/lib/benchmark-command.js +0 -357
  23. package/lib/benchmark.d.ts +0 -151
  24. package/lib/benchmark.js +0 -250
  25. package/lib/command-util.d.ts +0 -70
  26. package/lib/command-util.js +0 -123
  27. package/lib/command.d.ts +0 -13
  28. package/lib/command.js +0 -134
  29. package/lib/consolidate.d.ts +0 -90
  30. package/lib/consolidate.js +0 -180
  31. package/lib/copy.d.ts +0 -37
  32. package/lib/copy.js +0 -58
  33. package/lib/declines.d.ts +0 -103
  34. package/lib/declines.js +0 -179
  35. package/lib/evaluate.d.ts +0 -74
  36. package/lib/evaluate.js +0 -271
  37. package/lib/evolve-event.d.ts +0 -40
  38. package/lib/evolve-event.js +0 -60
  39. package/lib/extraction-phase.d.ts +0 -132
  40. package/lib/extraction-phase.js +0 -236
  41. package/lib/failures.d.ts +0 -42
  42. package/lib/failures.js +0 -171
  43. package/lib/fate.d.ts +0 -130
  44. package/lib/fate.js +0 -350
  45. package/lib/goal-command.d.ts +0 -7
  46. package/lib/goal-command.js +0 -37
  47. package/lib/goal.d.ts +0 -72
  48. package/lib/goal.js +0 -72
  49. package/lib/inject.d.ts +0 -90
  50. package/lib/inject.js +0 -164
  51. package/lib/injection-caps.d.ts +0 -4
  52. package/lib/injection-caps.js +0 -4
  53. package/lib/injection-directory.d.ts +0 -29
  54. package/lib/injection-directory.js +0 -78
  55. package/lib/injection-rank.d.ts +0 -85
  56. package/lib/injection-rank.js +0 -161
  57. package/lib/listener.d.ts +0 -45
  58. package/lib/listener.js +0 -199
  59. package/lib/llm-text.d.ts +0 -104
  60. package/lib/llm-text.js +0 -140
  61. package/lib/logfile.d.ts +0 -71
  62. package/lib/logfile.js +0 -159
  63. package/lib/maintenance-commands.d.ts +0 -23
  64. package/lib/maintenance-commands.js +0 -136
  65. package/lib/memory-agent.d.ts +0 -93
  66. package/lib/memory-agent.js +0 -300
  67. package/lib/memory-apply.d.ts +0 -44
  68. package/lib/memory-apply.js +0 -202
  69. package/lib/memory-benchmark.d.ts +0 -76
  70. package/lib/memory-benchmark.js +0 -170
  71. package/lib/memory-index.d.ts +0 -114
  72. package/lib/memory-index.js +0 -197
  73. package/lib/memory-manifest.d.ts +0 -16
  74. package/lib/memory-manifest.js +0 -70
  75. package/lib/message-source.d.ts +0 -23
  76. package/lib/message-source.js +0 -12
  77. package/lib/mount-command.d.ts +0 -10
  78. package/lib/mount-command.js +0 -48
  79. package/lib/mount.d.ts +0 -42
  80. package/lib/mount.js +0 -212
  81. package/lib/notify.d.ts +0 -48
  82. package/lib/notify.js +0 -57
  83. package/lib/plan-command.d.ts +0 -12
  84. package/lib/plan-command.js +0 -38
  85. package/lib/plan.d.ts +0 -16
  86. package/lib/plan.js +0 -126
  87. package/lib/planner.d.ts +0 -61
  88. package/lib/planner.js +0 -144
  89. package/lib/pool.d.ts +0 -7
  90. package/lib/pool.js +0 -25
  91. package/lib/prefix-cache.d.ts +0 -79
  92. package/lib/prefix-cache.js +0 -168
  93. package/lib/project.d.ts +0 -28
  94. package/lib/project.js +0 -66
  95. package/lib/projection.d.ts +0 -22
  96. package/lib/projection.js +0 -112
  97. package/lib/promotion.d.ts +0 -94
  98. package/lib/promotion.js +0 -171
  99. package/lib/recall.d.ts +0 -85
  100. package/lib/recall.js +0 -142
  101. package/lib/record-language.d.ts +0 -85
  102. package/lib/record-language.js +0 -152
  103. package/lib/render.d.ts +0 -13
  104. package/lib/render.js +0 -80
  105. package/lib/review-scheduler.d.ts +0 -38
  106. package/lib/review-scheduler.js +0 -183
  107. package/lib/review.d.ts +0 -60
  108. package/lib/review.js +0 -145
  109. package/lib/rollback.d.ts +0 -9
  110. package/lib/rollback.js +0 -68
  111. package/lib/rubric.d.ts +0 -29
  112. package/lib/rubric.js +0 -119
  113. package/lib/runtime-commands.d.ts +0 -14
  114. package/lib/runtime-commands.js +0 -115
  115. package/lib/runtime.d.ts +0 -24
  116. package/lib/runtime.js +0 -87
  117. package/lib/score.d.ts +0 -64
  118. package/lib/score.js +0 -191
  119. package/lib/search.d.ts +0 -83
  120. package/lib/search.js +0 -136
  121. package/lib/service.d.ts +0 -63
  122. package/lib/service.js +0 -253
  123. package/lib/skill-render.d.ts +0 -23
  124. package/lib/skill-render.js +0 -69
  125. package/lib/skill.d.ts +0 -15
  126. package/lib/skill.js +0 -80
  127. package/lib/skillquality.d.ts +0 -85
  128. package/lib/skillquality.js +0 -320
  129. package/lib/source.d.ts +0 -30
  130. package/lib/source.js +0 -43
  131. package/lib/state.d.ts +0 -26
  132. package/lib/state.js +0 -151
  133. package/lib/store.d.ts +0 -61
  134. package/lib/store.js +0 -164
  135. package/lib/token-usage.d.ts +0 -68
  136. package/lib/token-usage.js +0 -211
  137. package/lib/tool.d.ts +0 -34
  138. package/lib/tool.js +0 -320
  139. package/lib/turn-snapshot.d.ts +0 -78
  140. package/lib/turn-snapshot.js +0 -252
  141. package/lib/types.d.ts +0 -218
  142. package/lib/types.js +0 -133
  143. package/lib/usage.d.ts +0 -36
  144. package/lib/usage.js +0 -98
  145. package/lib/validate.d.ts +0 -28
  146. package/lib/validate.js +0 -181
  147. package/lib/wrapup-candidates.d.ts +0 -127
  148. package/lib/wrapup-candidates.js +0 -161
  149. package/lib/wrapup-command.d.ts +0 -10
  150. package/lib/wrapup-command.js +0 -243
  151. package/lib/wrapup-proposals.d.ts +0 -101
  152. package/lib/wrapup-proposals.js +0 -281
  153. package/lib/wrapup.d.ts +0 -56
  154. package/lib/wrapup.js +0 -105
package/lib/approval.d.ts DELETED
@@ -1,73 +0,0 @@
1
- /**
2
- * Human approval gate for persistent-scope evolution edits. Project and
3
- * global edits require an explicit human "批准" before they are applied;
4
- * rollbacks (which restore prior recorded state) do not. The engine itself
5
- * stays a pure library — this is a policy at the boundary.
6
- */
7
- import type { Context } from "@deepseek-ai/cordis";
8
- import type { Agent } from "@deepseek-ai/dsh-agent";
9
- import { type RecordLanguagePreference } from "./record-language.js";
10
- export { type ScopeApprovalDecision } from "./types.js";
11
- import type { ScopeApprovalDecision } from "./types.js";
12
- /** Labels the approval dialog offers for each decision (parser contract). */
13
- export declare const APPROVE_LABELS: readonly ["批准", "Approve"];
14
- export declare const DECLINE_LABELS: readonly ["拒绝", "Decline"];
15
- export interface QuestionService {
16
- ask(request: {
17
- questions: {
18
- id: string;
19
- question: string;
20
- options?: {
21
- label: string;
22
- description?: string;
23
- }[];
24
- }[];
25
- agent?: Agent;
26
- signal?: AbortSignal;
27
- }): Promise<{
28
- answers?: {
29
- id: string;
30
- selected?: string[];
31
- custom?: string;
32
- }[];
33
- }>;
34
- }
35
- /**
36
- * Lazily resolve the userQuestions service from the context.
37
- * Returns undefined when the service is not loaded — callers decide
38
- * whether that is an error or a fallback.
39
- */
40
- export declare function questionServiceOf(ctx: Context): QuestionService | undefined;
41
- /**
42
- * Ask once for a persistent-scope edit. Only a unique, explicit approval
43
- * choice is accepted. A missing/ambiguous/unknown answer throws so callers
44
- * never interpret a lost or malformed dialog as a durable rejection.
45
- *
46
- * Copy follows the headline → details → impact shape in the resolved dialog
47
- * language; labels stay literal per language for parser compatibility.
48
- *
49
- * Language resolution runs the full record-language chain — explicit config,
50
- * then the durable client preference, then the session's own recent user text
51
- * — because an approval dialog raised from a tool call DOES have a session
52
- * behind it. Stopping at the durable tier gave a Chinese-speaking user English
53
- * dialogs whenever the stored preference was unset (2026-10-01).
54
- *
55
- * @param ctx Cordis context carrying the userQuestions service.
56
- * @param agent Agent prompting the question, if any.
57
- * @param signal Abort signal for the question, if any.
58
- * @param scope Target persistent scope.
59
- * @param what Edit summary; truncated to 300 chars with "…" when longer.
60
- * @param configured Plugin `recordLanguage` preference; `auto`/absent defers
61
- * to the durable preference and the session's user text.
62
- * @returns "approved" when the user picks the approval label, otherwise "declined".
63
- * @throws When the service is missing or the answer is not unique/explicit.
64
- */
65
- export declare function requestScopeApproval(ctx: Context, agent: Agent | undefined, signal: AbortSignal | undefined, scope: "project" | "global", what: string, configured?: RecordLanguagePreference): Promise<ScopeApprovalDecision>;
66
- /**
67
- * Ask the user to approve a global edit. Throws when the service is missing,
68
- * the user declines, or the question cannot be answered.
69
- *
70
- * @param configured Plugin `recordLanguage` preference (see {@link requestScopeApproval}).
71
- */
72
- export declare function requireGlobalApproval(ctx: Context, agent: Agent | undefined, signal: AbortSignal | undefined, what: string, configured?: RecordLanguagePreference): Promise<void>;
73
- //# sourceMappingURL=approval.d.ts.map
package/lib/approval.js DELETED
@@ -1,127 +0,0 @@
1
- import { approvalCopy } from "./copy.js";
2
- import { normalizeRecordLanguage, resolveRecordLanguage } from "./record-language.js";
3
- import { recentUserText } from "./inject.js";
4
- /** Labels the approval dialog offers for each decision (parser contract). */
5
- export const APPROVE_LABELS = ["批准", "Approve"];
6
- export const DECLINE_LABELS = ["拒绝", "Decline"];
7
- /**
8
- * Typed ("Other") answers accepted as an explicit decision once normalized.
9
- * Deliberately exact: a substring rule would read "不批准" as approval, and a
10
- * misread decision is far worse than asking the human to click the button.
11
- */
12
- const TYPED_APPROVALS = new Set(["批准", "approve"]);
13
- const TYPED_DECLINES = new Set(["拒绝", "decline"]);
14
- /** Trim case/quotes/trailing punctuation and a trailing 吧/了 from a typed answer. */
15
- function normalizeTypedAnswer(text) {
16
- return text
17
- .trim()
18
- .toLowerCase()
19
- .replace(/^[\s"'“”「」]+/, "")
20
- .replace(/[\s"'“”「」。!!,,、]+$/, "")
21
- .replace(/[吧了]$/, "");
22
- }
23
- /**
24
- * Read a free-text answer as a decision, or `undefined` when it matches no
25
- * label exactly. Never guesses.
26
- */
27
- function typedDecision(custom) {
28
- if (typeof custom !== "string")
29
- return undefined;
30
- const normalized = normalizeTypedAnswer(custom);
31
- if (TYPED_APPROVALS.has(normalized))
32
- return "approved";
33
- if (TYPED_DECLINES.has(normalized))
34
- return "declined";
35
- return undefined;
36
- }
37
- /**
38
- * Lazily resolve the userQuestions service from the context.
39
- * Returns undefined when the service is not loaded — callers decide
40
- * whether that is an error or a fallback.
41
- */
42
- export function questionServiceOf(ctx) {
43
- return ctx.userQuestions;
44
- }
45
- /**
46
- * Ask once for a persistent-scope edit. Only a unique, explicit approval
47
- * choice is accepted. A missing/ambiguous/unknown answer throws so callers
48
- * never interpret a lost or malformed dialog as a durable rejection.
49
- *
50
- * Copy follows the headline → details → impact shape in the resolved dialog
51
- * language; labels stay literal per language for parser compatibility.
52
- *
53
- * Language resolution runs the full record-language chain — explicit config,
54
- * then the durable client preference, then the session's own recent user text
55
- * — because an approval dialog raised from a tool call DOES have a session
56
- * behind it. Stopping at the durable tier gave a Chinese-speaking user English
57
- * dialogs whenever the stored preference was unset (2026-10-01).
58
- *
59
- * @param ctx Cordis context carrying the userQuestions service.
60
- * @param agent Agent prompting the question, if any.
61
- * @param signal Abort signal for the question, if any.
62
- * @param scope Target persistent scope.
63
- * @param what Edit summary; truncated to 300 chars with "…" when longer.
64
- * @param configured Plugin `recordLanguage` preference; `auto`/absent defers
65
- * to the durable preference and the session's user text.
66
- * @returns "approved" when the user picks the approval label, otherwise "declined".
67
- * @throws When the service is missing or the answer is not unique/explicit.
68
- */
69
- export async function requestScopeApproval(ctx, agent, signal, scope, what, configured) {
70
- const userQuestions = questionServiceOf(ctx);
71
- if (!userQuestions) {
72
- throw new Error("global evolution edits require the userQuestions service (load @deepseek-ai/dsh-user-questions)");
73
- }
74
- const lang = normalizeRecordLanguage(configured) ??
75
- resolveRecordLanguage({ ctx, trajectoryText: recentUserText(agent) });
76
- const copy = approvalCopy(scope, what, lang);
77
- const answer = await userQuestions.ask({
78
- questions: [
79
- {
80
- id: "approve-global-evolve",
81
- question: copy.question,
82
- options: copy.options,
83
- },
84
- ],
85
- ...(agent ? { agent } : {}),
86
- ...(signal ? { signal } : {}),
87
- });
88
- const matching = answer.answers?.filter((entry) => entry.id === "approve-global-evolve") ?? [];
89
- if (matching.length !== 1 || !Array.isArray(matching[0]?.selected)) {
90
- throw new Error("evolution approval returned no unique explicit decision");
91
- }
92
- const entry = matching[0];
93
- const selected = [...new Set(entry.selected)];
94
- if (selected.length === 0) {
95
- // A typed "Other" answer counts only when it matches a dialog label
96
- // exactly; anything fuzzier stays an error, so a lost or ambiguous
97
- // reply is never recorded as a durable rejection.
98
- const typed = typedDecision(entry.custom);
99
- if (typed !== undefined) {
100
- return typed;
101
- }
102
- throw new Error(`evolution approval needs one clicked option (${APPROVE_LABELS.join("/")} or ${DECLINE_LABELS.join("/")}) — a typed reply cannot serve as a decision`);
103
- }
104
- if (selected.length !== 1) {
105
- throw new Error(`evolution approval returned an invalid decision: ${JSON.stringify(selected)}`);
106
- }
107
- const label = selected[0];
108
- if (APPROVE_LABELS.includes(label)) {
109
- return "approved";
110
- }
111
- if (DECLINE_LABELS.includes(label)) {
112
- return "declined";
113
- }
114
- throw new Error(`evolution approval returned an unknown decision label: ${JSON.stringify(label)}`);
115
- }
116
- /**
117
- * Ask the user to approve a global edit. Throws when the service is missing,
118
- * the user declines, or the question cannot be answered.
119
- *
120
- * @param configured Plugin `recordLanguage` preference (see {@link requestScopeApproval}).
121
- */
122
- export async function requireGlobalApproval(ctx, agent, signal, what, configured) {
123
- if ((await requestScopeApproval(ctx, agent, signal, "global", what, configured)) !== "approved") {
124
- throw new Error("global evolution edit rejected by the user");
125
- }
126
- }
127
- //# sourceMappingURL=approval.js.map
@@ -1,19 +0,0 @@
1
- export interface ReviewAuditRow {
2
- sessionId: string;
3
- reason: string;
4
- turnsSinceLastReview: number;
5
- outcome: string;
6
- rationale?: string;
7
- [key: string]: unknown;
8
- }
9
- /** Resolve the shared audit trail path under `<baseDir>/evolve/`. */
10
- export declare function reviewsAuditPath(baseDir: string): string;
11
- /** Append one audit row and bound the trail at write time. Never throws. */
12
- export declare function appendReviewRecord(baseDir: string, entry: ReviewAuditRow, retain: number | undefined, onError?: (cause: unknown) => void): void;
13
- /**
14
- * Boot-time diagnostic: the armed marker proves the listener was registered
15
- * even when its runtime default is off, distinguishing "not registered"
16
- * from "off". Never throws.
17
- */
18
- export declare function writeArmedMarker(baseDir: string, rationale: string, onError?: (cause: unknown) => void): void;
19
- //# sourceMappingURL=audit-log.d.ts.map
package/lib/audit-log.js DELETED
@@ -1,52 +0,0 @@
1
- /**
2
- * The shared `reviews.jsonl` audit trail: the only writer for extraction
3
- * decisions, mechanical skips, and the boot armed marker. Writes are
4
- * contained — a broken ledger must never break the extraction path that
5
- * already made its decision.
6
- */
7
- import { appendFileSync, mkdirSync } from "node:fs";
8
- import { join } from "node:path";
9
- import { DEFAULT_REVIEWS_RETAIN, pruneJsonlFile } from "./store.js";
10
- /** Resolve the shared audit trail path under `<baseDir>/evolve/`. */
11
- export function reviewsAuditPath(baseDir) {
12
- return join(baseDir, "evolve", "reviews.jsonl");
13
- }
14
- /** Append one audit row and bound the trail at write time. Never throws. */
15
- export function appendReviewRecord(baseDir, entry, retain, onError) {
16
- try {
17
- mkdirSync(join(baseDir, "evolve"), { recursive: true });
18
- appendFileSync(reviewsAuditPath(baseDir), `${JSON.stringify({ ...entry, timestamp: new Date().toISOString() })}\n`, "utf8");
19
- }
20
- catch (cause) {
21
- onError?.(cause);
22
- return;
23
- }
24
- try {
25
- pruneJsonlFile(reviewsAuditPath(baseDir), retain ?? DEFAULT_REVIEWS_RETAIN);
26
- }
27
- catch {
28
- // ignored — the next record retries
29
- }
30
- }
31
- /**
32
- * Boot-time diagnostic: the armed marker proves the listener was registered
33
- * even when its runtime default is off, distinguishing "not registered"
34
- * from "off". Never throws.
35
- */
36
- export function writeArmedMarker(baseDir, rationale, onError) {
37
- try {
38
- mkdirSync(join(baseDir, "evolve"), { recursive: true });
39
- appendFileSync(reviewsAuditPath(baseDir), `${JSON.stringify({
40
- timestamp: new Date().toISOString(),
41
- sessionId: "boot",
42
- reason: "boot",
43
- turnsSinceLastReview: 0,
44
- outcome: "armed",
45
- rationale,
46
- })}\n`, "utf8");
47
- }
48
- catch (cause) {
49
- onError?.(cause);
50
- }
51
- }
52
- //# sourceMappingURL=audit-log.js.map
package/lib/auto.d.ts DELETED
@@ -1,236 +0,0 @@
1
- import type { ScopeApprovalDecision } from "./approval.js";
2
- import type { Context } from "@deepseek-ai/cordis";
3
- import type { Agent } from "@deepseek-ai/dsh-agent";
4
- import type { HarnessState, RefinementEdit, RefinementProposal } from "./types.js";
5
- import type { EvolutionEngine } from "./service.js";
6
- import { type AutoRefineReason } from "./review.js";
7
- import { type ReviewScheduler } from "./review-scheduler.js";
8
- import { type TurnSnapshot } from "./turn-snapshot.js";
9
- import type { PromotionPolicy } from "./promotion.js";
10
- import type { PlannerPrefixCacheMode } from "./prefix-cache.js";
11
- import { type RecordLanguagePreference } from "./record-language.js";
12
- import type { RecordLanguage } from "./record-language.js";
13
- export interface AutoReviewConfig {
14
- /** Legacy fate cadence; successful turns are no longer gated by this value. */
15
- intervalTurns: number;
16
- /** Initial runtime state when no runtime.json exists. */
17
- enabledByDefault?: boolean;
18
- /** ZCode-style minimum lexical words in one direct user text part. */
19
- memoryMinUserWords?: number;
20
- /**
21
- * Run only the dedicated memory extraction phase. The general review,
22
- * planner, prompt/skill writes, and local-fate phases are never entered.
23
- */
24
- memoryOnly?: boolean;
25
- maxInputChars: number;
26
- budgetTokens: number;
27
- /** Queue a visible follow-up notice after an approved, applied gate run. */
28
- notifyOnAutoReview: boolean;
29
- /**
30
- * Local-fate dimension (#11 P2): the gate audits the session's local
31
- * entries on its own cadence and proposes promote/archive (consulted
32
- * first — never written silently). Off disables the whole dimension.
33
- */
34
- localFate: boolean;
35
- /**
36
- * Minimum turns between local-fate assessments on the successful-turn path
37
- * (compaction is unconditional). Independent of snapshot review cadence so
38
- * eligible turns do not pay an assessment every round.
39
- */
40
- fateIntervalTurns: number;
41
- /**
42
- * Gap C1: optional model override for the review gate (cheaper model).
43
- * Format: "provider/model" or just "model" (same provider as the agent).
44
- * When absent, the review gate uses the agent's own provider/model.
45
- */
46
- reviewModel?: string;
47
- /** Dedicated memory-agent writes to project/global require the normal human approval boundary. */
48
- requireGlobalApproval?: boolean;
49
- /**
50
- * Authoring language for this run's records. Absent/`auto` resolves per
51
- * call through the record-language chain (durable client preference,
52
- * then trajectory detection, then `en`); `zh`/`en` pin it.
53
- */
54
- recordLanguage?: RecordLanguagePreference;
55
- /**
56
- * Prefix-cache routing for the gate input (see reviewAutoRefine).
57
- * Absent mode → auto-detect; absent budget → the default prefix budget.
58
- */
59
- prefixCacheMode?: PlannerPrefixCacheMode;
60
- prefixMaxChars?: number;
61
- /**
62
- * Goal-blocked trigger (D3): after this many CONSECUTIVE gate runs that
63
- * observe the session goal in phase "blocked", run one local-fate
64
- * assessment (the same audit → classify → consult → apply pipeline as the
65
- * gate's normal fate dimension) so the blocked encounter is distilled
66
- * before the session moves on. 0 disables. The streak resets on any
67
- * non-blocked run and after each triggered assessment; a declined
68
- * proposal then follows the normal fate cooldown.
69
- */
70
- goalBlockedWrapupTurns: number;
71
- /**
72
- * Promotion policy (2026-08-22): mechanical promote guards applied by the
73
- * local-fate dimension before anything reaches the global store.
74
- */
75
- promotionPolicy: PromotionPolicy;
76
- /**
77
- * P1 auto-case capture: a gate run whose planned edits all failed to get
78
- * consent captures the attempt as a draft regression scaffold in the
79
- * auto-regression container benchmark (never in a user benchmark).
80
- */
81
- autoCase: boolean;
82
- /** Resolved rubric key for the capture's encrypted scaffold rubric. */
83
- rubricKey?: Buffer;
84
- /**
85
- * Storage hygiene (#20): tail lines kept in the shared reviews.jsonl
86
- * audit trail. Absent → the store default (readers need a recent
87
- * window, not the full past).
88
- */
89
- reviewsRetain?: number;
90
- /**
91
- * Session-close bounded drain (P1): how long a disposed session's
92
- * in-flight extraction may settle before its owner signal aborts.
93
- * Absent → 15s; 0 restores the legacy immediate abort.
94
- */
95
- sessionCloseDrainMs?: number;
96
- }
97
- export interface GateState {
98
- turns: number;
99
- /** Latest successful turn boundary seen by the listener. */
100
- completedTurn: number;
101
- /** Latest turn whose snapshot acquisition was reserved. */
102
- lastSnapshotTurn: number;
103
- /** Latest successful/no-op memory boundary, independent of later review/fate completion. */
104
- memoryCheckpoint?: string;
105
- /** Per-boundary/scope approval decisions retained until the memory phase settles. */
106
- memoryDecisions: Record<string, ScopeApprovalDecision>;
107
- lastReviewAt: number;
108
- running: boolean;
109
- /**
110
- * Per-candidate turn at which the user last rejected a skill proposal;
111
- * consulted skill proposals are not offered again within the cooldown
112
- * window (skills are governed resources — no nagging).
113
- */
114
- skillRejects: Map<string, number>;
115
- /** Turn at which the local-fate dimension last assessed (cadence). */
116
- lastFateAt: number;
117
- /**
118
- * Per-candidate-set turn at which the user last declined a local-fate
119
- * proposal; declined sets are not offered again within the cooldown
120
- * window (the consultSkillEdits pattern — no nagging).
121
- */
122
- fateRejects: Map<string, number>;
123
- /**
124
- * Consecutive gate runs that observed the goal phase "blocked" (D3).
125
- * Reset to 0 by any non-blocked run and after a triggered assessment —
126
- * see runGoalBlockedFate.
127
- */
128
- goalBlockStreak: number;
129
- }
130
- /** Turns a rejected skill candidate stays silent before being offered again. */
131
- export declare const SKILL_CONSULT_COOLDOWN_TURNS = 10;
132
- /** Default session-close drain budget: an in-flight extraction gets 15s to settle. */
133
- export declare const SESSION_CLOSE_DRAIN_MS_DEFAULT = 15000;
134
- /**
135
- * Resolve the session-close drain budget: absent/invalid → default, 0 →
136
- * immediate abort (legacy). Negative or non-finite values fail back to the
137
- * default rather than silently disabling the drain.
138
- */
139
- export declare function resolveSessionCloseDrainMs(raw?: number): number;
140
- /**
141
- * Bounded session-close drain for one scheduler: wait for in-flight work up
142
- * to drainMs, then abort the owner signal and drop pending captures. Never
143
- * rejects — disposal must not hang the host on a stuck model call, and the
144
- * abort below is idempotent when the drain already settled.
145
- */
146
- export declare function drainSchedulerOnDispose(scheduler: Pick<ReviewScheduler<TurnSnapshot>, "drain" | "shutdown">, drainMs: number): Promise<void>;
147
- export interface ReviewRecord {
148
- timestamp: string;
149
- sessionId: string;
150
- reason: AutoRefineReason;
151
- turnsSinceLastReview: number;
152
- outcome: "approved" | "declined" | "failed" | "assessed" | "deferred" | "skipped" | "armed" | "applied" | "noop";
153
- rationale?: string;
154
- refinementId?: string;
155
- /** P1 extraction stats (§6.7): wall time of the memory phase. */
156
- durationMs?: number;
157
- /** Extractor loop turns / manifest searches behind this row. */
158
- memoryTurns?: number;
159
- memorySearches?: number;
160
- /** Applied edit count carried by an applied row. */
161
- appliedEdits?: number;
162
- }
163
- export declare function registerAutoReview(ctx: Context, engine: EvolutionEngine, config: AutoReviewConfig): void;
164
- /**
165
- * Gap C1: parse a "provider/model" or "model" string into its components.
166
- * Returns undefined when the input is empty (no override). A bare model name
167
- * falls back to the agent's provider, then "deepseek".
168
- * Exported for unit testing (the advanceGateState precedent); production
169
- * resolves it inside runReviewPhase.
170
- */
171
- export declare function parseReviewModel(reviewModel: string | undefined, fallbackProvider: string | undefined): {
172
- provider: string;
173
- model: string;
174
- } | undefined;
175
- /**
176
- * The state view the gate and planner judge: the session's local entries
177
- * merged with the project and global stores, each entry carrying its real
178
- * scope. Without the global half the gate cannot see that a topic is already
179
- * covered cross-session and happily re-sediments a local duplicate of it.
180
- *
181
- * The merged view is read-only context — applying still targets the raw
182
- * local state (baseline checks compare local entries only).
183
- */
184
- export declare function loadGateHarnessView(engine: EvolutionEngine, sessionId: string, opts?: {
185
- projectKey?: string;
186
- }): HarnessState;
187
- /**
188
- * D3 (goal blocked → wrap-up coupling, reverse direction): count consecutive
189
- * gate runs whose goal is in phase "blocked"; when the streak reaches
190
- * `goalBlockedWrapupTurns`, run ONE local-fate assessment (same pipeline as
191
- * the normal fate dimension — audit, classify, consult, apply deterministically).
192
- * The streak resets on any non-blocked run and after a triggered assessment;
193
- * a declined proposal is then protected by the normal fate cooldown, so a
194
- * blocked session can never be nagged into another dialog.
195
- *
196
- * Exported for unit testing (the advanceGateState precedent); production runs
197
- * it from runGate.
198
- */
199
- export declare function runGoalBlockedFate(ctx: Context, engine: EvolutionEngine, agent: Agent, config: AutoReviewConfig, state: GateState, _reason: AutoRefineReason, record: (entry: Omit<ReviewRecord, "timestamp">) => void): Promise<void>;
200
- /**
201
- * Dedicated ZCode-style memory phase. It shares the scheduler snapshot and
202
- * snapshot with the general review, but owns its request loop, manifest and
203
- * memory-only tool policy. Its phase-specific checkpoint advances after a
204
- * successful/no-op memory outcome; later review/fate failures do not replay
205
- * old memory decisions, while memory failures leave the boundary retryable.
206
- */
207
- export declare function runMemoryExtractionPhase(ctx: Context, engine: EvolutionEngine, agent: Agent, config: AutoReviewConfig, state: GateState, snapshot: TurnSnapshot, record: (entry: Omit<ReviewRecord, "timestamp">) => void, signal?: AbortSignal): Promise<void>;
208
- /** True when the general planner returned only edits owned by the memory phase. */
209
- export declare function isDedicatedMemoryOnlyProposal(proposal: RefinementProposal): boolean;
210
- /**
211
- * Remove memory edits from the general auto-review planner. The dedicated
212
- * memory phase owns this responsibility and has already run against the same
213
- * snapshot; accepting a second memory proposal would reintroduce duplicates.
214
- */
215
- export declare function stripDedicatedMemoryEdits(proposal: RefinementProposal): RefinementProposal;
216
- /**
217
- * Split a proposal into skill edits and everything else. Skill edits are the
218
- * governed part: they need explicit user consent before the gate applies
219
- * them, while the remaining edits flow through the normal auto path.
220
- */
221
- export declare function splitSkillEdits(proposal: RefinementProposal): {
222
- skillEdits: RefinementEdit[];
223
- otherEdits: RefinementEdit[];
224
- };
225
- /**
226
- * Ask the user whether to solidify proposed skill edits (guidance or
227
- * executable) into the harness. Returns true when every skill edit is
228
- * consented. Never writes a skill silently:
229
- * - no question service available → false (conservative);
230
- * - the same candidate was rejected within the cooldown window → false
231
- * without asking again (no nagging);
232
- * - the user declines → false and the rejection is recorded for cooldown;
233
- * - the question call fails/aborts → false (conservative).
234
- */
235
- export declare function consultSkillEdits(ctx: Context, agent: Agent, skillEdits: RefinementEdit[], gate: GateState, language?: RecordLanguage): Promise<boolean>;
236
- //# sourceMappingURL=auto.d.ts.map