@lmzhen/dsh-evolution-core 0.30.24 → 0.30.25

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 CHANGED
@@ -1214,7 +1214,7 @@ var UnitTransactions = class {
1214
1214
  this.now = options.now ?? (() => Date.now());
1215
1215
  }
1216
1216
  unitId(plan) {
1217
- return plan.runId + ":" + createHash("sha256").update(plan.pairKey).digest("hex").slice(0, 16);
1217
+ return plan.unitId ?? plan.runId + ":" + createHash("sha256").update(plan.pairKey).digest("hex").slice(0, 16);
1218
1218
  }
1219
1219
  async snapshot(plan, unitId, planDigest) {
1220
1220
  const targetBefore = await this.options.backend.readSkill(plan.target);
@@ -6530,7 +6530,8 @@ function runsFile(home) {
6530
6530
  const TERMINAL = new Set([
6531
6531
  "succeeded",
6532
6532
  "failed",
6533
- "cancelled"
6533
+ "cancelled",
6534
+ "interrupted"
6534
6535
  ]);
6535
6536
  /**
6536
6537
  * Parse an index body into records.
@@ -12287,6 +12288,7 @@ var SkillLibrary = class {
12287
12288
  return rollbackMessage(result.message, stuck);
12288
12289
  }
12289
12290
  }
12291
+ await this.foldArchivedUsage(sources, (/* @__PURE__ */ new Date()).toISOString());
12290
12292
  await plan.onPhase?.("sources-archived");
12291
12293
  await plan.onPhase?.("unit-written");
12292
12294
  return {
@@ -50,7 +50,7 @@ export interface RunProgress {
50
50
  readonly total: number;
51
51
  }
52
52
  /** The four terminal-or-live states of a run. */
53
- export type RunState = 'running' | 'succeeded' | 'failed' | 'cancelled';
53
+ export type RunState = 'running' | 'succeeded' | 'failed' | 'cancelled' | 'interrupted';
54
54
  /** One tracked run. `resultRef` is a path to the run's report, never its content. */
55
55
  export interface RunRecord {
56
56
  id: string;
@@ -104,7 +104,7 @@ export interface RunHandle {
104
104
  }
105
105
  /** How a run ended, as reported by its owner. */
106
106
  export interface RunOutcome {
107
- state: 'succeeded' | 'failed' | 'cancelled';
107
+ state: 'succeeded' | 'failed' | 'cancelled' | 'interrupted';
108
108
  resultRef?: string | undefined;
109
109
  failure?: string | undefined;
110
110
  /** @deprecated Legacy merge projection; read-only compatibility, never written. */
@@ -49,7 +49,7 @@ export const DEFAULT_RUN_RECORDS = 50;
49
49
  export function runsFile(home) {
50
50
  return join(home, 'runs.json');
51
51
  }
52
- const TERMINAL = new Set(['succeeded', 'failed', 'cancelled']);
52
+ const TERMINAL = new Set(['succeeded', 'failed', 'cancelled', 'interrupted']);
53
53
  /**
54
54
  * Parse an index body into records.
55
55
  *
@@ -2392,6 +2392,7 @@ export class SkillLibrary {
2392
2392
  return rollbackMessage(result.message, stuck);
2393
2393
  }
2394
2394
  }
2395
+ await this.foldArchivedUsage(sources, new Date().toISOString());
2395
2396
  await plan.onPhase?.('sources-archived');
2396
2397
  await plan.onPhase?.('unit-written');
2397
2398
  return { ok: true, message: `已把 ${sources.join(', ')} 合并进「${target}」。`, unitId, targetPath: dir, archived, mutations: 1 + sources.length };
@@ -43,7 +43,9 @@ export class UnitTransactions {
43
43
  this.now = options.now ?? (() => Date.now());
44
44
  }
45
45
  unitId(plan) {
46
- return plan.runId + ":" + createHash("sha256").update(plan.pairKey).digest("hex").slice(0, 16);
46
+ // DEC-D5: the caller may provide the unitId and still get idempotent prepare/commit.
47
+ // Deriving one remains the fallback for callers that do not.
48
+ return plan.unitId ?? plan.runId + ":" + createHash("sha256").update(plan.pairKey).digest("hex").slice(0, 16);
47
49
  }
48
50
  async snapshot(plan, unitId, planDigest) {
49
51
  const targetBefore = await this.options.backend.readSkill(plan.target);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lmzhen/dsh-evolution-core",
3
3
  "description": "Shared stores, prompts, signals and lifecycle logic for the dsh-evolution plugin family (community build)",
4
- "version": "0.30.24",
4
+ "version": "0.30.25",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -181,15 +181,6 @@
181
181
  "state": [],
182
182
  "note": "The merge rows and their persisted round-one decisions. One transaction per mutation; reads stay pure projections."
183
183
  },
184
- {
185
- "id": "merge-gate-cache",
186
- "path": "<evolutionHome>/merge/gate-cache.json",
187
- "writer": "evolution-merge/src/gate-cache.ts",
188
- "serializedBy": "transact",
189
- "marker": "transactIo(io, gateCachePath(home)",
190
- "state": [],
191
- "note": "The L0-L2 gate cache. A cache is still a durable write and goes through the same transaction seam."
192
- },
193
184
  {
194
185
  "id": "reports-retention-lock",
195
186
  "path": "<evolutionHome>/reports/.retention",