@lmzhen/dsh-evolution-feedback 0.3.71 → 0.3.72
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/lib/index.js +26 -2
- package/lib/types/index.d.ts +8 -0
- package/package.json +7 -7
package/lib/index.js
CHANGED
|
@@ -223,6 +223,14 @@ var EvolutionFeedback = class EvolutionFeedback {
|
|
|
223
223
|
if (total === 0) return 0;
|
|
224
224
|
return (record.positive - record.negative) / total;
|
|
225
225
|
}
|
|
226
|
+
/**
|
|
227
|
+
* Deep-copy view of the live aggregate.
|
|
228
|
+
*
|
|
229
|
+
* OPT-26 (2026-09): `@internal` — test-support API, NO production consumer
|
|
230
|
+
* in the family (mirrors the explicit posture of evolution-replay's
|
|
231
|
+
* `plansSnapshot()`). External consumers should read the rendered
|
|
232
|
+
* score/warn surfaces instead of relying on this shape.
|
|
233
|
+
*/
|
|
226
234
|
snapshot() {
|
|
227
235
|
const copyRecords = (table) => {
|
|
228
236
|
const out = {};
|
|
@@ -373,12 +381,28 @@ function parseCache(raw, warn = () => {}) {
|
|
|
373
381
|
/** Per-record numeric-domain validation (S6.4): a record whose `positive` or
|
|
374
382
|
* `negative` is not a finite number >= 0, or whose `lastNote` is not a string,
|
|
375
383
|
* would fold as NaN into the usage aggregate — skip it with a warn instead of
|
|
376
|
-
* corrupting the state. A record with no valid count is dropped entirely.
|
|
384
|
+
* corrupting the state. A record with no valid count is dropped entirely.
|
|
385
|
+
* OPT-25 (2026-09): a count ABOVE `MAX_MIGRATED_EVENTS_PER_RECORD` is now
|
|
386
|
+
* CLAMPED here with a warn, symmetric with the migration reader's clamp (same
|
|
387
|
+
* file, same threat model — V24-05 covered the migration side only). Before,
|
|
388
|
+
* a poisoned boot-cache count folded as-is into every downstream decision;
|
|
389
|
+
* the clamp bounds the skew to the same ceiling migration accepts. */
|
|
377
390
|
function sanitizeCacheRecords(input, kind, warn) {
|
|
378
391
|
const out = {};
|
|
379
392
|
for (const [target, value] of Object.entries(input)) {
|
|
380
393
|
const record = sanitizeFeedbackRecord(value, target, kind, warn);
|
|
381
|
-
if (record)
|
|
394
|
+
if (record) {
|
|
395
|
+
let clamped;
|
|
396
|
+
if (record.positive > MAX_MIGRATED_EVENTS_PER_RECORD || record.negative > MAX_MIGRATED_EVENTS_PER_RECORD) {
|
|
397
|
+
warn(`evolution-feedback: cache record for ${kind} "${target}" exceeds the clamp ceiling (${MAX_MIGRATED_EVENTS_PER_RECORD}) — clamping like the migration reader`);
|
|
398
|
+
clamped = {
|
|
399
|
+
positive: Math.min(record.positive, MAX_MIGRATED_EVENTS_PER_RECORD),
|
|
400
|
+
negative: Math.min(record.negative, MAX_MIGRATED_EVENTS_PER_RECORD),
|
|
401
|
+
...record.lastNote !== void 0 ? { lastNote: record.lastNote } : {}
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
out[target] = clamped ?? record;
|
|
405
|
+
}
|
|
382
406
|
}
|
|
383
407
|
return out;
|
|
384
408
|
}
|
package/lib/types/index.d.ts
CHANGED
|
@@ -98,6 +98,14 @@ export declare class EvolutionFeedback {
|
|
|
98
98
|
refold(): Promise<void>;
|
|
99
99
|
record(target: string, rating: 'positive' | 'negative', note?: string, kind?: 'skill' | 'session'): void;
|
|
100
100
|
score(target: string, kind?: 'skill' | 'session'): number;
|
|
101
|
+
/**
|
|
102
|
+
* Deep-copy view of the live aggregate.
|
|
103
|
+
*
|
|
104
|
+
* OPT-26 (2026-09): `@internal` — test-support API, NO production consumer
|
|
105
|
+
* in the family (mirrors the explicit posture of evolution-replay's
|
|
106
|
+
* `plansSnapshot()`). External consumers should read the rendered
|
|
107
|
+
* score/warn surfaces instead of relying on this shape.
|
|
108
|
+
*/
|
|
101
109
|
snapshot(): FeedbackState;
|
|
102
110
|
/** Await the pending record-task chain (unload safety; rc.66). */
|
|
103
111
|
waitIdle(): Promise<unknown>;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lmzhen/dsh-evolution-feedback",
|
|
3
3
|
"description": "Feedback-to-quality scoring for self-evolution (community build)",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.72",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -31,18 +31,18 @@
|
|
|
31
31
|
"license": "MIT",
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@deepseek-ai/schemastery": "^3.18.1",
|
|
34
|
-
"@lmzhen/dsh-evolution-core": "^0.3.
|
|
34
|
+
"@lmzhen/dsh-evolution-core": "^0.3.72"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
37
|
"@deepseek-ai/dsh-invariants": "^0.1.5-rc.2",
|
|
38
38
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
39
|
-
"@lmzhen/dsh-evolution-io": "^0.3.
|
|
40
|
-
"@lmzhen/dsh-skill-usage": "^0.3.
|
|
39
|
+
"@lmzhen/dsh-evolution-io": "^0.3.72",
|
|
40
|
+
"@lmzhen/dsh-skill-usage": "^0.3.72"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@deepseek-ai/dsh-invariants": "^0.1.5-rc.2",
|
|
44
|
-
"@lmzhen/dsh-evolution-io": "^0.3.
|
|
45
|
-
"@lmzhen/dsh-evolution-io-node": "^0.3.
|
|
46
|
-
"@lmzhen/dsh-skill-usage": "^0.3.
|
|
44
|
+
"@lmzhen/dsh-evolution-io": "^0.3.72",
|
|
45
|
+
"@lmzhen/dsh-evolution-io-node": "^0.3.72",
|
|
46
|
+
"@lmzhen/dsh-skill-usage": "^0.3.72"
|
|
47
47
|
}
|
|
48
48
|
}
|