@lmzhen/dsh-evolution-replay 0.3.81 → 0.3.83

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
@@ -1,4 +1,4 @@
1
- # @deepseek-ai/dsh-evolution-replay
1
+ # @lmzhen/dsh-evolution-replay
2
2
 
3
3
  Replay/A-B evaluation primitives for evolution plans
4
4
 
@@ -8,7 +8,7 @@ Replay/A-B evaluation primitives for evolution plans
8
8
 
9
9
  #### What the model sees
10
10
 
11
- `@deepseek-ai/dsh-evolution-replay` registers no direct prompt or tool schema itself. Model-visible effects are owned by the packages that consume this service.
11
+ `@lmzhen/dsh-evolution-replay` registers no direct prompt or tool schema itself. Model-visible effects are owned by the packages that consume this service.
12
12
 
13
13
  #### Token effect
14
14
 
package/lib/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import z from "@deepseek-ai/schemastery";
2
2
  import { clampedNumber, evolutionHome, evolutionIoAdapter } from "@lmzhen/dsh-evolution-core";
3
- import { loadActivity } from "@lmzhen/dsh-evolution-activity";
3
+ import { loadActivityState } from "@lmzhen/dsh-evolution-activity";
4
4
  //#region lib/types/index.js
5
5
  /**
6
6
  * Replay/A-B evaluation for evolution plans.
@@ -94,8 +94,15 @@ var EvolutionReplayDriver = class EvolutionReplayDriver {
94
94
  maxPlans;
95
95
  /** V25-01 (v25): backfill-once latch — see {@link EvolutionReplayDriver.backfill}. */
96
96
  backfilled = false;
97
+ /** FLOW6-6 (v43): the backfill source was unreadable (newer format or corrupt
98
+ * bytes) — carried into every comparison so an empty leaderboard is never
99
+ * presented as "nothing was recorded". PLAN S5.1 (2026-09-16): this holds the
100
+ * most recent READ's verdict, not the first one — {@link EvolutionReplayDriver.markSourceReadable}
101
+ * clears it on a later clean read, so the qualification reflects the present
102
+ * instead of latching for the driver lifetime. */
103
+ sourceCorrupt = false;
97
104
  /** V26-05 (v25): plan ids recorded live BEFORE the backfill settled. A
98
- * plan-applied landing inside the one-shot `loadActivity` read window is
105
+ * plan-applied landing inside the one-shot `loadActivityState` read window is
99
106
  * recorded live AND persisted into the sidecar the backfill is reading —
100
107
  * `backfill()` drops those ids so the event is not counted twice.
101
108
  *
@@ -188,8 +195,41 @@ var EvolutionReplayDriver = class EvolutionReplayDriver {
188
195
  plansSnapshot() {
189
196
  return [...this.plans];
190
197
  }
198
+ /**
199
+ * FLOW6-6 (v43): mark the backfill source unreadable. Set by `apply()` when
200
+ * the activity sidecar carries bytes this build cannot read; the qualification
201
+ * then travels with every comparison — until a later read says otherwise
202
+ * (see {@link EvolutionReplayDriver.markSourceReadable}).
203
+ */
204
+ markSourceUnreadable() {
205
+ this.sourceCorrupt = true;
206
+ }
207
+ /**
208
+ * PLAN S5.1 (2026-09-16, audit P2-18): the counterpart clear — `apply()` calls
209
+ * this on every successful read whose bytes ARE the current format
210
+ * (`loadActivityState` answered `corrupt: false`), so the
211
+ * {@link ReplayResult.sourceCorrupt} qualification follows the CURRENT read
212
+ * state. Before this the flag latched for the driver lifetime: a repaired
213
+ * sidecar plus an io reload (HMR / plugin restart) backfilled the full
214
+ * history while `compare()` kept asserting "NOT the recorded history" — a
215
+ * permanent report claim contrary to fact. The corruption verdict is
216
+ * per-read; the past corruption itself stays observable through the warn
217
+ * `apply()` emits at mark time.
218
+ */
219
+ markSourceReadable() {
220
+ this.sourceCorrupt = false;
221
+ }
191
222
  compare(weights = this.weights) {
192
- return comparePlans([...this.plans], clampReplayWeights(weights, this.weights));
223
+ const result = comparePlans([...this.plans], clampReplayWeights(weights, this.weights));
224
+ if (!this.sourceCorrupt) return {
225
+ ...result,
226
+ sourceCorrupt: false
227
+ };
228
+ return {
229
+ ...result,
230
+ sourceCorrupt: true,
231
+ report: "The activity sidecar could not be read as the current format (corrupt bytes or a newer writer) — this leaderboard is NOT the recorded history, and an empty list does not mean nothing happened.\n" + result.report
232
+ };
193
233
  }
194
234
  };
195
235
  const name = "evolution-replay";
@@ -204,8 +244,12 @@ function apply(ctx, rawConfig = {}) {
204
244
  ctx.inject(["evolutionIo"], (ioCtx) => {
205
245
  const ioRegistry = ioCtx.evolutionIo;
206
246
  const io = evolutionIoAdapter(() => ioRegistry.provider());
207
- loadActivity(evolutionHome(), io).then((items) => {
208
- driver.backfill(items);
247
+ loadActivityState(evolutionHome(), io).then((loaded) => {
248
+ if (loaded.corrupt) {
249
+ ioCtx.logger.warn("evolution-replay: the activity sidecar could not be read as the current format (corrupt bytes or a newer writer) — the leaderboard backfilled from it is INCOMPLETE; the writer quarantines those bytes on its next append");
250
+ driver.markSourceUnreadable();
251
+ } else driver.markSourceReadable();
252
+ driver.backfill(loaded.records);
209
253
  }).catch((error) => {
210
254
  ioCtx.logger.warn(`evolution-replay: activity sidecar backfill skipped (${error instanceof Error ? error.message : String(error)})`);
211
255
  });
@@ -44,6 +44,13 @@ export interface ReplayResult {
44
44
  margin: number | null;
45
45
  plans: ReplayPlan[];
46
46
  report: string;
47
+ /** FLOW6-6 (v43): the activity sidecar could not be read as the current
48
+ * format at the most recent backfill read — `plans` is then NOT the
49
+ * recorded history, and the report says so. PLAN S5.1 (2026-09-16): the
50
+ * flag tracks the CURRENT read state, so a later clean read (the sidecar
51
+ * was repaired and an io reload re-read it) clears the qualification —
52
+ * it never outlives the condition it describes. */
53
+ sourceCorrupt?: boolean | undefined;
47
54
  }
48
55
  export interface ReplayWeights {
49
56
  accepted: number;
@@ -76,8 +83,15 @@ export declare class EvolutionReplayDriver {
76
83
  private readonly maxPlans;
77
84
  /** V25-01 (v25): backfill-once latch — see {@link EvolutionReplayDriver.backfill}. */
78
85
  private backfilled;
86
+ /** FLOW6-6 (v43): the backfill source was unreadable (newer format or corrupt
87
+ * bytes) — carried into every comparison so an empty leaderboard is never
88
+ * presented as "nothing was recorded". PLAN S5.1 (2026-09-16): this holds the
89
+ * most recent READ's verdict, not the first one — {@link EvolutionReplayDriver.markSourceReadable}
90
+ * clears it on a later clean read, so the qualification reflects the present
91
+ * instead of latching for the driver lifetime. */
92
+ private sourceCorrupt;
79
93
  /** V26-05 (v25): plan ids recorded live BEFORE the backfill settled. A
80
- * plan-applied landing inside the one-shot `loadActivity` read window is
94
+ * plan-applied landing inside the one-shot `loadActivityState` read window is
81
95
  * recorded live AND persisted into the sidecar the backfill is reading —
82
96
  * `backfill()` drops those ids so the event is not counted twice.
83
97
  *
@@ -121,6 +135,26 @@ export declare class EvolutionReplayDriver {
121
135
  * @internal Exported for this package's own tests only.
122
136
  */
123
137
  plansSnapshot(): ReplayPlan[];
138
+ /**
139
+ * FLOW6-6 (v43): mark the backfill source unreadable. Set by `apply()` when
140
+ * the activity sidecar carries bytes this build cannot read; the qualification
141
+ * then travels with every comparison — until a later read says otherwise
142
+ * (see {@link EvolutionReplayDriver.markSourceReadable}).
143
+ */
144
+ markSourceUnreadable(): void;
145
+ /**
146
+ * PLAN S5.1 (2026-09-16, audit P2-18): the counterpart clear — `apply()` calls
147
+ * this on every successful read whose bytes ARE the current format
148
+ * (`loadActivityState` answered `corrupt: false`), so the
149
+ * {@link ReplayResult.sourceCorrupt} qualification follows the CURRENT read
150
+ * state. Before this the flag latched for the driver lifetime: a repaired
151
+ * sidecar plus an io reload (HMR / plugin restart) backfilled the full
152
+ * history while `compare()` kept asserting "NOT the recorded history" — a
153
+ * permanent report claim contrary to fact. The corruption verdict is
154
+ * per-read; the past corruption itself stays observable through the warn
155
+ * `apply()` emits at mark time.
156
+ */
157
+ markSourceReadable(): void;
124
158
  compare(weights?: ReplayWeights): ReplayResult;
125
159
  }
126
160
  export declare const name = "evolution-replay";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lmzhen/dsh-evolution-replay",
3
3
  "description": "Replay/A-B evaluation primitives for evolution plans (community build)",
4
- "version": "0.3.81",
4
+ "version": "0.3.83",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -27,14 +27,14 @@
27
27
  "license": "MIT",
28
28
  "dependencies": {
29
29
  "@deepseek-ai/schemastery": "^3.18.1",
30
- "@lmzhen/dsh-evolution-activity": "^0.3.81",
31
- "@lmzhen/dsh-evolution-core": "^0.3.81"
30
+ "@lmzhen/dsh-evolution-activity": "^0.3.83",
31
+ "@lmzhen/dsh-evolution-core": "^0.3.83"
32
32
  },
33
33
  "peerDependencies": {
34
34
  "@deepseek-ai/cordis": "^4.0.1"
35
35
  },
36
36
  "devDependencies": {
37
- "@lmzhen/dsh-evolution-activity": "^0.3.81",
38
- "@lmzhen/dsh-evolution-core": "^0.3.81"
37
+ "@lmzhen/dsh-evolution-activity": "^0.3.83",
38
+ "@lmzhen/dsh-evolution-core": "^0.3.83"
39
39
  }
40
40
  }