dsh-continual-evolve 0.11.0 → 0.12.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.
- package/README.md +42 -115
- package/README.zh.md +33 -93
- package/client/client.js +253 -0
- package/cordis.patch.yml +2 -2
- package/lib/card-routes.d.ts +32 -0
- package/lib/card-routes.js +92 -0
- package/lib/index.d.ts +65 -217
- package/lib/index.js +74 -234
- package/lib/known-workspaces.d.ts +22 -0
- package/lib/known-workspaces.js +42 -0
- package/lib/memory-guide.d.ts +13 -14
- package/lib/memory-guide.js +34 -21
- package/lib/memory-section.d.ts +77 -0
- package/lib/memory-section.js +189 -0
- package/lib/memory-snapshot.d.ts +54 -0
- package/lib/memory-snapshot.js +125 -0
- package/package.json +8 -17
- package/lib/apply.d.ts +0 -22
- package/lib/apply.js +0 -157
- package/lib/approval.d.ts +0 -73
- package/lib/approval.js +0 -127
- package/lib/audit-log.d.ts +0 -19
- package/lib/audit-log.js +0 -52
- package/lib/auto.d.ts +0 -236
- package/lib/auto.js +0 -773
- package/lib/autocase.d.ts +0 -38
- package/lib/autocase.js +0 -76
- package/lib/benchmark-command.d.ts +0 -9
- package/lib/benchmark-command.js +0 -357
- package/lib/benchmark.d.ts +0 -151
- package/lib/benchmark.js +0 -250
- package/lib/command-util.d.ts +0 -70
- package/lib/command-util.js +0 -123
- package/lib/command.d.ts +0 -13
- package/lib/command.js +0 -134
- package/lib/consolidate.d.ts +0 -90
- package/lib/consolidate.js +0 -180
- package/lib/copy.d.ts +0 -37
- package/lib/copy.js +0 -58
- package/lib/declines.d.ts +0 -103
- package/lib/declines.js +0 -179
- package/lib/evaluate.d.ts +0 -74
- package/lib/evaluate.js +0 -271
- package/lib/evolve-event.d.ts +0 -40
- package/lib/evolve-event.js +0 -60
- package/lib/extraction-phase.d.ts +0 -132
- package/lib/extraction-phase.js +0 -236
- package/lib/failures.d.ts +0 -42
- package/lib/failures.js +0 -171
- package/lib/fate.d.ts +0 -130
- package/lib/fate.js +0 -350
- package/lib/goal-command.d.ts +0 -7
- package/lib/goal-command.js +0 -37
- package/lib/goal.d.ts +0 -72
- package/lib/goal.js +0 -72
- package/lib/inject.d.ts +0 -90
- package/lib/inject.js +0 -164
- package/lib/injection-caps.d.ts +0 -4
- package/lib/injection-caps.js +0 -4
- package/lib/injection-directory.d.ts +0 -29
- package/lib/injection-directory.js +0 -78
- package/lib/injection-rank.d.ts +0 -85
- package/lib/injection-rank.js +0 -161
- package/lib/listener.d.ts +0 -45
- package/lib/listener.js +0 -199
- package/lib/llm-text.d.ts +0 -104
- package/lib/llm-text.js +0 -140
- package/lib/logfile.d.ts +0 -71
- package/lib/logfile.js +0 -159
- package/lib/maintenance-commands.d.ts +0 -23
- package/lib/maintenance-commands.js +0 -136
- package/lib/memory-agent.d.ts +0 -93
- package/lib/memory-agent.js +0 -300
- package/lib/memory-apply.d.ts +0 -44
- package/lib/memory-apply.js +0 -202
- package/lib/memory-benchmark.d.ts +0 -76
- package/lib/memory-benchmark.js +0 -170
- package/lib/memory-index.d.ts +0 -114
- package/lib/memory-index.js +0 -197
- package/lib/memory-manifest.d.ts +0 -16
- package/lib/memory-manifest.js +0 -70
- package/lib/message-source.d.ts +0 -23
- package/lib/message-source.js +0 -12
- package/lib/mount-command.d.ts +0 -10
- package/lib/mount-command.js +0 -48
- package/lib/mount.d.ts +0 -42
- package/lib/mount.js +0 -212
- package/lib/notify.d.ts +0 -48
- package/lib/notify.js +0 -57
- package/lib/plan-command.d.ts +0 -12
- package/lib/plan-command.js +0 -38
- package/lib/plan.d.ts +0 -16
- package/lib/plan.js +0 -126
- package/lib/planner.d.ts +0 -61
- package/lib/planner.js +0 -144
- package/lib/pool.d.ts +0 -7
- package/lib/pool.js +0 -25
- package/lib/prefix-cache.d.ts +0 -79
- package/lib/prefix-cache.js +0 -168
- package/lib/project.d.ts +0 -28
- package/lib/project.js +0 -66
- package/lib/projection.d.ts +0 -22
- package/lib/projection.js +0 -112
- package/lib/promotion.d.ts +0 -94
- package/lib/promotion.js +0 -171
- package/lib/recall.d.ts +0 -85
- package/lib/recall.js +0 -142
- package/lib/record-language.d.ts +0 -85
- package/lib/record-language.js +0 -152
- package/lib/render.d.ts +0 -13
- package/lib/render.js +0 -80
- package/lib/review-scheduler.d.ts +0 -38
- package/lib/review-scheduler.js +0 -183
- package/lib/review.d.ts +0 -60
- package/lib/review.js +0 -145
- package/lib/rollback.d.ts +0 -9
- package/lib/rollback.js +0 -68
- package/lib/rubric.d.ts +0 -29
- package/lib/rubric.js +0 -119
- package/lib/runtime-commands.d.ts +0 -14
- package/lib/runtime-commands.js +0 -115
- package/lib/runtime.d.ts +0 -24
- package/lib/runtime.js +0 -87
- package/lib/score.d.ts +0 -64
- package/lib/score.js +0 -191
- package/lib/search.d.ts +0 -83
- package/lib/search.js +0 -136
- package/lib/service.d.ts +0 -63
- package/lib/service.js +0 -253
- package/lib/skill-render.d.ts +0 -23
- package/lib/skill-render.js +0 -69
- package/lib/skill.d.ts +0 -15
- package/lib/skill.js +0 -80
- package/lib/skillquality.d.ts +0 -85
- package/lib/skillquality.js +0 -320
- package/lib/source.d.ts +0 -30
- package/lib/source.js +0 -43
- package/lib/state.d.ts +0 -26
- package/lib/state.js +0 -151
- package/lib/store.d.ts +0 -61
- package/lib/store.js +0 -164
- package/lib/token-usage.d.ts +0 -68
- package/lib/token-usage.js +0 -211
- package/lib/tool.d.ts +0 -34
- package/lib/tool.js +0 -320
- package/lib/turn-snapshot.d.ts +0 -78
- package/lib/turn-snapshot.js +0 -252
- package/lib/types.d.ts +0 -218
- package/lib/types.js +0 -133
- package/lib/usage.d.ts +0 -36
- package/lib/usage.js +0 -98
- package/lib/validate.d.ts +0 -28
- package/lib/validate.js +0 -181
- package/lib/wrapup-candidates.d.ts +0 -127
- package/lib/wrapup-candidates.js +0 -161
- package/lib/wrapup-command.d.ts +0 -10
- package/lib/wrapup-command.js +0 -243
- package/lib/wrapup-proposals.d.ts +0 -101
- package/lib/wrapup-proposals.js +0 -281
- package/lib/wrapup.d.ts +0 -56
- package/lib/wrapup.js +0 -105
package/lib/types.d.ts
DELETED
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
/** What a harness entry can be. */
|
|
2
|
-
export type RefinementKind = "prompt" | "memory" | "skill" | "subagent";
|
|
3
|
-
/**
|
|
4
|
-
* Skill-entry form: `executable` skills carry a python reference contract
|
|
5
|
-
* and can be hot-mounted as tools; `guidance` skills are SKILL.md documents
|
|
6
|
-
* (no python reference) that materialize as discoverable skills for the
|
|
7
|
-
* `skill` tool — the form for recurring multi-step workflows. Absent means
|
|
8
|
-
* `executable` (backwards compatible with pre-guidance stores).
|
|
9
|
-
*/
|
|
10
|
-
export type SkillKind = "executable" | "guidance";
|
|
11
|
-
/** How an entry changes. */
|
|
12
|
-
export type RefinementAction = "create" | "update" | "delete" | "archive";
|
|
13
|
-
/** Where an entry lives: session staging, one project, or cross-project. */
|
|
14
|
-
export type HarnessScope = "local" | "project" | "global";
|
|
15
|
-
/**
|
|
16
|
-
* Memory-entry shape discipline (one fact per entry, typed like ZCode's
|
|
17
|
-
* memory frontmatter): every `memory` create must stamp one of these in
|
|
18
|
-
* `metadata[MEMORY_TYPE_KEY]` — the recall hook the directory shows.
|
|
19
|
-
*/
|
|
20
|
-
export declare const MEMORY_TYPE_KEY = "memoryType";
|
|
21
|
-
/** Closed memory-type set: user | feedback | project | reference. */
|
|
22
|
-
export declare const MEMORY_TYPES: readonly ["user", "feedback", "project", "reference"];
|
|
23
|
-
/** One of {@link MEMORY_TYPES}. */
|
|
24
|
-
export type MemoryRecallType = (typeof MEMORY_TYPES)[number];
|
|
25
|
-
/** True when the value is a closed-set memory type. */
|
|
26
|
-
export declare function isMemoryType(value: unknown): value is MemoryRecallType;
|
|
27
|
-
/**
|
|
28
|
-
* Metadata key recording which session an entry's content was distilled from
|
|
29
|
-
* (trajectory citation; see {@link EntrySource}).
|
|
30
|
-
*/
|
|
31
|
-
export declare const SOURCE_SESSION_KEY = "sourceSession";
|
|
32
|
-
/**
|
|
33
|
-
* Metadata key recording the session-log event seqs (of the direct user
|
|
34
|
-
* messages) the entry cites as its source (trajectory citation).
|
|
35
|
-
*/
|
|
36
|
-
export declare const SOURCE_SEQS_KEY = "sourceSeqs";
|
|
37
|
-
/**
|
|
38
|
-
* Metadata key recording when an entry was archived. Archived entries are
|
|
39
|
-
* hidden from injection but never deleted — the data stays in the store and
|
|
40
|
-
* the entry can be restored (unarchive) or rolled back like any other edit.
|
|
41
|
-
*/
|
|
42
|
-
export declare const ARCHIVED_AT_KEY = "archivedAt";
|
|
43
|
-
/**
|
|
44
|
-
* Metadata key stamped on a LOCAL entry that was promoted to the global
|
|
45
|
-
* store by a session wrap-up: the id of the global entry it became. Present
|
|
46
|
-
* means the entry's lifecycle is finished — it must not be offered for
|
|
47
|
-
* promotion again (the global copy is the live one, the local copy is a
|
|
48
|
-
* restorable trace).
|
|
49
|
-
*/
|
|
50
|
-
export declare const PROMOTED_TO_KEY = "promotedTo";
|
|
51
|
-
/**
|
|
52
|
-
* Metadata key recording when a local entry was promoted to the global
|
|
53
|
-
* store (companion of {@link PROMOTED_TO_KEY}).
|
|
54
|
-
*/
|
|
55
|
-
export declare const PROMOTED_AT_KEY = "promotedAt";
|
|
56
|
-
/**
|
|
57
|
-
* Metadata key stamped on a GLOBAL entry created by a session wrap-up
|
|
58
|
-
* promotion: `<sessionId>:<localEntryId>` — the反向 provenance link from the
|
|
59
|
-
* cross-session copy back to the session it was distilled from.
|
|
60
|
-
*/
|
|
61
|
-
export declare const SOURCED_FROM_KEY = "sourcedFromLocal";
|
|
62
|
-
/**
|
|
63
|
-
* Metadata key stamped on a GLOBAL entry that was created despite a
|
|
64
|
-
* moderate-similarity overlap with an existing entry (write-time conflict
|
|
65
|
-
* guard, warn tier): `<kind>:<id>:<score>` — points at the entry it may
|
|
66
|
-
* duplicate so wrapup/fate can consolidate later. Creates at/above the block
|
|
67
|
-
* threshold never reach this stamp; they are rejected outright.
|
|
68
|
-
*/
|
|
69
|
-
export declare const CONFLICT_HINT_KEY = "conflictHint";
|
|
70
|
-
/**
|
|
71
|
-
* Negative-valence counter (P1 效价反馈): how many times an assessment marked
|
|
72
|
-
* this entry contradicted by newer evidence (user correction, overridden
|
|
73
|
-
* fact). Injection ranking demotes entries with a positive counter and the
|
|
74
|
-
* wrapup/fate assessors see the count so they prefer archiving the entry.
|
|
75
|
-
*/
|
|
76
|
-
export declare const VALENCE_NEGATIVE_KEY = "valenceNegative";
|
|
77
|
-
/**
|
|
78
|
-
* Provenance of entries merged INTO this one by the consolidation command
|
|
79
|
-
* (P1 反膨胀): array of `<kind>:<id>` — the near-duplicate sources whose
|
|
80
|
-
* content was appended before they archived. The trail keeps an unarchive of
|
|
81
|
-
* the source explainable and lets audits find the merge provenance.
|
|
82
|
-
*/
|
|
83
|
-
export declare const MERGED_FROM_KEY = "mergedFrom";
|
|
84
|
-
/**
|
|
85
|
-
* True when the entry is archived (hidden from injection, restorable).
|
|
86
|
-
* Absent or empty archivedAt means the entry is active.
|
|
87
|
-
*/
|
|
88
|
-
export declare function isArchived(entry: HarnessEntry): boolean;
|
|
89
|
-
/**
|
|
90
|
-
* Trajectory citation attached to newly created entries: the session the
|
|
91
|
-
* content came from and the seqs of the direct user messages it was
|
|
92
|
-
* distilled from. Both fields are optional — when they cannot be determined
|
|
93
|
-
* the citation is simply omitted (never an error).
|
|
94
|
-
*/
|
|
95
|
-
export interface EntrySource {
|
|
96
|
-
sessionId?: string;
|
|
97
|
-
/** Event seqs of the source user messages, in log order. */
|
|
98
|
-
seqs?: number[];
|
|
99
|
-
}
|
|
100
|
-
/** A single persisted harness entry. */
|
|
101
|
-
export interface HarnessEntry {
|
|
102
|
-
id: string;
|
|
103
|
-
kind: RefinementKind;
|
|
104
|
-
title: string;
|
|
105
|
-
content: string;
|
|
106
|
-
path: string;
|
|
107
|
-
scope: HarnessScope;
|
|
108
|
-
/** Skill entries carry an executable contract; see {@link PythonReference}. */
|
|
109
|
-
reference: Record<string, unknown>;
|
|
110
|
-
/** Skill entries declare their accepted inputs here. */
|
|
111
|
-
arguments: Record<string, unknown>;
|
|
112
|
-
/** Skill form: "executable" (default) or "guidance" (SKILL.md document). */
|
|
113
|
-
skill_kind?: SkillKind;
|
|
114
|
-
metadata: Record<string, unknown>;
|
|
115
|
-
source: "evolve";
|
|
116
|
-
created_at: string;
|
|
117
|
-
updated_at: string;
|
|
118
|
-
version: number;
|
|
119
|
-
}
|
|
120
|
-
/** One entry of the append-only refinement history (the evidence trail). */
|
|
121
|
-
export interface HarnessRefinementEvent {
|
|
122
|
-
id: string;
|
|
123
|
-
trigger: string;
|
|
124
|
-
changes: string[];
|
|
125
|
-
/** Where the trajectory evidence for this refinement lives (e.g. seq ranges). */
|
|
126
|
-
evidence: string;
|
|
127
|
-
/** The falsifiable expectation recorded with the edit. */
|
|
128
|
-
outcome: string;
|
|
129
|
-
created_at: string;
|
|
130
|
-
}
|
|
131
|
-
/** The whole harness state file. */
|
|
132
|
-
export interface HarnessState {
|
|
133
|
-
schema: number;
|
|
134
|
-
entries: Record<RefinementKind, Record<string, HarnessEntry>>;
|
|
135
|
-
refinements: HarnessRefinementEvent[];
|
|
136
|
-
}
|
|
137
|
-
/** A model-proposed edit, before validation and application. */
|
|
138
|
-
export interface RefinementEdit {
|
|
139
|
-
action: RefinementAction;
|
|
140
|
-
kind: RefinementKind;
|
|
141
|
-
id?: string;
|
|
142
|
-
title?: string;
|
|
143
|
-
content?: string;
|
|
144
|
-
path?: string;
|
|
145
|
-
reference?: Record<string, unknown>;
|
|
146
|
-
arguments?: Record<string, unknown>;
|
|
147
|
-
/** Skill form: "guidance" for SKILL.md document skills; absent = executable. */
|
|
148
|
-
skill_kind?: SkillKind;
|
|
149
|
-
metadata?: Record<string, unknown>;
|
|
150
|
-
reason?: string;
|
|
151
|
-
/**
|
|
152
|
-
* Gap C2: blast-radius annotation — how broadly this edit applies.
|
|
153
|
-
* Values: "general" (cross-project tactical), "project" (single project),
|
|
154
|
-
* "session" (one-off session-specific). The review gate checks that
|
|
155
|
-
* local-scope edits are "session" or "project" and global-scope edits
|
|
156
|
-
* are "general" or "project".
|
|
157
|
-
*/
|
|
158
|
-
blastRadius?: "general" | "project" | "session";
|
|
159
|
-
}
|
|
160
|
-
/** The structured output of a planning pass. */
|
|
161
|
-
export interface RefinementProposal {
|
|
162
|
-
summary: string;
|
|
163
|
-
rationale: string;
|
|
164
|
-
edits: RefinementEdit[];
|
|
165
|
-
expectedOutcome: string;
|
|
166
|
-
}
|
|
167
|
-
/** An edit after the apply pass: before/after snapshots and outcome per edit. */
|
|
168
|
-
export interface AppliedRefinementEdit extends RefinementEdit {
|
|
169
|
-
id: string;
|
|
170
|
-
before?: HarnessEntry;
|
|
171
|
-
after?: HarnessEntry;
|
|
172
|
-
applied: boolean;
|
|
173
|
-
error?: string;
|
|
174
|
-
}
|
|
175
|
-
/** The result of applying one refinement. */
|
|
176
|
-
export interface RefinementResult {
|
|
177
|
-
id: string;
|
|
178
|
-
summary: string;
|
|
179
|
-
rationale: string;
|
|
180
|
-
expectedOutcome: string;
|
|
181
|
-
appliedEdits: AppliedRefinementEdit[];
|
|
182
|
-
harnessStatePath: string;
|
|
183
|
-
rollbackOf?: string;
|
|
184
|
-
scope?: HarnessScope;
|
|
185
|
-
}
|
|
186
|
-
/** The executable contract a skill entry must carry (python REPL skills). */
|
|
187
|
-
export interface PythonReference {
|
|
188
|
-
type: "python";
|
|
189
|
-
import?: string;
|
|
190
|
-
python_import?: string;
|
|
191
|
-
callable?: string;
|
|
192
|
-
call_pattern?: string;
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* A stable id derived from a title: ASCII runs become snake_case (unchanged
|
|
196
|
-
* legacy behavior). Titles with no ASCII content at all (e.g. pure Chinese)
|
|
197
|
-
* used to collapse onto the bare fallback, so distinct memories shared one
|
|
198
|
-
* id and every later create failed as "already exists". They now take
|
|
199
|
-
* `<fallback>_<sha256-8>` instead: distinct titles get distinct ids while
|
|
200
|
-
* identical titles still dedupe onto the same id. The fallback itself is
|
|
201
|
-
* assumed id-safe (callers pass entry kinds).
|
|
202
|
-
*/
|
|
203
|
-
export declare function slug(raw: string, fallback: string): string;
|
|
204
|
-
/** Fresh empty state with the current schema version. */
|
|
205
|
-
export declare function emptyHarnessState(): HarnessState;
|
|
206
|
-
/** Deep clone helper (state is plain JSON data). */
|
|
207
|
-
export declare function cloneEntry(entry: HarnessEntry | undefined): HarnessEntry | undefined;
|
|
208
|
-
/**
|
|
209
|
-
* Storage-hygiene defaults (#20): JSONL tail lines kept per store history
|
|
210
|
-
* and per shared audit trail when no explicit `historyRetain` is set.
|
|
211
|
-
*/
|
|
212
|
-
export declare const DEFAULT_REFINEMENTS_RETAIN = 500;
|
|
213
|
-
export declare const DEFAULT_REVIEWS_RETAIN = 500;
|
|
214
|
-
/** Prefix-cache routing modes for extractor/planner inputs (see prefix-cache.ts). */
|
|
215
|
-
export type PlannerPrefixCacheMode = "auto" | "session" | "off";
|
|
216
|
-
/** The only two durable outcomes a scope-approval dialog may produce. */
|
|
217
|
-
export type ScopeApprovalDecision = "approved" | "declined";
|
|
218
|
-
//# sourceMappingURL=types.d.ts.map
|
package/lib/types.js
DELETED
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Type model for the continual-evolution harness state.
|
|
3
|
-
*
|
|
4
|
-
* Design provenance: the state model follows the continual-harness design
|
|
5
|
-
* validated in prime-agent's `/refine` subsystem (MIT): versioned entries
|
|
6
|
-
* keyed by kind, an append-only refinement history carrying an evidence
|
|
7
|
-
* trail, atomic persistence, and deterministic inverse-op rollback. The
|
|
8
|
-
* code here is an original implementation, written for the DeepSeek Harness
|
|
9
|
-
* plugin surface.
|
|
10
|
-
*/
|
|
11
|
-
import { createHash } from "node:crypto";
|
|
12
|
-
/**
|
|
13
|
-
* Memory-entry shape discipline (one fact per entry, typed like ZCode's
|
|
14
|
-
* memory frontmatter): every `memory` create must stamp one of these in
|
|
15
|
-
* `metadata[MEMORY_TYPE_KEY]` — the recall hook the directory shows.
|
|
16
|
-
*/
|
|
17
|
-
export const MEMORY_TYPE_KEY = "memoryType";
|
|
18
|
-
/** Closed memory-type set: user | feedback | project | reference. */
|
|
19
|
-
export const MEMORY_TYPES = ["user", "feedback", "project", "reference"];
|
|
20
|
-
/** True when the value is a closed-set memory type. */
|
|
21
|
-
export function isMemoryType(value) {
|
|
22
|
-
return typeof value === "string" && MEMORY_TYPES.includes(value);
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Metadata key recording which session an entry's content was distilled from
|
|
26
|
-
* (trajectory citation; see {@link EntrySource}).
|
|
27
|
-
*/
|
|
28
|
-
export const SOURCE_SESSION_KEY = "sourceSession";
|
|
29
|
-
/**
|
|
30
|
-
* Metadata key recording the session-log event seqs (of the direct user
|
|
31
|
-
* messages) the entry cites as its source (trajectory citation).
|
|
32
|
-
*/
|
|
33
|
-
export const SOURCE_SEQS_KEY = "sourceSeqs";
|
|
34
|
-
/**
|
|
35
|
-
* Metadata key recording when an entry was archived. Archived entries are
|
|
36
|
-
* hidden from injection but never deleted — the data stays in the store and
|
|
37
|
-
* the entry can be restored (unarchive) or rolled back like any other edit.
|
|
38
|
-
*/
|
|
39
|
-
export const ARCHIVED_AT_KEY = "archivedAt";
|
|
40
|
-
/**
|
|
41
|
-
* Metadata key stamped on a LOCAL entry that was promoted to the global
|
|
42
|
-
* store by a session wrap-up: the id of the global entry it became. Present
|
|
43
|
-
* means the entry's lifecycle is finished — it must not be offered for
|
|
44
|
-
* promotion again (the global copy is the live one, the local copy is a
|
|
45
|
-
* restorable trace).
|
|
46
|
-
*/
|
|
47
|
-
export const PROMOTED_TO_KEY = "promotedTo";
|
|
48
|
-
/**
|
|
49
|
-
* Metadata key recording when a local entry was promoted to the global
|
|
50
|
-
* store (companion of {@link PROMOTED_TO_KEY}).
|
|
51
|
-
*/
|
|
52
|
-
export const PROMOTED_AT_KEY = "promotedAt";
|
|
53
|
-
/**
|
|
54
|
-
* Metadata key stamped on a GLOBAL entry created by a session wrap-up
|
|
55
|
-
* promotion: `<sessionId>:<localEntryId>` — the反向 provenance link from the
|
|
56
|
-
* cross-session copy back to the session it was distilled from.
|
|
57
|
-
*/
|
|
58
|
-
export const SOURCED_FROM_KEY = "sourcedFromLocal";
|
|
59
|
-
/**
|
|
60
|
-
* Metadata key stamped on a GLOBAL entry that was created despite a
|
|
61
|
-
* moderate-similarity overlap with an existing entry (write-time conflict
|
|
62
|
-
* guard, warn tier): `<kind>:<id>:<score>` — points at the entry it may
|
|
63
|
-
* duplicate so wrapup/fate can consolidate later. Creates at/above the block
|
|
64
|
-
* threshold never reach this stamp; they are rejected outright.
|
|
65
|
-
*/
|
|
66
|
-
export const CONFLICT_HINT_KEY = "conflictHint";
|
|
67
|
-
/**
|
|
68
|
-
* Negative-valence counter (P1 效价反馈): how many times an assessment marked
|
|
69
|
-
* this entry contradicted by newer evidence (user correction, overridden
|
|
70
|
-
* fact). Injection ranking demotes entries with a positive counter and the
|
|
71
|
-
* wrapup/fate assessors see the count so they prefer archiving the entry.
|
|
72
|
-
*/
|
|
73
|
-
export const VALENCE_NEGATIVE_KEY = "valenceNegative";
|
|
74
|
-
/**
|
|
75
|
-
* Provenance of entries merged INTO this one by the consolidation command
|
|
76
|
-
* (P1 反膨胀): array of `<kind>:<id>` — the near-duplicate sources whose
|
|
77
|
-
* content was appended before they archived. The trail keeps an unarchive of
|
|
78
|
-
* the source explainable and lets audits find the merge provenance.
|
|
79
|
-
*/
|
|
80
|
-
export const MERGED_FROM_KEY = "mergedFrom";
|
|
81
|
-
/**
|
|
82
|
-
* True when the entry is archived (hidden from injection, restorable).
|
|
83
|
-
* Absent or empty archivedAt means the entry is active.
|
|
84
|
-
*/
|
|
85
|
-
export function isArchived(entry) {
|
|
86
|
-
const value = entry.metadata[ARCHIVED_AT_KEY];
|
|
87
|
-
return typeof value === "string" && value.length > 0;
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* A stable id derived from a title: ASCII runs become snake_case (unchanged
|
|
91
|
-
* legacy behavior). Titles with no ASCII content at all (e.g. pure Chinese)
|
|
92
|
-
* used to collapse onto the bare fallback, so distinct memories shared one
|
|
93
|
-
* id and every later create failed as "already exists". They now take
|
|
94
|
-
* `<fallback>_<sha256-8>` instead: distinct titles get distinct ids while
|
|
95
|
-
* identical titles still dedupe onto the same id. The fallback itself is
|
|
96
|
-
* assumed id-safe (callers pass entry kinds).
|
|
97
|
-
*/
|
|
98
|
-
export function slug(raw, fallback) {
|
|
99
|
-
const normalized = raw
|
|
100
|
-
.trim()
|
|
101
|
-
.toLowerCase()
|
|
102
|
-
.replace(/[^a-z0-9]+/g, "_")
|
|
103
|
-
.replace(/^_+|_+$/g, "")
|
|
104
|
-
.slice(0, 80);
|
|
105
|
-
if (normalized)
|
|
106
|
-
return normalized;
|
|
107
|
-
const digest = createHash("sha256").update(raw, "utf8").digest("hex").slice(0, 8);
|
|
108
|
-
return `${fallback}_${digest}`;
|
|
109
|
-
}
|
|
110
|
-
/** Fresh empty state with the current schema version. */
|
|
111
|
-
export function emptyHarnessState() {
|
|
112
|
-
return {
|
|
113
|
-
schema: 1,
|
|
114
|
-
entries: {
|
|
115
|
-
prompt: {},
|
|
116
|
-
memory: {},
|
|
117
|
-
skill: {},
|
|
118
|
-
subagent: {},
|
|
119
|
-
},
|
|
120
|
-
refinements: [],
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
/** Deep clone helper (state is plain JSON data). */
|
|
124
|
-
export function cloneEntry(entry) {
|
|
125
|
-
return entry ? JSON.parse(JSON.stringify(entry)) : undefined;
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* Storage-hygiene defaults (#20): JSONL tail lines kept per store history
|
|
129
|
-
* and per shared audit trail when no explicit `historyRetain` is set.
|
|
130
|
-
*/
|
|
131
|
-
export const DEFAULT_REFINEMENTS_RETAIN = 500;
|
|
132
|
-
export const DEFAULT_REVIEWS_RETAIN = 500;
|
|
133
|
-
//# sourceMappingURL=types.js.map
|
package/lib/usage.d.ts
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import type { RefinementKind } from "./types.js";
|
|
2
|
-
export interface UsageStore {
|
|
3
|
-
/** Injection count per entry key (`kind:id`). */
|
|
4
|
-
counts: Record<string, number>;
|
|
5
|
-
/** Session dedup marker: the last session id each key was counted in (v2). */
|
|
6
|
-
lastSession?: Record<string, string>;
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* Load the usage store from disk; returns an empty store when absent or
|
|
10
|
-
* corrupt. Accepts BOTH on-disk shapes:
|
|
11
|
-
* - legacy (≤0.3.x): a flat `{ "kind:id": count }` map,
|
|
12
|
-
* - v2: `{ version: 2, counts, lastSession }` with per-session dedup.
|
|
13
|
-
*/
|
|
14
|
-
export declare function loadUsage(baseDir: string): UsageStore;
|
|
15
|
-
/** Persist the usage store atomically (always the v2 shape). */
|
|
16
|
-
export declare function saveUsage(baseDir: string, store: UsageStore): void;
|
|
17
|
-
/** Build the usage key for an entry. */
|
|
18
|
-
export declare function usageKey(kind: RefinementKind, id: string): string;
|
|
19
|
-
/**
|
|
20
|
-
* Increment injection counts for the entries that were actually injected.
|
|
21
|
-
* Called after `entriesSectionText` renders the injected block. Keys not
|
|
22
|
-
* present in the store are initialized to 1.
|
|
23
|
-
*
|
|
24
|
-
* Session dedup (2026-08-22): with a sessionId, each key counts AT MOST
|
|
25
|
-
* ONCE per session — the old per-build counting produced meaningless
|
|
26
|
-
* numbers (one entry hit 2311× in a week) and hid the real "how many
|
|
27
|
-
* sessions found this useful" signal that staleness decay needs. Without
|
|
28
|
-
* a sessionId the call degrades to legacy always-increment behavior.
|
|
29
|
-
*/
|
|
30
|
-
export declare function recordInjection(baseDir: string, injectedKeys: readonly string[], sessionId?: string): void;
|
|
31
|
-
/**
|
|
32
|
-
* Get the injection count for a specific entry. Returns 0 when the entry
|
|
33
|
-
* has never been injected (absent from the store).
|
|
34
|
-
*/
|
|
35
|
-
export declare function getUsageCount(store: UsageStore, kind: RefinementKind, id: string): number;
|
|
36
|
-
//# sourceMappingURL=usage.d.ts.map
|
package/lib/usage.js
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Entry usage tracking (gap B1): records how many times each entry has been
|
|
3
|
-
* injected into system prompts. The counts are durable (persisted to disk)
|
|
4
|
-
* and exposed in `evolve_list` and the gate's archive-candidate reporting,
|
|
5
|
-
* so "zero-usage stale entries" can be surfaced for cleanup.
|
|
6
|
-
*
|
|
7
|
-
* Storage: `<baseDir>/evolve/usage.json` — a flat JSON object mapping
|
|
8
|
-
* `kind:id` to an integer count. Reads are tolerant of missing/corrupt files;
|
|
9
|
-
* writes are atomic (tmp + rename).
|
|
10
|
-
*/
|
|
11
|
-
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
12
|
-
import { join } from "node:path";
|
|
13
|
-
const USAGE_FILE = "usage.json";
|
|
14
|
-
function usagePath(baseDir) {
|
|
15
|
-
return join(baseDir, "evolve", USAGE_FILE);
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Load the usage store from disk; returns an empty store when absent or
|
|
19
|
-
* corrupt. Accepts BOTH on-disk shapes:
|
|
20
|
-
* - legacy (≤0.3.x): a flat `{ "kind:id": count }` map,
|
|
21
|
-
* - v2: `{ version: 2, counts, lastSession }` with per-session dedup.
|
|
22
|
-
*/
|
|
23
|
-
export function loadUsage(baseDir) {
|
|
24
|
-
const path = usagePath(baseDir);
|
|
25
|
-
try {
|
|
26
|
-
if (!existsSync(path))
|
|
27
|
-
return { counts: {}, lastSession: {} };
|
|
28
|
-
const raw = JSON.parse(readFileSync(path, "utf8"));
|
|
29
|
-
if (typeof raw === "object" && raw !== null && !Array.isArray(raw)) {
|
|
30
|
-
const record = raw;
|
|
31
|
-
if (record["version"] === 2 && typeof record["counts"] === "object" && record["counts"] !== null) {
|
|
32
|
-
return {
|
|
33
|
-
counts: record["counts"],
|
|
34
|
-
lastSession: typeof record["lastSession"] === "object" && record["lastSession"] !== null
|
|
35
|
-
? record["lastSession"]
|
|
36
|
-
: {},
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
// Legacy flat map: every key is a count.
|
|
40
|
-
return { counts: raw, lastSession: {} };
|
|
41
|
-
}
|
|
42
|
-
return { counts: {}, lastSession: {} };
|
|
43
|
-
}
|
|
44
|
-
catch {
|
|
45
|
-
return { counts: {}, lastSession: {} };
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
/** Persist the usage store atomically (always the v2 shape). */
|
|
49
|
-
export function saveUsage(baseDir, store) {
|
|
50
|
-
const dir = join(baseDir, "evolve");
|
|
51
|
-
mkdirSync(dir, { recursive: true });
|
|
52
|
-
const path = usagePath(baseDir);
|
|
53
|
-
const tmp = `${path}.${process.pid}.tmp`;
|
|
54
|
-
writeFileSync(tmp, `${JSON.stringify({ version: 2, counts: store.counts, lastSession: store.lastSession ?? {} }, null, 2)}\n`, "utf8");
|
|
55
|
-
renameSync(tmp, path);
|
|
56
|
-
}
|
|
57
|
-
/** Build the usage key for an entry. */
|
|
58
|
-
export function usageKey(kind, id) {
|
|
59
|
-
return `${kind}:${id}`;
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Increment injection counts for the entries that were actually injected.
|
|
63
|
-
* Called after `entriesSectionText` renders the injected block. Keys not
|
|
64
|
-
* present in the store are initialized to 1.
|
|
65
|
-
*
|
|
66
|
-
* Session dedup (2026-08-22): with a sessionId, each key counts AT MOST
|
|
67
|
-
* ONCE per session — the old per-build counting produced meaningless
|
|
68
|
-
* numbers (one entry hit 2311× in a week) and hid the real "how many
|
|
69
|
-
* sessions found this useful" signal that staleness decay needs. Without
|
|
70
|
-
* a sessionId the call degrades to legacy always-increment behavior.
|
|
71
|
-
*/
|
|
72
|
-
export function recordInjection(baseDir, injectedKeys, sessionId) {
|
|
73
|
-
if (injectedKeys.length === 0)
|
|
74
|
-
return;
|
|
75
|
-
const store = loadUsage(baseDir);
|
|
76
|
-
let dirty = false;
|
|
77
|
-
for (const key of injectedKeys) {
|
|
78
|
-
if (sessionId !== undefined && store.lastSession?.[key] === sessionId) {
|
|
79
|
-
continue;
|
|
80
|
-
}
|
|
81
|
-
store.counts[key] = (store.counts[key] ?? 0) + 1;
|
|
82
|
-
if (store.lastSession && sessionId !== undefined) {
|
|
83
|
-
store.lastSession[key] = sessionId;
|
|
84
|
-
}
|
|
85
|
-
dirty = true;
|
|
86
|
-
}
|
|
87
|
-
if (dirty) {
|
|
88
|
-
saveUsage(baseDir, store);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Get the injection count for a specific entry. Returns 0 when the entry
|
|
93
|
-
* has never been injected (absent from the store).
|
|
94
|
-
*/
|
|
95
|
-
export function getUsageCount(store, kind, id) {
|
|
96
|
-
return store.counts[usageKey(kind, id)] ?? 0;
|
|
97
|
-
}
|
|
98
|
-
//# sourceMappingURL=usage.js.map
|
package/lib/validate.d.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Code-enforced validation of model-proposed edits. Every rule here exists
|
|
3
|
-
* because the proposal is untrusted input: enum membership, immutability of
|
|
4
|
-
* the base system prompt, required fields per action, and the executable
|
|
5
|
-
* contract skill entries must carry.
|
|
6
|
-
*/
|
|
7
|
-
import type { HarnessEntry, HarnessScope, RefinementEdit } from "./types.js";
|
|
8
|
-
export declare const BASE_SYSTEM_PROMPT_ID = "base_system_prompt";
|
|
9
|
-
/**
|
|
10
|
-
* Gap C2: mechanical check that an edit's declared blast radius is coherent
|
|
11
|
-
* with the scope it targets. A session-scoped edit claiming "general" would
|
|
12
|
-
* silently read like a cross-project tactical rule; a global edit claiming
|
|
13
|
-
* "session" would contradict its persistence. Absent blastRadius is NOT
|
|
14
|
-
* rejected (pre-C2 data and manual edits stay compatible) — the planner is
|
|
15
|
-
* instructed to always declare it, and this rule catches what it declares
|
|
16
|
-
* incoherently.
|
|
17
|
-
*/
|
|
18
|
-
export declare function validateBlastRadiusScope(scope: HarnessScope, blastRadius: "general" | "project" | "session"): string | undefined;
|
|
19
|
-
/**
|
|
20
|
-
* Returns a human-readable failure reason, or undefined when the edit passes.
|
|
21
|
-
*
|
|
22
|
-
* `before` (the entry the edit targets, absent for creates/unknown ids) lets
|
|
23
|
-
* update rules distinguish "carrying the persisted value" from "changing it"
|
|
24
|
-
* — e.g. a rollback inverse re-carries the stored skill_kind, which must
|
|
25
|
-
* pass, while a genuine executable↔guidance switch must not.
|
|
26
|
-
*/
|
|
27
|
-
export declare function validateEdit(edit: RefinementEdit, computedId: string | undefined, scope?: HarnessScope, before?: HarnessEntry): string | undefined;
|
|
28
|
-
//# sourceMappingURL=validate.d.ts.map
|