@lmzhen/dsh-evolution-core 0.3.24 → 0.3.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
@@ -2332,7 +2332,10 @@ async function recordMutation(root, io, record, cap = 500) {
2332
2332
  * delta rows.
2333
2333
  *
2334
2334
  * Same contract as `install-layered.mjs` `generateAgentPreset` (the source
2335
- * install path) — installer.spec pins byte parity between the two.
2335
+ * install path) — installer.spec pins byte parity between the two, and both
2336
+ * apply the identical row-collision contract: a delta id that overlaps a
2337
+ * standard row id fails loud by default, and `DSH_EVOLUTION_ALLOW_ROW_COLLISIONS=1`
2338
+ * downgrades it to a warning that keeps both (the row mounts twice).
2336
2339
  *
2337
2340
  * Row ids are read from `- id:` lines; an id present in both fragments would
2338
2341
  * mount twice and could shadow the platform row, so it fails loud.
@@ -2343,7 +2346,8 @@ async function recordMutation(root, io, record, cap = 500) {
2343
2346
  function composePresetComposition(standardComposition, deltaComposition) {
2344
2347
  const standardIds = compositionRowIds(standardComposition);
2345
2348
  const collisions = [...compositionRowIds(deltaComposition)].filter((id) => standardIds.has(id)).sort();
2346
- if (collisions.length > 0) throw new Error(`evolution preset composition: delta rows collide with runtime standard rows: ${collisions.join(", ")}`);
2349
+ if (collisions.length > 0 && process.env.DSH_EVOLUTION_ALLOW_ROW_COLLISIONS !== "1") throw new Error(`evolution preset composition: delta rows collide with runtime standard rows: ${collisions.join(", ")}`);
2350
+ if (collisions.length > 0) console.warn(`evolution preset composition: warning — delta rows collide with standard rows (${collisions.join(", ")}); keeping both (DSH_EVOLUTION_ALLOW_ROW_COLLISIONS=1)`);
2347
2351
  return `${standardComposition.replace(/\s+$/, "")}\n\n${deltaComposition.trim()}\n`;
2348
2352
  }
2349
2353
  function compositionRowIds(composition) {
@@ -2582,8 +2586,15 @@ const DEFAULT_HEALTH_THRESHOLDS = {
2582
2586
  stampDensityPerKb: 2,
2583
2587
  churnMinPatches: 20
2584
2588
  };
2585
- /** Stamp regex shared by health assessment and the maintenance probe (single source, 011). */
2586
- const HEALTH_STAMP_RE = /\brc\.\d+\b|\b[0-9a-f]{7,40}\b|\b\d{4}-\d{2}-\d{2}(?:T[0-9:.]+Z)?\b/g;
2589
+ /**
2590
+ * Stamp regex shared by health assessment and the maintenance probe (single
2591
+ * source, 011). Two refinements over the naive form (F-320): the hex branch
2592
+ * requires at least one digit so coincidental all-letter English words
2593
+ * (`defaced`, `feedback`) are not counted as commit shas; the ISO branch
2594
+ * accepts a UTC `Z`, a numeric UTC offset (`+08:00`), or no timezone at all —
2595
+ * non-UTC timestamps used to escape detection (log-like content missed).
2596
+ */
2597
+ const HEALTH_STAMP_RE = new RegExp(String.raw`\brc\.\d+\b|\b(?=[0-9a-f]{7,40}\b)[0-9a-f]*[0-9][0-9a-f]*\b|\b\d{4}-\d{2}-\d{2}(?:T[0-9:.]+(?:Z|[+-]\d{2}:?\d{2})?)?\b`, "g");
2587
2598
  /**
2588
2599
  * Bodies below this size skip stamp-density assessment: a few dates or shas
2589
2600
  * in a short body are ordinary documentation, not log-like content. With the
@@ -3109,7 +3120,7 @@ function relatedSkillNames(content, exclude) {
3109
3120
  const raw = parsed.frontmatter["related_skills"];
3110
3121
  if (typeof raw !== "string") return [];
3111
3122
  const names = /* @__PURE__ */ new Set();
3112
- for (const match of Array.from(raw.matchAll(/[a-z0-9][a-z0-9-]*/g))) {
3123
+ for (const match of Array.from(raw.matchAll(/(?<![A-Za-z0-9_-])[a-z0-9][a-z0-9-]*(?![A-Za-z0-9_-])/g))) {
3113
3124
  const target = match[0];
3114
3125
  if (target && SKILL_NAME_RE.test(target) && target !== exclude) names.add(target);
3115
3126
  }
@@ -3853,7 +3864,7 @@ var SkillLibrary = class {
3853
3864
  const protection = await this.deleteProtection(name, options.allowBundled === void 0 ? {} : { allowBundled: options.allowBundled });
3854
3865
  if (protection) return {
3855
3866
  ok: false,
3856
- message: `Skill "${name}" is protected (${protection}).`
3867
+ message: protection === "pinned" ? `Skill "${name}" is pinned and cannot be archived. Remove the \`.pinned\` marker in its directory, then retry.` : `Skill "${name}" is protected (${protection}).`
3857
3868
  };
3858
3869
  if (options.absorbedInto) {
3859
3870
  if (options.absorbedInto.trim() === name) return {
@@ -4603,7 +4614,7 @@ var SkillLibrary = class {
4603
4614
  rootEntries = [];
4604
4615
  }
4605
4616
  for (const entry of rootEntries) {
4606
- if (entry.startsWith(".")) continue;
4617
+ if (entry === ".archive" || entry === ".backups" || entry === ".mutations.json" || entry === ".curator-suppressed.json") continue;
4607
4618
  await this.io.remove(join(this.root, entry));
4608
4619
  }
4609
4620
  const manifest = await this.readSnapshotManifest(snapshotPath);
@@ -6,7 +6,10 @@
6
6
  * delta rows.
7
7
  *
8
8
  * Same contract as `install-layered.mjs` `generateAgentPreset` (the source
9
- * install path) — installer.spec pins byte parity between the two.
9
+ * install path) — installer.spec pins byte parity between the two, and both
10
+ * apply the identical row-collision contract: a delta id that overlaps a
11
+ * standard row id fails loud by default, and `DSH_EVOLUTION_ALLOW_ROW_COLLISIONS=1`
12
+ * downgrades it to a warning that keeps both (the row mounts twice).
10
13
  *
11
14
  * Row ids are read from `- id:` lines; an id present in both fragments would
12
15
  * mount twice and could shadow the platform row, so it fails loud.
@@ -22,7 +22,14 @@ export interface SkillHealthThresholds {
22
22
  churnMinPatches: number;
23
23
  }
24
24
  export declare const DEFAULT_HEALTH_THRESHOLDS: SkillHealthThresholds;
25
- /** Stamp regex shared by health assessment and the maintenance probe (single source, 011). */
25
+ /**
26
+ * Stamp regex shared by health assessment and the maintenance probe (single
27
+ * source, 011). Two refinements over the naive form (F-320): the hex branch
28
+ * requires at least one digit so coincidental all-letter English words
29
+ * (`defaced`, `feedback`) are not counted as commit shas; the ISO branch
30
+ * accepts a UTC `Z`, a numeric UTC offset (`+08:00`), or no timezone at all —
31
+ * non-UTC timestamps used to escape detection (log-like content missed).
32
+ */
26
33
  export declare const HEALTH_STAMP_RE: RegExp;
27
34
  /**
28
35
  * Bodies below this size skip stamp-density assessment: a few dates or shas
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.3.24",
4
+ "version": "0.3.25",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },