@lmzhen/dsh-evolution-core 0.30.18 → 0.30.20

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
@@ -366,6 +366,7 @@ const UNIT_JOURNAL_PHASES = [
366
366
  "source-archiving",
367
367
  "sources-archived",
368
368
  "support-pending",
369
+ "unit-written",
369
370
  "committed",
370
371
  "failed",
371
372
  "rolled-back"
@@ -1183,6 +1184,26 @@ function canonical(value) {
1183
1184
  function digest(plan) {
1184
1185
  return createHash("sha256").update(canonical(plan)).digest("hex");
1185
1186
  }
1187
+ function canonicalJson(value) {
1188
+ if (value === null || typeof value !== "object") return JSON.stringify(value);
1189
+ if (Array.isArray(value)) return "[" + value.map(canonicalJson).join(",") + "]";
1190
+ const object = value;
1191
+ return "{" + Object.keys(object).sort().map((key) => JSON.stringify(key) + ":" + canonicalJson(object[key])).join(",") + "}";
1192
+ }
1193
+ function unitEvidenceDigest(evidence) {
1194
+ return createHash("sha256").update(canonicalJson({
1195
+ ...evidence,
1196
+ at: 0,
1197
+ mutations: 0
1198
+ })).digest("hex");
1199
+ }
1200
+ function evidenceDigest(evidence) {
1201
+ return createHash("sha256").update(JSON.stringify({
1202
+ ...evidence,
1203
+ at: 0,
1204
+ mutations: 0
1205
+ }, null, 2) + "\n").digest("hex");
1206
+ }
1186
1207
  var UnitTransactions = class {
1187
1208
  options;
1188
1209
  prepared = /* @__PURE__ */ new Map();
@@ -1219,6 +1240,7 @@ var UnitTransactions = class {
1219
1240
  sourceBefore,
1220
1241
  origin: plan.origin,
1221
1242
  summary: plan.summary,
1243
+ ...plan.validationPlan === void 0 ? {} : { validationPlan: plan.validationPlan },
1222
1244
  createdAt: this.now()
1223
1245
  };
1224
1246
  }
@@ -1313,12 +1335,12 @@ var UnitTransactions = class {
1313
1335
  let lock;
1314
1336
  let claim;
1315
1337
  const checkpoints = [];
1316
- const writePhase = async (phase, checkpointsNext) => {
1338
+ const writePhase = async (phase, checkpointsNext = checkpoints) => {
1317
1339
  if (lock !== void 0 && !await lock.assertHeld()) throw new Error("unit-fence-lost");
1318
1340
  await writeUnitJournal(this.options.io, this.options.home, {
1319
1341
  ...journalBase,
1320
1342
  phase,
1321
- ...checkpointsNext === void 0 ? {} : { checkpoints: checkpointsNext }
1343
+ checkpoints: checkpointsNext
1322
1344
  });
1323
1345
  await this.options.onPhase?.(phase);
1324
1346
  };
@@ -1346,7 +1368,10 @@ var UnitTransactions = class {
1346
1368
  ...journalBase,
1347
1369
  phase: "target-pending"
1348
1370
  });
1349
- const result = await this.options.backend.commit(stored.plan, async (phase, detail) => {
1371
+ const result = await this.options.backend.commit({
1372
+ ...stored.plan,
1373
+ unitId: prepared.unitId
1374
+ }, async (phase, detail) => {
1350
1375
  if (phase === "support-pending") {
1351
1376
  await writePhase("support-pending");
1352
1377
  await this.options.onPhase?.("support-pending");
@@ -1367,7 +1392,7 @@ var UnitTransactions = class {
1367
1392
  archived: stored.plan.sources.filter((source) => source !== stored.plan.target),
1368
1393
  at: this.now()
1369
1394
  });
1370
- await this.options.onPhase?.("unit-written");
1395
+ await writePhase("unit-written");
1371
1396
  return;
1372
1397
  }
1373
1398
  if (phase === "source-archiving" && detail?.source !== void 0) checkpoints.push({
@@ -1382,7 +1407,7 @@ var UnitTransactions = class {
1382
1407
  await writePhase("failed");
1383
1408
  return {
1384
1409
  ok: false,
1385
- code: "unit-commit-failed",
1410
+ code: result.code ?? "unit-commit-failed",
1386
1411
  message: result.message
1387
1412
  };
1388
1413
  }
@@ -1407,10 +1432,22 @@ var UnitTransactions = class {
1407
1432
  absorbedInto: stored.plan.target
1408
1433
  })),
1409
1434
  mutations: result.mutations ?? 0,
1435
+ ...stored.plan.validationPlan === void 0 ? {} : { validationPlan: stored.plan.validationPlan },
1410
1436
  at: this.now()
1411
1437
  };
1412
1438
  if (!await lock.assertHeld()) throw new Error("unit-fence-lost");
1439
+ const evidenceSha256 = evidenceDigest(evidence);
1413
1440
  await writeUnitEvidence(this.options.io, this.options.home, evidence);
1441
+ await writeUnitReceipt(this.options.io, this.options.home, {
1442
+ schemaVersion: 1,
1443
+ unitId: prepared.unitId,
1444
+ runId: stored.plan.runId,
1445
+ planDigest: stored.digest,
1446
+ target: stored.plan.target,
1447
+ archived: stored.plan.sources.filter((source) => source !== stored.plan.target),
1448
+ at: this.now(),
1449
+ evidenceSha256
1450
+ });
1414
1451
  await writePhase("committed", checkpoints);
1415
1452
  this.prepared.delete(prepared.unitId);
1416
1453
  return {
@@ -1461,6 +1498,29 @@ var UnitTransactions = class {
1461
1498
  code: "unit-rollback-blocked",
1462
1499
  message: "source checkpoint missing: " + missing.map((item) => item.name).join(",")
1463
1500
  };
1501
+ const liveTarget = await this.options.backend.readSkill(snapshot.target);
1502
+ if (liveTarget === null || liveTarget !== (snapshot.targetAfter ?? null)) return {
1503
+ ok: false,
1504
+ code: "unit-rollback-blocked",
1505
+ message: "target live hash does not match the prepared target; manual recovery required"
1506
+ };
1507
+ const liveSource = (await Promise.all(snapshot.sourceBefore.map(async (source) => ({
1508
+ name: source.name,
1509
+ body: await this.options.backend.readSkill(source.name)
1510
+ })))).find((source) => source.body !== null);
1511
+ if (liveSource !== void 0) return {
1512
+ ok: false,
1513
+ code: "unit-rollback-blocked",
1514
+ message: "source is still live: " + liveSource.name
1515
+ };
1516
+ if ((await Promise.all(snapshot.supportAfter.map(async (file) => ({
1517
+ path: file.path,
1518
+ content: await this.options.backend.readSupportFile(snapshot.target, file.path)
1519
+ })))).some((file) => file.content !== (snapshot.supportAfter.find((item) => item.path === file.path)?.content ?? null))) return {
1520
+ ok: false,
1521
+ code: "unit-rollback-blocked",
1522
+ message: "support file live hash does not match the prepared support; manual recovery required"
1523
+ };
1464
1524
  const evidence = {
1465
1525
  schemaVersion: 1,
1466
1526
  unitId,
@@ -1481,8 +1541,14 @@ var UnitTransactions = class {
1481
1541
  absorbedInto: snapshot.target
1482
1542
  })),
1483
1543
  mutations: 0,
1544
+ ...snapshot.validationPlan === void 0 ? {} : { validationPlan: snapshot.validationPlan },
1484
1545
  at: this.now()
1485
1546
  };
1547
+ if (receipt?.evidenceSha256 !== void 0 && evidenceDigest(evidence) !== receipt.evidenceSha256) return {
1548
+ ok: false,
1549
+ code: "unit-rollback-blocked",
1550
+ message: "receipt evidence hash does not match rebuilt evidence"
1551
+ };
1486
1552
  await writeUnitEvidence(this.options.io, this.options.home, evidence);
1487
1553
  if (journal.phase !== "committed") await writeUnitJournal(this.options.io, this.options.home, {
1488
1554
  ...journal,
@@ -1503,7 +1569,13 @@ var UnitTransactions = class {
1503
1569
  };
1504
1570
  const snapshot = await readUnitSnapshot(this.options.io, this.options.home, unitId);
1505
1571
  const journal = await readUnitJournal(this.options.io, this.options.home, unitId);
1506
- if (snapshot === null || journal === null || journal.phase !== "target-written" && journal.phase !== "sources-archived") return {
1572
+ if (snapshot === null || journal === null || ![
1573
+ "target-written",
1574
+ "support-pending",
1575
+ "source-archiving",
1576
+ "sources-archived",
1577
+ "unit-written"
1578
+ ].includes(journal.phase)) return {
1507
1579
  ok: false,
1508
1580
  code: "unit-rollback-blocked",
1509
1581
  message: "unit is not roll-forwardable; manual recovery required"
@@ -1516,10 +1588,27 @@ var UnitTransactions = class {
1516
1588
  message: "source checkpoint missing: " + missing.map((item) => item.name).join(",")
1517
1589
  };
1518
1590
  const targetAfter = await this.options.backend.readSkill(snapshot.target);
1519
- if (targetAfter === null) return {
1591
+ if (targetAfter === null || targetAfter !== (snapshot.targetAfter ?? null)) return {
1592
+ ok: false,
1593
+ code: "unit-rollback-blocked",
1594
+ message: "target missing or drifted; manual recovery required"
1595
+ };
1596
+ const liveSource = (await Promise.all(snapshot.sourceBefore.map(async (source) => ({
1597
+ name: source.name,
1598
+ body: await this.options.backend.readSkill(source.name)
1599
+ })))).find((source) => source.body !== null);
1600
+ if (liveSource !== void 0) return {
1601
+ ok: false,
1602
+ code: "unit-rollback-blocked",
1603
+ message: "source is still live: " + liveSource.name
1604
+ };
1605
+ if ((await Promise.all(snapshot.supportAfter.map(async (file) => ({
1606
+ path: file.path,
1607
+ content: await this.options.backend.readSupportFile(snapshot.target, file.path)
1608
+ })))).some((file) => file.content !== (snapshot.supportAfter.find((item) => item.path === file.path)?.content ?? null))) return {
1520
1609
  ok: false,
1521
1610
  code: "unit-rollback-blocked",
1522
- message: "target missing; manual recovery required"
1611
+ message: "support file live hash does not match the prepared support; manual recovery required"
1523
1612
  };
1524
1613
  const evidence = {
1525
1614
  schemaVersion: 1,
@@ -1541,6 +1630,7 @@ var UnitTransactions = class {
1541
1630
  absorbedInto: snapshot.target
1542
1631
  })),
1543
1632
  mutations: 0,
1633
+ ...snapshot.validationPlan === void 0 ? {} : { validationPlan: snapshot.validationPlan },
1544
1634
  at: this.now()
1545
1635
  };
1546
1636
  await writeUnitEvidence(this.options.io, this.options.home, evidence);
@@ -1700,6 +1790,8 @@ function skillLibraryUnitBackend(skills) {
1700
1790
  },
1701
1791
  async commit(plan, onPhase, signal, assertFence) {
1702
1792
  const result = await skills.commitMerge({
1793
+ ...plan.runId === void 0 ? {} : { runId: plan.runId },
1794
+ ...plan.unitId === void 0 ? {} : { unitId: plan.unitId },
1703
1795
  target: plan.target,
1704
1796
  targetExists: plan.targetExists,
1705
1797
  sources: plan.sources,
@@ -1709,6 +1801,10 @@ function skillLibraryUnitBackend(skills) {
1709
1801
  expectedSourceBodies: plan.expectedSourceBodies,
1710
1802
  origin: plan.origin,
1711
1803
  summary: plan.summary,
1804
+ ...plan.skillLimits === void 0 ? {} : { limits: plan.skillLimits },
1805
+ ...plan.targetRevision === void 0 ? {} : { targetRevision: plan.targetRevision },
1806
+ ...plan.sourceRevisions === void 0 ? {} : { sourceRevisions: plan.sourceRevisions },
1807
+ ...plan.supportDigest === void 0 ? {} : { supportDigest: plan.supportDigest },
1712
1808
  ...onPhase === void 0 ? {} : { onPhase },
1713
1809
  ...signal === void 0 ? {} : { signal },
1714
1810
  ...assertFence === void 0 ? {} : { assertFence }
@@ -1716,6 +1812,7 @@ function skillLibraryUnitBackend(skills) {
1716
1812
  return {
1717
1813
  ok: result.ok,
1718
1814
  message: result.message,
1815
+ ...result.code === void 0 ? {} : { code: result.code },
1719
1816
  ...result.archived === void 0 ? {} : { archived: result.archived },
1720
1817
  ...result.mutations === void 0 ? {} : { mutations: result.mutations }
1721
1818
  };
@@ -6463,11 +6560,7 @@ function parseIndex(raw) {
6463
6560
  ...typeof record.resultRef === "string" ? { resultRef: record.resultRef } : {},
6464
6561
  ...typeof record.failure === "string" ? { failure: record.failure } : {},
6465
6562
  ...typeof record.supersededAt === "number" ? { supersededAt: record.supersededAt } : {},
6466
- ...typeof record.parentRunId === "string" ? { parentRunId: record.parentRunId } : {},
6467
- ...record.mergeStatus === "running" || record.mergeStatus === "succeeded" || record.mergeStatus === "failed" || record.mergeStatus === "cancelled" || record.mergeStatus === "awaiting-approval" || record.mergeStatus === "undone" || record.mergeStatus === "superseded" || record.mergeStatus === "interrupted" || record.mergeStatus === "orphan" ? { mergeStatus: record.mergeStatus } : {},
6468
- ...typeof record.stagingRef === "string" ? { stagingRef: record.stagingRef } : {},
6469
- ...typeof record.pairKey === "string" ? { pairKey: record.pairKey } : {},
6470
- ...Array.isArray(record.pairs) ? { pairs: record.pairs } : {}
6563
+ ...typeof record.parentRunId === "string" ? { parentRunId: record.parentRunId } : {}
6471
6564
  });
6472
6565
  }
6473
6566
  return {
@@ -6501,7 +6594,6 @@ function newRunRegistry(options) {
6501
6594
  const orphanOf = (row) => ({
6502
6595
  ...row,
6503
6596
  state: "failed",
6504
- mergeStatus: "orphan",
6505
6597
  endedAt: now(),
6506
6598
  failure: ORPHAN_FAILURE
6507
6599
  });
@@ -6643,8 +6735,7 @@ function newRunRegistry(options) {
6643
6735
  if (this.find(id)?.state !== "running") return false;
6644
6736
  await this.settle(id, {
6645
6737
  state: "failed",
6646
- failure: "orphan",
6647
- mergeStatus: "orphan"
6738
+ failure: "orphan"
6648
6739
  });
6649
6740
  return true;
6650
6741
  },
@@ -6661,10 +6752,6 @@ function newRunRegistry(options) {
6661
6752
  pid: process.pid,
6662
6753
  ...seed?.command !== void 0 ? { command: seed.command } : {},
6663
6754
  ...seed?.parentRunId !== void 0 ? { parentRunId: seed.parentRunId } : {},
6664
- ...seed?.mergeStatus !== void 0 ? { mergeStatus: seed.mergeStatus } : {},
6665
- ...seed?.stagingRef !== void 0 ? { stagingRef: seed.stagingRef } : {},
6666
- ...seed?.pairKey !== void 0 ? { pairKey: seed.pairKey } : {},
6667
- ...seed?.pairs !== void 0 ? { pairs: seed.pairs } : {},
6668
6755
  ...seed?.total !== void 0 ? { progress: {
6669
6756
  done: 0,
6670
6757
  total: seed.total
@@ -6696,7 +6783,6 @@ function newRunRegistry(options) {
6696
6783
  const row = owned.get(id);
6697
6784
  if (row === void 0 || row.supersededAt !== void 0) continue;
6698
6785
  row.supersededAt = now();
6699
- if (row.kind === "merge") row.mergeStatus = "superseded";
6700
6786
  changed = true;
6701
6787
  }
6702
6788
  if (changed) await persist();
@@ -6711,7 +6797,6 @@ function newRunRegistry(options) {
6711
6797
  for (const row of merged.values()) {
6712
6798
  if (row.kind !== kind || row.supersededAt !== void 0) continue;
6713
6799
  row.supersededAt = now();
6714
- if (row.kind === "merge") row.mergeStatus = "superseded";
6715
6800
  marked += 1;
6716
6801
  }
6717
6802
  const kept = capped([...merged.values()]);
@@ -6735,10 +6820,43 @@ function newRunRegistry(options) {
6735
6820
  row.endedAt = now();
6736
6821
  if (outcome.resultRef !== void 0) row.resultRef = outcome.resultRef;
6737
6822
  if (outcome.failure !== void 0) row.failure = outcome.failure;
6738
- if (outcome.mergeStatus !== void 0) row.mergeStatus = outcome.mergeStatus;
6739
6823
  controllers.delete(id);
6740
6824
  await persist();
6741
6825
  },
6826
+ async settleRecovered(id, outcome) {
6827
+ if (owned.get(id) !== void 0) {
6828
+ await this.settle(id, outcome);
6829
+ return owned.get(id)?.state === outcome.state;
6830
+ }
6831
+ let changed = false;
6832
+ await transactIo(options.io, path, (current) => {
6833
+ const onDisk = parseIndex(current);
6834
+ const row = onDisk.records.find((item) => item.id === id);
6835
+ if (row === void 0) return current;
6836
+ if (!(row.state === "running" && ownerIsGone(row) || row.state === "failed" && row.failure === ORPHAN_FAILURE)) return current;
6837
+ changed = true;
6838
+ const next = {
6839
+ ...row,
6840
+ state: outcome.state,
6841
+ endedAt: now(),
6842
+ ...outcome.resultRef === void 0 ? {} : { resultRef: outcome.resultRef },
6843
+ ...outcome.failure === void 0 ? {} : { failure: outcome.failure }
6844
+ };
6845
+ const kept = capped(onDisk.records.map((item) => item.id === id ? next : item));
6846
+ const live = kept.filter((item) => item.state === "running");
6847
+ const done = kept.filter((item) => TERMINAL.has(item.state));
6848
+ return JSON.stringify({
6849
+ schemaVersion: 2,
6850
+ runs: [
6851
+ ...live,
6852
+ ...done,
6853
+ ...onDisk.foreign
6854
+ ]
6855
+ }, null, 2);
6856
+ });
6857
+ if (changed) await this.load();
6858
+ return changed;
6859
+ },
6742
6860
  inFlight(kind) {
6743
6861
  return view().find((row) => row.state === "running" && (kind === void 0 || row.kind === kind));
6744
6862
  },
@@ -7831,7 +7949,7 @@ function renderLongRunTable() {
7831
7949
  * `client` probes run in the browser half, where the host has no view of the seats.
7832
7950
  * @module @lmzhen/dsh-evolution-core
7833
7951
  */
7834
- /** The 25 probes, in service-name order (the guard checks this list against the tree). */
7952
+ /** The 26 probes, in service-name order (the guard checks this list against the tree). */
7835
7953
  const PLATFORM_SERVICE_PROBES = Object.freeze([
7836
7954
  {
7837
7955
  service: "agents",
@@ -7870,7 +7988,7 @@ const PLATFORM_SERVICE_PROBES = Object.freeze([
7870
7988
  },
7871
7989
  {
7872
7990
  service: "evolutionMerge",
7873
- feature: "merge rows and run state",
7991
+ feature: "merge command delegation and the merge doctor fact",
7874
7992
  side: "host"
7875
7993
  },
7876
7994
  {
@@ -10017,6 +10135,54 @@ function staleRouteStubs(indexes) {
10017
10135
  return out.sort((a, b) => a.skill.localeCompare(b.skill) || a.v - b.v || a.owner.localeCompare(b.owner));
10018
10136
  }
10019
10137
  //#endregion
10138
+ //#region lib/types/skill-revision.js
10139
+ /**
10140
+ * Content-revision identity shared by every planner that records a decision and every
10141
+ * committer that re-checks it.
10142
+ *
10143
+ * A skill's revision covers the trimmed NAME, the SKILL.md body and every support file
10144
+ * (`references/…`, `templates/…`, `scripts/…`, `assets/…`), each as read through the
10145
+ * store. The merge domain records a decision-time anchor and the store compares the live
10146
+ * anchor before writing; both sides must hash the same bytes or the compare is meaningless,
10147
+ * so the hash lives HERE and nowhere else.
10148
+ */
10149
+ /**
10150
+ * Canonical fingerprint of one skill's content.
10151
+ *
10152
+ * Field order and separators are a wire format: decisions persist anchors derived from
10153
+ * this string, and a later commit compares against it. Do not reorder.
10154
+ * @param name - the (trimmed) skill name.
10155
+ * @param body - the SKILL.md text.
10156
+ * @param files - every support file under SUPPORT_DIRS.
10157
+ * @returns the fingerprint string to hash.
10158
+ */
10159
+ function revisionFingerprint(name, body, files) {
10160
+ const ordered = [...files].sort((left, right) => left.path.localeCompare(right.path));
10161
+ return name + "\0" + body + "\0" + ordered.map((file) => file.path + "\0" + file.content).join("\0");
10162
+ }
10163
+ /** Hash one fingerprint into its anchor (CRLF-normalized by contentHash). */
10164
+ function revisionAnchor(name, body, files) {
10165
+ return {
10166
+ kind: "present",
10167
+ sha256: contentHash(revisionFingerprint(name, body, files))
10168
+ };
10169
+ }
10170
+ /** Anchor for a skill whose body may be absent. */
10171
+ function revisionAnchorOf(name, body, files) {
10172
+ return body === null ? { kind: "absent" } : revisionAnchor(name, body, files);
10173
+ }
10174
+ /**
10175
+ * Support digest over several skills' fingerprints: the union of their full content.
10176
+ *
10177
+ * Sort is by fingerprint (name-prefixed), so name order and fingerprint order agree and
10178
+ * a decision-time digest can be recomputed by a committer that only has hashes.
10179
+ * @param fingerprints - one fingerprint per involved skill (missing skills simply absent).
10180
+ * @returns the digest recorded on a decision and re-checked at commit.
10181
+ */
10182
+ function revisionSupportDigest(fingerprints) {
10183
+ return contentHash([...fingerprints].sort().join("\0"));
10184
+ }
10185
+ //#endregion
10020
10186
  //#region lib/types/skill-store.js
10021
10187
  /**
10022
10188
  * Skill library management for the self-evolution plugin.
@@ -10453,6 +10619,11 @@ function serialForRoot(root) {
10453
10619
  ROOT_SERIAL.set(key, created);
10454
10620
  return created;
10455
10621
  }
10622
+ /** Same-content test for two revision anchors (absent only equals absent). */
10623
+ function sameRevisionAnchor(expected, live) {
10624
+ if (expected.kind !== live.kind) return false;
10625
+ return expected.kind === "absent" || expected.sha256 === live.sha256;
10626
+ }
10456
10627
  var SkillLibrary = class {
10457
10628
  root;
10458
10629
  limits;
@@ -10727,7 +10898,53 @@ var SkillLibrary = class {
10727
10898
  }
10728
10899
  }
10729
10900
  /**
10730
-
10901
+ * Content anchor of one live skill: name + body + every support file under SUPPORT_DIRS.
10902
+ *
10903
+ * This is the commit-side counterpart of the decision-time anchor recorded by the merge
10904
+ * domain (see skill-revision.ts): both sides call the same fingerprint, so a changed
10905
+ * source, target or support file cannot slip past the commit CAS.
10906
+ * @param rawName - caller-supplied skill name (trimmed here).
10907
+ * @returns present anchor, or absent when the skill has no SKILL.md.
10908
+ */
10909
+ async revisionFingerprint(rawName) {
10910
+ const name = rawName.trim();
10911
+ if (this.badName(name) !== null) return null;
10912
+ let body;
10913
+ try {
10914
+ body = await this.io.readText(join(this.dirOf(name), "SKILL.md"));
10915
+ } catch (error) {
10916
+ if (error?.code === "EISDIR") return null;
10917
+ throw error;
10918
+ }
10919
+ if (body === null) return null;
10920
+ return revisionFingerprint(name, body, await this.liveSupportFiles(name));
10921
+ }
10922
+ /** Content anchor of one live skill; the hash a decision records and a commit re-checks. */
10923
+ async revisionAnchor(rawName) {
10924
+ const fingerprint = await this.revisionFingerprint(rawName);
10925
+ return fingerprint === null ? { kind: "absent" } : {
10926
+ kind: "present",
10927
+ sha256: contentHash(fingerprint)
10928
+ };
10929
+ }
10930
+ /** Every support file of one live skill, in listing order; unreadable/missing files fail loud. */
10931
+ async liveSupportFiles(rawName) {
10932
+ const name = rawName.trim();
10933
+ if (this.badName(name) !== null) return [];
10934
+ const listed = await this.listSupportFiles(name);
10935
+ if (isUnknown(listed)) throw new Error("support file list is unknown: " + name);
10936
+ if (!isPresent(listed)) return [];
10937
+ const dir = this.dirOf(name);
10938
+ return await Promise.all(listed.value.map(async (path) => {
10939
+ const content = await this.io.readText(join(dir, ...path.replace(/\\/g, "/").split("/").filter(Boolean)));
10940
+ if (content === null) throw new Error("support file disappeared: " + name + "/" + path);
10941
+ return {
10942
+ path,
10943
+ content
10944
+ };
10945
+ }));
10946
+ }
10947
+ /**
10731
10948
  * Single path-building choke point (rc.42 audit P2-5): every directory path
10732
10949
 
10733
10950
  * is built from the TRIMMED name, so a name that passes `badName` (which
@@ -11026,6 +11243,16 @@ var SkillLibrary = class {
11026
11243
  if (this.badName(name) !== null) return [];
11027
11244
  return await loadVersions(this.root, this.io, name);
11028
11245
  }
11246
+ /** Versions from the latest merge baseline onward; old versions stay listable via listVersions. */
11247
+ async listBaselineVersions(rawName) {
11248
+ const versions = await this.listVersions(rawName);
11249
+ let start = -1;
11250
+ for (let index = versions.length - 1; index >= 0; index -= 1) if (versions[index]?.unitHead?.baseline === true) {
11251
+ start = index;
11252
+ break;
11253
+ }
11254
+ return start < 0 ? versions : versions.slice(start);
11255
+ }
11029
11256
  /**
11030
11257
  * One version's content, read back from the content-addressed blob store.
11031
11258
  * @param rawName - the skill's name.
@@ -11038,6 +11265,40 @@ var SkillLibrary = class {
11038
11265
  if (this.badName(name) !== null) return null;
11039
11266
  return await loadVersionContent(this.root, this.io, name, v);
11040
11267
  }
11268
+ /** Read an archived skill's human-readable reason, exact or stamped. */
11269
+ async readArchiveReason(rawName) {
11270
+ const name = rawName.trim();
11271
+ if (this.badName(name) !== null) return null;
11272
+ const archiveRoot = join(this.root, ".archive");
11273
+ const exact = await this.io.readText(join(archiveRoot, name, ".archive-reason"));
11274
+ if (exact !== null) return exact.trim();
11275
+ const entries = await this.io.list(archiveRoot).catch(() => []);
11276
+ for (const entry of [...entries].reverse()) {
11277
+ if (entry !== name && !entry.startsWith(name + "-")) continue;
11278
+ const marker = await this.io.readText(join(archiveRoot, entry, ".archive-name"));
11279
+ if (marker !== null && marker.trim() !== name) continue;
11280
+ const reason = await this.io.readText(join(archiveRoot, entry, ".archive-reason"));
11281
+ if (reason !== null) return reason.trim();
11282
+ }
11283
+ return null;
11284
+ }
11285
+ /** Read an archived skill body (SKILL.md) by its original name, exact or stamped. */
11286
+ async readArchived(rawName) {
11287
+ const name = rawName.trim();
11288
+ if (this.badName(name) !== null) return null;
11289
+ const archiveRoot = join(this.root, ".archive");
11290
+ const exact = await this.io.readText(join(archiveRoot, name, "SKILL.md"));
11291
+ if (exact !== null) return exact;
11292
+ const entries = await this.io.list(archiveRoot).catch(() => []);
11293
+ for (const entry of [...entries].reverse()) {
11294
+ if (entry !== name && !entry.startsWith(name + "-")) continue;
11295
+ const marker = await this.io.readText(join(archiveRoot, entry, ".archive-name"));
11296
+ if (marker !== null && marker.trim() !== name) continue;
11297
+ const text = await this.io.readText(join(archiveRoot, entry, "SKILL.md"));
11298
+ if (text !== null) return text;
11299
+ }
11300
+ return null;
11301
+ }
11041
11302
  /**
11042
11303
  * Pin or unpin a skill (`.pinned` marker). Pinned skills are protected from
11043
11304
  * deletion, from background-review writes, and from the lifecycle — a
@@ -11537,6 +11798,18 @@ var SkillLibrary = class {
11537
11798
  if (typeof name !== "string") return false;
11538
11799
  return name !== "" && name !== "." && name !== ".." && !name.includes("/") && !name.includes("\\") && basename(name) === name;
11539
11800
  }
11801
+ /** Mark merge-absorbed sources archived in the usage sidecar (FR-DATA-07). */
11802
+ async foldArchivedUsage(sources, at) {
11803
+ try {
11804
+ await mutateUsage(this.root, this.io, (map) => {
11805
+ for (const name of sources) {
11806
+ const record = getRecord(map, name);
11807
+ record.state = "archived";
11808
+ record.archived_at = at;
11809
+ }
11810
+ });
11811
+ } catch {}
11812
+ }
11540
11813
  async archive(rawName, options = {}, origin = this.authority.origin) {
11541
11814
  const name = rawName.trim();
11542
11815
  const badName = this.badName(name, { allowReserved: true });
@@ -11648,6 +11921,7 @@ var SkillLibrary = class {
11648
11921
  ok: false,
11649
11922
  message: `来源技能「${protectedSource}」是受保护的内置技能。`
11650
11923
  };
11924
+ const limits = plan.limits ?? this.limits;
11651
11925
  return await this.serial(async () => {
11652
11926
  const dir = this.dirOf(target);
11653
11927
  const targetPath = join(dir, "SKILL.md");
@@ -11701,7 +11975,35 @@ var SkillLibrary = class {
11701
11975
  };
11702
11976
  sourceBodies.set(source, body);
11703
11977
  }
11704
- const validation = validateFrontmatter(plan.body, target, this.limits);
11978
+ if (plan.targetRevision !== void 0) {
11979
+ const liveTargetRevision = await this.revisionAnchor(target);
11980
+ if (!sameRevisionAnchor(plan.targetRevision, liveTargetRevision)) return {
11981
+ ok: false,
11982
+ code: "target-changed",
11983
+ message: `目标技能「${target}」的内容在决策之后被改过;拒绝提交(未写入任何内容)。`
11984
+ };
11985
+ }
11986
+ if (plan.sourceRevisions !== void 0) for (const [name, expected] of Object.entries(plan.sourceRevisions)) {
11987
+ if (!sources.includes(name)) continue;
11988
+ if (!sameRevisionAnchor(expected, await this.revisionAnchor(name))) return {
11989
+ ok: false,
11990
+ code: "source-changed",
11991
+ message: `来源技能「${name}」的内容在决策之后被改过;拒绝提交(未写入任何内容)。`
11992
+ };
11993
+ }
11994
+ if (plan.supportDigest !== void 0) {
11995
+ const fingerprints = [];
11996
+ for (const name of [target, ...sources]) {
11997
+ const fingerprint = await this.revisionFingerprint(name);
11998
+ if (fingerprint !== null) fingerprints.push(fingerprint);
11999
+ }
12000
+ if (revisionSupportDigest(fingerprints) !== plan.supportDigest) return {
12001
+ ok: false,
12002
+ code: "support-changed",
12003
+ message: "参与合并的技能支撑文件在决策之后被改过;拒绝提交(未写入任何内容)。"
12004
+ };
12005
+ }
12006
+ const validation = validateFrontmatter(plan.body, target, limits);
11705
12007
  if (validation) return {
11706
12008
  ok: false,
11707
12009
  message: validation
@@ -11719,9 +12021,9 @@ var SkillLibrary = class {
11719
12021
  message: `支撑文件重复:${file.path}`
11720
12022
  };
11721
12023
  supportPaths.add(file.path);
11722
- if (Buffer.byteLength(file.content, "utf8") > this.limits.maxSkillFileBytes) return {
12024
+ if (Buffer.byteLength(file.content, "utf8") > limits.maxSkillFileBytes) return {
11723
12025
  ok: false,
11724
- message: `支撑文件超过 ${this.limits.maxSkillFileBytes} 字节:${file.path}`
12026
+ message: `支撑文件超过 ${limits.maxSkillFileBytes} 字节:${file.path}`
11725
12027
  };
11726
12028
  const threat = this.contentThreatBlock(file.content);
11727
12029
  if (threat) return {
@@ -11738,18 +12040,21 @@ var SkillLibrary = class {
11738
12040
  message: `正文引用了未提供的支撑文件「${ref}」;拒绝提交。`
11739
12041
  };
11740
12042
  }
11741
- const unitId = "u-" + Date.now().toString(36) + "-" + (nextUnitSeq += 1).toString(36);
12043
+ const unitId = plan.unitId ?? "u-" + Date.now().toString(36) + "-" + (nextUnitSeq += 1).toString(36);
12044
+ const supportMoves = plan.supportFiles.map((file) => {
12045
+ const previous = supportPrevious.get(file.path) ?? null;
12046
+ return {
12047
+ path: file.path,
12048
+ kind: previous === null ? "created" : "moved",
12049
+ to: file.path,
12050
+ ...previous === null ? {} : { beforeRef: contentHash(previous) },
12051
+ afterRef: contentHash(file.content)
12052
+ };
12053
+ });
11742
12054
  const unitHead = {
11743
- moves: plan.supportFiles.map((file) => {
11744
- const previous = supportPrevious.get(file.path) ?? null;
11745
- return {
11746
- path: file.path,
11747
- kind: previous === null ? "created" : "moved",
11748
- to: file.path,
11749
- ...previous === null ? {} : { beforeRef: contentHash(previous) },
11750
- afterRef: contentHash(file.content)
11751
- };
11752
- }),
12055
+ ...plan.runId === void 0 ? {} : { runId: plan.runId },
12056
+ baseline: true,
12057
+ moves: supportMoves,
11753
12058
  sources: [{ skill: target }, ...sources.map((source) => ({ skill: source }))]
11754
12059
  };
11755
12060
  const archived = [];
@@ -11860,6 +12165,7 @@ var SkillLibrary = class {
11860
12165
  archived.push(source);
11861
12166
  }
11862
12167
  await plan.onPhase?.("sources-archived");
12168
+ await this.foldArchivedUsage(sources, (/* @__PURE__ */ new Date()).toISOString());
11863
12169
  await plan.onPhase?.("unit-written");
11864
12170
  return {
11865
12171
  ok: true,
@@ -14653,13 +14959,18 @@ const PARAM_EXPOSURE = Object.freeze([
14653
14959
  {
14654
14960
  id: "evolution-approval.enabled",
14655
14961
  group: "deployment",
14656
- tier: "E2",
14962
+ tier: "E3",
14657
14963
  authority: "cordis",
14658
14964
  owner: "evolution-approval",
14659
- applies: "none",
14965
+ applies: "live",
14660
14966
  docAnchor: "PARAMETERS.md#deployment",
14661
- summary: "Require approval before a staged write executes.",
14662
- why: "security"
14967
+ summary: "Master approval switch: run the approval pipeline for foreground writes.",
14968
+ label: "启用批准流水线",
14969
+ hint: "关闭后前台写入不再经批准。",
14970
+ control: "switch",
14971
+ unit: "",
14972
+ values: "",
14973
+ card: "evolution-approval"
14663
14974
  },
14664
14975
  {
14665
14976
  id: "evolution-approval.stageForeground",
@@ -15516,4 +15827,4 @@ function isIgnorableEvent(event) {
15516
15827
  return classifySessionEvent(event) !== "model";
15517
15828
  }
15518
15829
  //#endregion
15519
- export { AUTHORING_DESCRIPTION_BAR, AUTHORING_SPLIT_LINE_CHARS, BASELINE_ACTION, CITATION_SUPPORT_DIRS, COMBINED_REVIEW_PLAN_PROMPT, COMBINED_REVIEW_PROMPT, COMPLETION_SKILL_REVIEW_PROMPT, CONTENT_SPLIT_HINT, COST_ASCII_TOKEN_HIGH, COST_ASCII_TOKEN_LOW, COST_CJK_TOKEN_HIGH, COST_CJK_TOKEN_LOW, CURATOR_DRY_RUN_BANNER, CURATOR_PROMPT, DEDUP_MAX_PAIR_COMPARISONS, DEDUP_SIMILARITY_THRESHOLD, DEFAULT_ADMISSION, DEFAULT_ARCHIVE_AFTER_DAYS, DEFAULT_ARCHIVE_RETENTION_POLICY, DEFAULT_CITATION_POLICY, DEFAULT_CITATION_REF_BUDGET, DEFAULT_CONSOLIDATION_FAILURES, DEFAULT_CURATOR_BOOT_GRACE_SECONDS, DEFAULT_CURATOR_INTERVAL_HOURS, DEFAULT_CURATOR_MODEL, DEFAULT_CURATOR_REVIEW_MAX_TOKENS, DEFAULT_HEALTH_THRESHOLDS, DEFAULT_MAX_OPS_PER_PLAN, DEFAULT_MEMORY_CHAR_LIMIT, DEFAULT_MEMORY_REVIEW_MODEL, DEFAULT_MIN_IDLE_HOURS, DEFAULT_MUTATION_CAP, DEFAULT_PROBE_TIMEOUT_MS, DEFAULT_REFERENCE_REWRITE_POLICY, DEFAULT_REVIEW_CONTEXT_MESSAGES, DEFAULT_REVIEW_MEMORY_INTERVAL, DEFAULT_REVIEW_MESSAGE_CHARS, DEFAULT_REVIEW_SKILL_INTERVAL, DEFAULT_REVIEW_TIMEOUT_MS, DEFAULT_RUN_RECORDS, DEFAULT_SKILL_CONTENT_CHARS, DEFAULT_SKILL_LIMITS, DEFAULT_SKILL_REVIEW_COMPLETION_MIN_TOOL_CALLS, DEFAULT_SKILL_REVIEW_MODEL, DEFAULT_SKILL_REVIEW_TRIGGER, DEFAULT_SKILL_VERSION_KEEP, DEFAULT_STALE_AFTER_DAYS, DEFAULT_SUBSTANTIVE_MIN_AGENT_CHARS, DEFAULT_SUBSTANTIVE_MIN_TOOL_CALLS, DEFAULT_SUBSTANTIVE_MIN_USER_CHARS, DEFAULT_SUPPORT_FILE_CHAR_POLICY, DEFAULT_SUPPORT_READ_TOOL_NAMES, DEFAULT_THREAT_MAX_SCAN_CHARS, DEFAULT_USER_CHAR_LIMIT, DEFAULT_WRITE_CONFIRM_MODE, DEFAULT_WRITE_CONFIRM_TIMEOUT_SECONDS, DIAGNOSTICS_FACT_KEYS, DIAGNOSTICS_RUNTIME_KEYS, DIAGNOSTICS_VIEW_SCHEMA_VERSION, DISPATCH_EVENT_TYPES, DRIFT_MAX_LINE_CHARS, DRIFT_SIGNALS_VERSION, DRIFT_SIGNAL_NOUNS, DSH_AUTHORING_STANDARDS, ENTRY_DELIMITER, EVENT_ARCHIVE_PREFIX, EVENT_LOG_RETAIN_ARCHIVES, EVENT_LOG_ROTATE_AT, EVENT_LOG_VERSION, EVOLUTION_ERRORS, EVOLUTION_PRESET_IDS, EVOLUTION_WRITE_TOOLS, EvolutionGateSet, FAMILY_SESSION_TOOL_NAMES, FORBIDDEN_CONTROL_KEYS, FUZZY_MAX_PATTERN_CHARS, FUZZY_MAX_WORK, HEALTH_STAMP_RE, HISTORY_DIR, HISTORY_INDEX_VERSION, HOOK_LINE_RE, HOST_ROUTES, INSTANCE_KEYS, KEEP_LINE_RE, LONG_RUNS, LOW_QUALITY_THRESHOLD, MAINTAINER_PRESET_ID, MAINTAIN_OUTPUT_INSTRUCTION, MAINTAIN_PROMPT, MAX_DESCRIPTION_LENGTH, MAX_REQUEST_BODY_BYTES, MAX_RESTRUCTURE_MOVES, MAX_SKILL_CONTENT_CHARS, MAX_SKILL_FILE_BYTES, MAX_SKILL_NAME_LENGTH, MAX_SUPPORT_READ_PATHS, MAX_TIMER_DELAY_MS, MEMORY_GUIDANCE_SECTION_ORDER, MEMORY_REVIEW_PROMPT, MIN_STAMP_BODY_CHARS, MODEL_SESSION_EVENT_TYPES as MODEL_SESSION_EVENTS, MODEL_SESSION_EVENT_TYPES, MUTATIONS_FILE_VERSION, MemoryStore, NAMESPACE_MIGRATIONS, NATIVE_CALL_EVENT, NATIVE_RESULT_EVENT, PARAM_ALIASES, PARAM_EXPOSURE, PARAM_GROUP_LABELS, PARAM_NAMESPACES, PATTERN_OVERLAP, PLATFORM_CATALOG_DESCRIPTION_DEFAULT, PLATFORM_ESTIMATE_CHARS_PER_TOKEN, PLATFORM_LINE, PLATFORM_SERVICE_PROBES, POLICY_STAGE_DEFAULTS, PROMPT_BUNDLE, PROMPT_BUNDLE_ID, PROMPT_BUNDLE_VERSION, PROTECTED_BUILTIN_SKILLS, PTC_DISPATCH_EVENT, PTC_DISPATCH_START_EVENT, QUALITY_WEIGHTS, READ_REQUIRED_ACTIONS, RESTRICTED_PRESET_DISPLAY, RESTRICTED_TOOLS_ROW_ID, RESTRICTOR_MODULE, RESTRUCTURE_TARGET_RE, RETENTION_FEEDBACK_KEEP_RATIO, RETENTION_FEEDBACK_MIN_CHARS, REVIEWER_PRESET_ID, RULES, RUNS_SCHEMA_VERSION, SKILLS_GUIDANCE, SKILLS_GUIDANCE_SECTION_ORDER, SKILL_ACTION_REQUIRED_FIELDS, SKILL_NAME_RE, SKILL_REVIEW_PLAN_PROMPT, SKILL_REVIEW_PROMPT, SNAPSHOT_EXTRA_NAME_RE, STORE_LEDGER, SUMMARY_DUPLICATE_HINT_THRESHOLD, SUPPORT_DIRS, SUPPORT_SPRAWL_FILES, SUPPRESSED_FILE_VERSION, SkillLibrary, TEXT_DIFF_MAX_CHARS, TEXT_DIFF_MAX_LINES, THREAT_EXEMPTION_HINT, TOKEN_ASCII_WEIGHT, TOKEN_CJK_WEIGHT, ToolDispatchNormalizer, ToolDispatchPayloadError, UNIT_JOURNAL_PHASES, UNIT_JOURNAL_SCHEMA_VERSION, UNIT_STORAGE_SCHEMA_VERSION, UNTRUSTED_LINE_BREAK, UNTRUSTED_LINE_MARK, UPSTREAM_LIMIT_CHARS_PER_TOKEN, UnitTransactions, VERSION_SUMMARY_MAX_CHARS, absentHostServices, acquireTreeWriteLock, admissionVerdict, advanceReview, affinity, ageCopyKey, allowRowCollisions, anchorVerdict, appendEvolutionEvent, applyCuratorLifecycleFields, applyCuratorMetaFields, applyNamespaceMigration, applyReferenceRewrite, asRecord, assertDispatchPayload, assertSkillsRootAliasRetired, assertUnitJournalTransition, assessStructureHealth, atomicWriteFiles, authoringFeedback, authorityFrom, backupsReachability, blobPath, bodyCost, buildCuratorRunReport, buildHealthBaseline, buildLearnPrompt, bumpPatch, bumpSupportRead, bumpUse, bumpView, callingScope, candidateSkills, canonicalWriteId, claimInstance, clampOnce, clampedNumber, classifyNamespaceMigration, classifySessionEvent, clearReviewChannel, collectReadSkillNames, computeDedupGroups, computeDriftSignals, computeLifecycleTransitions, computePrefixClusters, computeQualityScores, computeScopeView, contentHash, contentRetentionFeedback, countDispatches, countReferenceFiles, createGateSet, createSubagentChannel, daysSinceIso, declaredReportStamp, describeReferenceRewrite, diffFindings, dispatchKeyOf, dispatchStepOf, displayBodyOf, duplicateHeadings, elapsedSince, emptyRecord, entryTarget, errorText, evaluateThreat, eventsFile, evidenceKindIndex, evolutionActivityProjection, evolutionEventPayloadIssue, evolutionEvidenceProjection, evolutionHome, evolutionIoAdapter, evolutionReadsProjection, evolutionRoot, evolutionSignalsProjection, executeUnitUndo, filterUnreadSkillOps, findDriftSignal, foldCuratorFields, foldToolDispatches, foldTurnEvent, foldTurnEvents, foldUntrustedLines, frontmatterBlock, frontmatterCatalogInvalid, fuzzyPatch, getRecord, h2Sections, historyIndexFile, historyReachability, historyRoot, hostSurface, identity, idleDays, initialTurnFold, installEvolutionProjections, instanceClaimKey, instanceClaimedWriteSites, instanceHolder, isAbsent, isBookkeepingFrame, isCommittedWarning, isDeprecatedParamId, isFileShapedPath, isIgnorableEvent, isLandmark, isMissingPath, isPresent, isProcessAlive, isProgramToolName, isRecord, isReviewChannelSession, isSkillReadToolName, isSkillToolName, isUnknown, isUnreadWrite, json, landmarkVerdict, latestActivityAt, latestVersionAt, lifecycleCandidate, lintBody, lintSkill, listEventArchives, liveBool, liveEnum, liveNumber, liveString, loadMutations, loadSuppressedNames, loadUsage, loadVersionContent, loadVersions, makeSerialQueue, mapProbe, markAgentCreated, markReviewChannel, markerEntryName, memoryRoot, methodNotAllowed, missingSupportPointers, mutateUsage, mutationsFile, narrowNameMatches, nearDuplicateSummaries, newRunRegistry, newSkillLibrary, nextHistoryIndex, nodeEvolutionIo, normalizeFrontmatter, normalizeUsageRecord, normalizeVersionSummary, observeEvent, orderVersions, overlongLines, paramNamespace, paramRowId, paramSettingsId, parseCuratorNominations, parseEvolutionEvents, parseFrontmatter, parseHistoryIndex, partitionVersions, payloadText, persistedWriteSite, persistedWriteSites, pickWithPolicy, planNamespaceMigration, planReferenceRewrite, planRehoming, planUnitUndoAcross, policyStageLimits, probeAbsent, probeChannelState, probeList, probeMtime, probePresent, probeReason, probeText, probeUnknown, projectionText, protectedSkillNamesOf, readDispatchSignal, readEvolutionEvents, readEvolutionTimeline, readHistoryIndex, readJsonObject, readNumberParam, readParam, readTreeLock, readUnitEvidence, readUnitIndex, readUnitJournal, readUnitReceipt, readUnitSnapshot, readingStats, recordMutation, recordVersions, redactSecrets, referencedBlobs, registerHostRoutes, relatedSkillNames, releaseInstance, renameWithRetry, renderCuratorReportMarkdown, renderLongRunTable, reportTime, reportsReachability, reportsSweepLockTarget, resolveCitations, resolveExecOrigins, resolveOrigins, resolveParamId, resolveRootConfig, resolveSkillsRoot, resolveUnitMembers, resolveUnitMembersFromIndexes, restructureCandidates, retainEventArchives, retirementReport, reviewPrompt, runWriteGates, runsFile, saveSuppressedNames, saveUsage, scanBodyHooks, scanContentThreats, scanMemoryThreats, scanThreats, scopeOfNearestManifest, scopedPackageName, scopedProbeReport, sessionAudited, sessionEvidenceIndex, sessionLastEventTime, sessionReadNames, sessionReadSkillNames, sessionSeesFamilyTools, sessionTurnSignals, skillLibraryUnitBackend, skillReadNameOf, skillRowCells, skillStateKey, skillWriteGateContext, skillsRoot, staleRouteStubs, subagentChannelState, supportFileReadOf, supportRefs, suppressedFile, sweepReports, sweepReviewChannelSessions, textDiffFacts, tokenLineFor, transactIo, transactTaskGuard, treeLockFile, trimPatternBoundaries, unhookedSupportPointers, unitEvidencePath, unitIndexPath, unitJournalPath, unitJournalPhaseRank, unitMembersAreComplete, unitReceiptPath, unitSnapshotPath, unitSnapshotsDir, unitStorageKey, unwrapLive, updateSuppressedNames, upsertUnitIndex, usageFile, usageObserved, userSetKeys, validateFrontmatter, validateRestructureTarget, validateSupportPath, valueOr, verifyPromptBundle, versionActionKind, versionRowCells, versionSummaryPrompt, versionTarget, vocabulary, withTreeWrite, withTreeWriteLock, writeDurableTmp, writePathSymbols, writeUnitEvidence, writeUnitJournal, writeUnitReceipt, writeUnitSnapshot, yamlPlainScalarNeedsQuotes };
15830
+ export { AUTHORING_DESCRIPTION_BAR, AUTHORING_SPLIT_LINE_CHARS, BASELINE_ACTION, CITATION_SUPPORT_DIRS, COMBINED_REVIEW_PLAN_PROMPT, COMBINED_REVIEW_PROMPT, COMPLETION_SKILL_REVIEW_PROMPT, CONTENT_SPLIT_HINT, COST_ASCII_TOKEN_HIGH, COST_ASCII_TOKEN_LOW, COST_CJK_TOKEN_HIGH, COST_CJK_TOKEN_LOW, CURATOR_DRY_RUN_BANNER, CURATOR_PROMPT, DEDUP_MAX_PAIR_COMPARISONS, DEDUP_SIMILARITY_THRESHOLD, DEFAULT_ADMISSION, DEFAULT_ARCHIVE_AFTER_DAYS, DEFAULT_ARCHIVE_RETENTION_POLICY, DEFAULT_CITATION_POLICY, DEFAULT_CITATION_REF_BUDGET, DEFAULT_CONSOLIDATION_FAILURES, DEFAULT_CURATOR_BOOT_GRACE_SECONDS, DEFAULT_CURATOR_INTERVAL_HOURS, DEFAULT_CURATOR_MODEL, DEFAULT_CURATOR_REVIEW_MAX_TOKENS, DEFAULT_HEALTH_THRESHOLDS, DEFAULT_MAX_OPS_PER_PLAN, DEFAULT_MEMORY_CHAR_LIMIT, DEFAULT_MEMORY_REVIEW_MODEL, DEFAULT_MIN_IDLE_HOURS, DEFAULT_MUTATION_CAP, DEFAULT_PROBE_TIMEOUT_MS, DEFAULT_REFERENCE_REWRITE_POLICY, DEFAULT_REVIEW_CONTEXT_MESSAGES, DEFAULT_REVIEW_MEMORY_INTERVAL, DEFAULT_REVIEW_MESSAGE_CHARS, DEFAULT_REVIEW_SKILL_INTERVAL, DEFAULT_REVIEW_TIMEOUT_MS, DEFAULT_RUN_RECORDS, DEFAULT_SKILL_CONTENT_CHARS, DEFAULT_SKILL_LIMITS, DEFAULT_SKILL_REVIEW_COMPLETION_MIN_TOOL_CALLS, DEFAULT_SKILL_REVIEW_MODEL, DEFAULT_SKILL_REVIEW_TRIGGER, DEFAULT_SKILL_VERSION_KEEP, DEFAULT_STALE_AFTER_DAYS, DEFAULT_SUBSTANTIVE_MIN_AGENT_CHARS, DEFAULT_SUBSTANTIVE_MIN_TOOL_CALLS, DEFAULT_SUBSTANTIVE_MIN_USER_CHARS, DEFAULT_SUPPORT_FILE_CHAR_POLICY, DEFAULT_SUPPORT_READ_TOOL_NAMES, DEFAULT_THREAT_MAX_SCAN_CHARS, DEFAULT_USER_CHAR_LIMIT, DEFAULT_WRITE_CONFIRM_MODE, DEFAULT_WRITE_CONFIRM_TIMEOUT_SECONDS, DIAGNOSTICS_FACT_KEYS, DIAGNOSTICS_RUNTIME_KEYS, DIAGNOSTICS_VIEW_SCHEMA_VERSION, DISPATCH_EVENT_TYPES, DRIFT_MAX_LINE_CHARS, DRIFT_SIGNALS_VERSION, DRIFT_SIGNAL_NOUNS, DSH_AUTHORING_STANDARDS, ENTRY_DELIMITER, EVENT_ARCHIVE_PREFIX, EVENT_LOG_RETAIN_ARCHIVES, EVENT_LOG_ROTATE_AT, EVENT_LOG_VERSION, EVOLUTION_ERRORS, EVOLUTION_PRESET_IDS, EVOLUTION_WRITE_TOOLS, EvolutionGateSet, FAMILY_SESSION_TOOL_NAMES, FORBIDDEN_CONTROL_KEYS, FUZZY_MAX_PATTERN_CHARS, FUZZY_MAX_WORK, HEALTH_STAMP_RE, HISTORY_DIR, HISTORY_INDEX_VERSION, HOOK_LINE_RE, HOST_ROUTES, INSTANCE_KEYS, KEEP_LINE_RE, LONG_RUNS, LOW_QUALITY_THRESHOLD, MAINTAINER_PRESET_ID, MAINTAIN_OUTPUT_INSTRUCTION, MAINTAIN_PROMPT, MAX_DESCRIPTION_LENGTH, MAX_REQUEST_BODY_BYTES, MAX_RESTRUCTURE_MOVES, MAX_SKILL_CONTENT_CHARS, MAX_SKILL_FILE_BYTES, MAX_SKILL_NAME_LENGTH, MAX_SUPPORT_READ_PATHS, MAX_TIMER_DELAY_MS, MEMORY_GUIDANCE_SECTION_ORDER, MEMORY_REVIEW_PROMPT, MIN_STAMP_BODY_CHARS, MODEL_SESSION_EVENT_TYPES as MODEL_SESSION_EVENTS, MODEL_SESSION_EVENT_TYPES, MUTATIONS_FILE_VERSION, MemoryStore, NAMESPACE_MIGRATIONS, NATIVE_CALL_EVENT, NATIVE_RESULT_EVENT, PARAM_ALIASES, PARAM_EXPOSURE, PARAM_GROUP_LABELS, PARAM_NAMESPACES, PATTERN_OVERLAP, PLATFORM_CATALOG_DESCRIPTION_DEFAULT, PLATFORM_ESTIMATE_CHARS_PER_TOKEN, PLATFORM_LINE, PLATFORM_SERVICE_PROBES, POLICY_STAGE_DEFAULTS, PROMPT_BUNDLE, PROMPT_BUNDLE_ID, PROMPT_BUNDLE_VERSION, PROTECTED_BUILTIN_SKILLS, PTC_DISPATCH_EVENT, PTC_DISPATCH_START_EVENT, QUALITY_WEIGHTS, READ_REQUIRED_ACTIONS, RESTRICTED_PRESET_DISPLAY, RESTRICTED_TOOLS_ROW_ID, RESTRICTOR_MODULE, RESTRUCTURE_TARGET_RE, RETENTION_FEEDBACK_KEEP_RATIO, RETENTION_FEEDBACK_MIN_CHARS, REVIEWER_PRESET_ID, RULES, RUNS_SCHEMA_VERSION, SKILLS_GUIDANCE, SKILLS_GUIDANCE_SECTION_ORDER, SKILL_ACTION_REQUIRED_FIELDS, SKILL_NAME_RE, SKILL_REVIEW_PLAN_PROMPT, SKILL_REVIEW_PROMPT, SNAPSHOT_EXTRA_NAME_RE, STORE_LEDGER, SUMMARY_DUPLICATE_HINT_THRESHOLD, SUPPORT_DIRS, SUPPORT_SPRAWL_FILES, SUPPRESSED_FILE_VERSION, SkillLibrary, TEXT_DIFF_MAX_CHARS, TEXT_DIFF_MAX_LINES, THREAT_EXEMPTION_HINT, TOKEN_ASCII_WEIGHT, TOKEN_CJK_WEIGHT, ToolDispatchNormalizer, ToolDispatchPayloadError, UNIT_JOURNAL_PHASES, UNIT_JOURNAL_SCHEMA_VERSION, UNIT_STORAGE_SCHEMA_VERSION, UNTRUSTED_LINE_BREAK, UNTRUSTED_LINE_MARK, UPSTREAM_LIMIT_CHARS_PER_TOKEN, UnitTransactions, VERSION_SUMMARY_MAX_CHARS, absentHostServices, acquireTreeWriteLock, admissionVerdict, advanceReview, affinity, ageCopyKey, allowRowCollisions, anchorVerdict, appendEvolutionEvent, applyCuratorLifecycleFields, applyCuratorMetaFields, applyNamespaceMigration, applyReferenceRewrite, asRecord, assertDispatchPayload, assertSkillsRootAliasRetired, assertUnitJournalTransition, assessStructureHealth, atomicWriteFiles, authoringFeedback, authorityFrom, backupsReachability, blobPath, bodyCost, buildCuratorRunReport, buildHealthBaseline, buildLearnPrompt, bumpPatch, bumpSupportRead, bumpUse, bumpView, callingScope, candidateSkills, canonicalWriteId, claimInstance, clampOnce, clampedNumber, classifyNamespaceMigration, classifySessionEvent, clearReviewChannel, collectReadSkillNames, computeDedupGroups, computeDriftSignals, computeLifecycleTransitions, computePrefixClusters, computeQualityScores, computeScopeView, contentHash, contentRetentionFeedback, countDispatches, countReferenceFiles, createGateSet, createSubagentChannel, daysSinceIso, declaredReportStamp, describeReferenceRewrite, diffFindings, dispatchKeyOf, dispatchStepOf, displayBodyOf, duplicateHeadings, elapsedSince, emptyRecord, entryTarget, errorText, evaluateThreat, eventsFile, evidenceKindIndex, evolutionActivityProjection, evolutionEventPayloadIssue, evolutionEvidenceProjection, evolutionHome, evolutionIoAdapter, evolutionReadsProjection, evolutionRoot, evolutionSignalsProjection, executeUnitUndo, filterUnreadSkillOps, findDriftSignal, foldCuratorFields, foldToolDispatches, foldTurnEvent, foldTurnEvents, foldUntrustedLines, frontmatterBlock, frontmatterCatalogInvalid, fuzzyPatch, getRecord, h2Sections, historyIndexFile, historyReachability, historyRoot, hostSurface, identity, idleDays, initialTurnFold, installEvolutionProjections, instanceClaimKey, instanceClaimedWriteSites, instanceHolder, isAbsent, isBookkeepingFrame, isCommittedWarning, isDeprecatedParamId, isFileShapedPath, isIgnorableEvent, isLandmark, isMissingPath, isPresent, isProcessAlive, isProgramToolName, isRecord, isReviewChannelSession, isSkillReadToolName, isSkillToolName, isUnknown, isUnreadWrite, json, landmarkVerdict, latestActivityAt, latestVersionAt, lifecycleCandidate, lintBody, lintSkill, listEventArchives, liveBool, liveEnum, liveNumber, liveString, loadMutations, loadSuppressedNames, loadUsage, loadVersionContent, loadVersions, makeSerialQueue, mapProbe, markAgentCreated, markReviewChannel, markerEntryName, memoryRoot, methodNotAllowed, missingSupportPointers, mutateUsage, mutationsFile, narrowNameMatches, nearDuplicateSummaries, newRunRegistry, newSkillLibrary, nextHistoryIndex, nodeEvolutionIo, normalizeFrontmatter, normalizeUsageRecord, normalizeVersionSummary, observeEvent, orderVersions, overlongLines, paramNamespace, paramRowId, paramSettingsId, parseCuratorNominations, parseEvolutionEvents, parseFrontmatter, parseHistoryIndex, partitionVersions, payloadText, persistedWriteSite, persistedWriteSites, pickWithPolicy, planNamespaceMigration, planReferenceRewrite, planRehoming, planUnitUndoAcross, policyStageLimits, probeAbsent, probeChannelState, probeList, probeMtime, probePresent, probeReason, probeText, probeUnknown, projectionText, protectedSkillNamesOf, readDispatchSignal, readEvolutionEvents, readEvolutionTimeline, readHistoryIndex, readJsonObject, readNumberParam, readParam, readTreeLock, readUnitEvidence, readUnitIndex, readUnitJournal, readUnitReceipt, readUnitSnapshot, readingStats, recordMutation, recordVersions, redactSecrets, referencedBlobs, registerHostRoutes, relatedSkillNames, releaseInstance, renameWithRetry, renderCuratorReportMarkdown, renderLongRunTable, reportTime, reportsReachability, reportsSweepLockTarget, resolveCitations, resolveExecOrigins, resolveOrigins, resolveParamId, resolveRootConfig, resolveSkillsRoot, resolveUnitMembers, resolveUnitMembersFromIndexes, restructureCandidates, retainEventArchives, retirementReport, reviewPrompt, revisionAnchor, revisionAnchorOf, revisionFingerprint, revisionSupportDigest, runWriteGates, runsFile, saveSuppressedNames, saveUsage, scanBodyHooks, scanContentThreats, scanMemoryThreats, scanThreats, scopeOfNearestManifest, scopedPackageName, scopedProbeReport, sessionAudited, sessionEvidenceIndex, sessionLastEventTime, sessionReadNames, sessionReadSkillNames, sessionSeesFamilyTools, sessionTurnSignals, skillLibraryUnitBackend, skillReadNameOf, skillRowCells, skillStateKey, skillWriteGateContext, skillsRoot, staleRouteStubs, subagentChannelState, supportFileReadOf, supportRefs, suppressedFile, sweepReports, sweepReviewChannelSessions, textDiffFacts, tokenLineFor, transactIo, transactTaskGuard, treeLockFile, trimPatternBoundaries, unhookedSupportPointers, unitEvidenceDigest, unitEvidencePath, unitIndexPath, unitJournalPath, unitJournalPhaseRank, unitMembersAreComplete, unitReceiptPath, unitSnapshotPath, unitSnapshotsDir, unitStorageKey, unwrapLive, updateSuppressedNames, upsertUnitIndex, usageFile, usageObserved, userSetKeys, validateFrontmatter, validateRestructureTarget, validateSupportPath, valueOr, verifyPromptBundle, versionActionKind, versionRowCells, versionSummaryPrompt, versionTarget, vocabulary, withTreeWrite, withTreeWriteLock, writeDurableTmp, writePathSymbols, writeUnitEvidence, writeUnitJournal, writeUnitReceipt, writeUnitSnapshot, yamlPlainScalarNeedsQuotes };