@lmzhen/dsh-evolution-core 0.32.3 → 0.32.4

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.
Files changed (36) hide show
  1. package/README.md +5 -5
  2. package/lib/composition/index.js +2 -2
  3. package/lib/{composition-DSesmTvf.js → composition-3QFfEe56.js} +1 -1
  4. package/lib/{ensure-BuWsjPGD.js → ensure-C2tUoF5U.js} +1 -1
  5. package/lib/{errors-Br2-uUSK.js → errors-DRZ9A187.js} +1 -0
  6. package/lib/index.js +423 -113
  7. package/lib/restrictor.js +1 -1
  8. package/lib/subagent/index.js +1 -1
  9. package/lib/types/errors.d.ts +1 -0
  10. package/lib/types/errors.js +1 -0
  11. package/lib/types/index.d.ts +1 -0
  12. package/lib/types/index.js +1 -0
  13. package/lib/types/mutation-storage-adapter.d.ts +5 -2
  14. package/lib/types/mutation-storage-adapter.js +59 -22
  15. package/lib/types/mutation-unit.d.ts +2 -2
  16. package/lib/types/mutation-unit.js +18 -45
  17. package/lib/types/params.js +1 -1
  18. package/lib/types/platform-services.js +0 -1
  19. package/lib/types/session-projection.d.ts +14 -0
  20. package/lib/types/session-projection.js +12 -3
  21. package/lib/types/skill-reads.d.ts +19 -0
  22. package/lib/types/skill-reads.js +42 -2
  23. package/lib/types/skill-store.js +4 -2
  24. package/lib/types/tool-dispatch.d.ts +16 -0
  25. package/lib/types/tool-dispatch.js +42 -11
  26. package/lib/types/unit-journal.d.ts +5 -3
  27. package/lib/types/unit-journal.js +7 -6
  28. package/lib/types/unit-storage.d.ts +5 -4
  29. package/lib/types/unit-storage.js +8 -8
  30. package/lib/types/unit-transaction.js +5 -7
  31. package/lib/types/write-gates.d.ts +4 -0
  32. package/lib/types/write-gates.js +16 -1
  33. package/lib/types/write-kernel.d.ts +81 -0
  34. package/lib/types/write-kernel.js +155 -0
  35. package/package.json +2 -2
  36. package/persisted-write-inventory.json +1 -10
package/lib/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import { _ as scopedPackageName, c as MAINTAINER_PRESET_ID, d as RESTRICTED_TOOLS_ROW_ID, f as RESTRICTOR_MODULE, g as scopeOfNearestManifest, p as REVIEWER_PRESET_ID, s as EVOLUTION_PRESET_IDS, u as RESTRICTED_PRESET_DISPLAY } from "./ensure-BuWsjPGD.js";
1
+ import { _ as scopedPackageName, c as MAINTAINER_PRESET_ID, d as RESTRICTED_TOOLS_ROW_ID, f as RESTRICTOR_MODULE, g as scopeOfNearestManifest, p as REVIEWER_PRESET_ID, s as EVOLUTION_PRESET_IDS, u as RESTRICTED_PRESET_DISPLAY } from "./ensure-C2tUoF5U.js";
2
2
  import { a as methodNotAllowed, c as asRecord, i as json, l as isRecord, n as MAX_REQUEST_BODY_BYTES, o as readJsonObject, r as hostSurface, s as registerHostRoutes, t as HOST_ROUTES } from "./http-routes-D1Ty6nnh.js";
3
- import { w as allowRowCollisions } from "./composition-DSesmTvf.js";
4
- import { n as errorText, t as EVOLUTION_ERRORS } from "./errors-Br2-uUSK.js";
3
+ import { w as allowRowCollisions } from "./composition-3QFfEe56.js";
4
+ import { n as errorText, t as EVOLUTION_ERRORS } from "./errors-DRZ9A187.js";
5
5
  import { createSubagentChannel, probeChannelState, subagentChannelState } from "./subagent/index.js";
6
6
  import { createHash, randomBytes, randomUUID } from "node:crypto";
7
7
  import { basename, dirname, isAbsolute, join, relative, resolve } from "node:path";
@@ -256,11 +256,11 @@ const UNIT_STORAGE_SCHEMA_VERSION = 1;
256
256
  function unitStorageKey(unitId) {
257
257
  return createHash("sha256").update(unitId).digest("hex");
258
258
  }
259
- function unitSnapshotsDir(home) {
260
- return join(home, "merge", "unit-snapshots");
259
+ function unitSnapshotsDir(home, scope = "merge") {
260
+ return scope === "merge" ? join(home, "merge", "unit-snapshots") : join(home, "units", "skill", "snapshots");
261
261
  }
262
- function unitSnapshotPath(home, unitId) {
263
- return join(unitSnapshotsDir(home), unitStorageKey(unitId) + ".json");
262
+ function unitSnapshotPath(home, unitId, scope = "merge") {
263
+ return join(unitSnapshotsDir(home, scope), unitStorageKey(unitId) + ".json");
264
264
  }
265
265
  function unitEvidencePath(home, unitId) {
266
266
  return join(home, "merge", "units", unitStorageKey(unitId), "evidence.json");
@@ -268,15 +268,15 @@ function unitEvidencePath(home, unitId) {
268
268
  function unitIndexPath(home) {
269
269
  return join(home, "merge", "unit-index.json");
270
270
  }
271
- async function writeUnitSnapshot(io, home, snapshot) {
272
- const path = unitSnapshotPath(home, snapshot.unitId);
271
+ async function writeUnitSnapshot(io, home, snapshot, scope = "merge") {
272
+ const path = unitSnapshotPath(home, snapshot.unitId, scope);
273
273
  const content = JSON.stringify(snapshot, null, 2) + "\n";
274
274
  if (io.transact !== void 0) await io.transact(path, () => content);
275
275
  else await io.writeText(path, content);
276
276
  return path;
277
277
  }
278
- async function readUnitSnapshot(io, home, unitId) {
279
- const raw = await io.readText(unitSnapshotPath(home, unitId));
278
+ async function readUnitSnapshot(io, home, unitId, scope = "merge") {
279
+ const raw = await io.readText(unitSnapshotPath(home, unitId, scope));
280
280
  if (raw === null) return null;
281
281
  try {
282
282
  return JSON.parse(raw);
@@ -371,8 +371,8 @@ const UNIT_JOURNAL_PHASES = [
371
371
  "failed",
372
372
  "rolled-back"
373
373
  ];
374
- function unitJournalPath(home, unitId) {
375
- return join(home, "merge", "unit-journals", createHash("sha256").update(unitId).digest("hex") + ".json");
374
+ function unitJournalPath(home, unitId, scope = "merge") {
375
+ return join(scope === "merge" ? join(home, "merge", "unit-journals") : join(home, "units", "skill", "journals"), createHash("sha256").update(unitId).digest("hex") + ".json");
376
376
  }
377
377
  function unitJournalPhaseRank(phase) {
378
378
  return UNIT_JOURNAL_PHASES.indexOf(phase);
@@ -382,15 +382,15 @@ function assertUnitJournalTransition(from, to) {
382
382
  if (from === "failed" || from === "rolled-back" || from === "committed") throw new Error("unit-journal-terminal:" + from);
383
383
  if (unitJournalPhaseRank(to) <= unitJournalPhaseRank(from)) throw new Error("unit-journal-nonmonotonic:" + from + "->" + to);
384
384
  }
385
- async function writeUnitJournal(io, home, journal) {
386
- const path = unitJournalPath(home, journal.unitId);
385
+ async function writeUnitJournal(io, home, journal, scope = "merge") {
386
+ const path = unitJournalPath(home, journal.unitId, scope);
387
387
  const content = JSON.stringify(journal, null, 2) + "\n";
388
388
  if (io.transact !== void 0) await io.transact(path, () => content);
389
389
  else await io.writeText(path, content);
390
390
  return path;
391
391
  }
392
- async function readUnitJournal(io, home, unitId) {
393
- const raw = await io.readText(unitJournalPath(home, unitId));
392
+ async function readUnitJournal(io, home, unitId, scope = "merge") {
393
+ const raw = await io.readText(unitJournalPath(home, unitId, scope));
394
394
  if (raw === null) return null;
395
395
  try {
396
396
  return JSON.parse(raw);
@@ -1202,13 +1202,6 @@ function unitEvidenceDigest(evidence) {
1202
1202
  mutations: 0
1203
1203
  })).digest("hex");
1204
1204
  }
1205
- function evidenceDigest(evidence) {
1206
- return createHash("sha256").update(JSON.stringify({
1207
- ...evidence,
1208
- at: 0,
1209
- mutations: 0
1210
- }, null, 2) + "\n").digest("hex");
1211
- }
1212
1205
  var UnitTransactions = class {
1213
1206
  options;
1214
1207
  prepared = /* @__PURE__ */ new Map();
@@ -1441,7 +1434,7 @@ var UnitTransactions = class {
1441
1434
  at: this.now()
1442
1435
  };
1443
1436
  if (!await lock.assertHeld()) throw new Error("unit-fence-lost");
1444
- const evidenceSha256 = evidenceDigest(evidence);
1437
+ const evidenceSha256 = unitEvidenceDigest(evidence);
1445
1438
  await writeUnitEvidence(this.options.io, this.options.home, evidence);
1446
1439
  await writeUnitReceipt(this.options.io, this.options.home, {
1447
1440
  schemaVersion: 1,
@@ -1473,7 +1466,8 @@ var UnitTransactions = class {
1473
1466
  }
1474
1467
  async verify(ref) {
1475
1468
  if ("unitId" in ref) return await readUnitEvidence(this.options.io, this.options.home, ref.unitId);
1476
- const found = (await Promise.all([...this.prepared.keys()].map(async (id) => readUnitEvidence(this.options.io, this.options.home, id)))).filter((item) => item !== null && item.runId === ref.runId);
1469
+ const entries = (await readUnitIndex(this.options.io, this.options.home)).filter((entry) => entry.runId === ref.runId);
1470
+ const found = (await Promise.all(entries.map(async (entry) => readUnitEvidence(this.options.io, this.options.home, entry.unitId)))).filter((item) => item !== null && item.runId === ref.runId);
1477
1471
  const only = found[0];
1478
1472
  return found.length === 0 ? null : found.length === 1 ? only ?? null : found;
1479
1473
  }
@@ -1549,7 +1543,7 @@ var UnitTransactions = class {
1549
1543
  ...snapshot.validationPlan === void 0 ? {} : { validationPlan: snapshot.validationPlan },
1550
1544
  at: this.now()
1551
1545
  };
1552
- if (receipt?.evidenceSha256 !== void 0 && evidenceDigest(evidence) !== receipt.evidenceSha256) return {
1546
+ if (receipt?.evidenceSha256 !== void 0 && unitEvidenceDigest(evidence) !== receipt.evidenceSha256) return {
1553
1547
  ok: false,
1554
1548
  code: "unit-rollback-blocked",
1555
1549
  message: "receipt evidence hash does not match rebuilt evidence"
@@ -1946,6 +1940,7 @@ function skillWriteGateContext(services, request) {
1946
1940
  origin: request.origin,
1947
1941
  protectedNames: protectedSkillNamesOf(services.policy),
1948
1942
  readNames: services.readNames,
1943
+ ...services.readSupportFiles === void 0 ? {} : { readSupportFiles: services.readSupportFiles },
1949
1944
  confirm: services.confirm,
1950
1945
  ...services.confirmMode === void 0 ? {} : { confirmMode: services.confirmMode },
1951
1946
  ...services.confirmTimeoutSeconds === void 0 ? {} : { confirmTimeoutSeconds: services.confirmTimeoutSeconds },
@@ -1974,6 +1969,7 @@ function gateArgsOf(args) {
1974
1969
  action: typeof action === "string" ? action : void 0,
1975
1970
  name: typeof name === "string" ? name : "",
1976
1971
  absorbedInto: typeof absorbedInto === "string" && absorbedInto.trim() !== "" ? absorbedInto : void 0,
1972
+ filePath: typeof scalars.file_path === "string" && scalars.file_path.trim() !== "" ? scalars.file_path.replace(/\\/g, "/").replace(/^\.\//, "") : void 0,
1977
1973
  scalars
1978
1974
  };
1979
1975
  }
@@ -2018,13 +2014,19 @@ const GATES = [
2018
2014
  {
2019
2015
  id: "read-before-write",
2020
2016
  appliesTo: ["admission"],
2021
- run: ({ view, origin, readNames, warn }) => {
2017
+ run: ({ view, origin, readNames, readSupportFiles, warn }) => {
2022
2018
  if (origin === "foreground") return null;
2023
2019
  if (readNames === void 0) {
2024
2020
  warn("skill_manage: the read-before-write check could not run for this call — the session log is not readable here, so the write is allowed.");
2025
2021
  return null;
2026
2022
  }
2027
2023
  if (view.action === void 0) return null;
2024
+ if ((view.action === "write_file" || view.action === "remove_file") && view.filePath !== void 0) if (readSupportFiles === void 0) warn("skill_manage: the support-file read check could not run for this call — no support-file read evidence; the write is allowed.");
2025
+ else if (readSupportFiles.get(view.name)?.has(view.filePath) === true) return null;
2026
+ else return errorText("e-326-support-write-without-a-read", {
2027
+ a1: view.name,
2028
+ a2: view.filePath
2029
+ });
2028
2030
  if (!isUnreadWrite({
2029
2031
  action: view.action,
2030
2032
  name: view.name
@@ -9165,11 +9167,6 @@ const PLATFORM_SERVICE_PROBES = Object.freeze([
9165
9167
  feature: "the state facade behind activity and replay",
9166
9168
  side: "host"
9167
9169
  },
9168
- {
9169
- service: "evolutionStateStore",
9170
- feature: "generic durable state store for assignment queue and future collections",
9171
- side: "host"
9172
- },
9173
9170
  {
9174
9171
  service: "llm",
9175
9172
  feature: "the curator one-shot review model call",
@@ -9905,9 +9902,8 @@ function parsedArguments(signal) {
9905
9902
  if (parsed === null || typeof parsed !== "object") return null;
9906
9903
  return parsed;
9907
9904
  }
9908
- /** The path-shaped argument of a file tool, when it carries one. */
9909
- function readPathArgument(signal) {
9910
- const record = parsedArguments(signal);
9905
+ /** The path-shaped argument of one already-parsed call, when it carries one. */
9906
+ function readPathFromRecord(record) {
9911
9907
  if (record === null) return null;
9912
9908
  for (const key of [
9913
9909
  "file_path",
@@ -9920,6 +9916,20 @@ function readPathArgument(signal) {
9920
9916
  }
9921
9917
  return null;
9922
9918
  }
9919
+ /** The path-shaped argument of a file tool, when it carries one. */
9920
+ function readPathArgument(signal) {
9921
+ return readPathFromRecord(parsedArguments(signal));
9922
+ }
9923
+ /** The path one dispatch names, for the read-evidence projection. */
9924
+ function dispatchPathOf(step) {
9925
+ let parsed = step.arguments;
9926
+ if (typeof parsed === "string") try {
9927
+ parsed = JSON.parse(parsed);
9928
+ } catch {
9929
+ return null;
9930
+ }
9931
+ return parsed !== null && typeof parsed === "object" ? readPathFromRecord(parsed) : null;
9932
+ }
9923
9933
  /**
9924
9934
  * Read one dispatch as a SUPPORT-FILE read attributed to a skill: a read of
9925
9935
  * `<root>/<skill>/<support dir>/…` is demand evidence for that one file, the
@@ -9930,11 +9940,8 @@ function readPathArgument(signal) {
9930
9940
  * @returns the skill name and the skill-root-relative path, or `null` when the
9931
9941
  * dispatch is not a support-file read. Pure: no IO, no service lookup.
9932
9942
  */
9933
- function supportFileReadOf(signal, options) {
9934
- if (!options.toolNames.includes(signal.name)) return null;
9935
- if (signal.ok === false) return null;
9936
- const raw = readPathArgument(signal);
9937
- if (raw === null) return null;
9943
+ /** Attribute one raw path string to a skill support file (pure; no IO). */
9944
+ function supportFileReadFromPath(raw, options) {
9938
9945
  const normalized = raw.replace(/\\/g, "/").trim();
9939
9946
  if (normalized === "" || normalized.split("/").includes("..")) return null;
9940
9947
  const root = options.root.replace(/\\/g, "/").replace(/\/+$/, "");
@@ -9959,6 +9966,12 @@ function supportFileReadOf(signal, options) {
9959
9966
  rel: parts.slice(1).join("/")
9960
9967
  };
9961
9968
  }
9969
+ function supportFileReadOf(signal, options) {
9970
+ if (!options.toolNames.includes(signal.name)) return null;
9971
+ if (signal.ok === false) return null;
9972
+ const raw = readPathArgument(signal);
9973
+ return raw === null ? null : supportFileReadFromPath(raw, options);
9974
+ }
9962
9975
  function skillReadNameOf(signal) {
9963
9976
  if (!SKILL_READ_TOOL_NAMES.has(signal.name)) return void 0;
9964
9977
  if (signal.ok === false) return void 0;
@@ -9989,6 +10002,18 @@ function collectReadSkillNames(events) {
9989
10002
  }
9990
10003
  return names;
9991
10004
  }
10005
+ /** Every skill support file this log read through a non-failed configured file tool. */
10006
+ function collectReadSupportFiles(events, options) {
10007
+ const reads = /* @__PURE__ */ new Map();
10008
+ for (const signal of foldToolDispatches(events)) {
10009
+ const hit = supportFileReadOf(signal, options);
10010
+ if (hit === null) continue;
10011
+ const set = reads.get(hit.skill) ?? /* @__PURE__ */ new Set();
10012
+ set.add(hit.rel);
10013
+ reads.set(hit.skill, set);
10014
+ }
10015
+ return reads;
10016
+ }
9992
10017
  /** Tool names that touch the skill library at all — the review's skill-signal set. */
9993
10018
  const SKILL_TOOL_NAMES = new Set([...SKILL_READ_TOOL_NAMES, "skill_manage"]);
9994
10019
  /**
@@ -10386,7 +10411,9 @@ const projectionHistorySchema = z.object({
10386
10411
  const readsStateSchema = z.object({ reads: z.array(z.object({
10387
10412
  key: z.string(),
10388
10413
  skill: z.string().nullable(),
10389
- failed: z.boolean()
10414
+ failed: z.boolean(),
10415
+ file: z.string().nullable().optional(),
10416
+ tool: z.string().optional()
10390
10417
  }).strict()) }).strict();
10391
10418
  const signalsStateSchema = z.object({
10392
10419
  through: z.number().int().min(-1).max(Number.MAX_SAFE_INTEGER),
@@ -10461,12 +10488,22 @@ const evolutionReadsProjection = {
10461
10488
  reads[at] = {
10462
10489
  key: entry.key,
10463
10490
  skill: entry.skill,
10464
- failed
10491
+ failed,
10492
+ ...entry.file === void 0 ? {} : { file: entry.file },
10493
+ ...entry.tool === void 0 ? {} : { tool: entry.tool }
10465
10494
  };
10466
10495
  return { reads };
10467
10496
  };
10468
10497
  if (step.name === "") return settled();
10469
10498
  if (at >= 0) return settled();
10499
+ const file = dispatchPathOf(step);
10500
+ if (file !== null) return { reads: [...state.reads.slice(-511), {
10501
+ key: step.key,
10502
+ skill: null,
10503
+ failed: step.outcome?.ok === false,
10504
+ file,
10505
+ tool: step.name
10506
+ }] };
10470
10507
  if (!isSkillReadToolName(step.name)) return state;
10471
10508
  const skill = skillReadNameOf({
10472
10509
  kind: step.kind,
@@ -10642,6 +10679,45 @@ function sessionReadSkillNames(ctx, session) {
10642
10679
  const events = session.readEvents?.();
10643
10680
  return events === void 0 ? void 0 : collectReadSkillNames(events);
10644
10681
  }
10682
+ /**
10683
+ * Skill support files ONE session read through a non-failed file tool (P2-27).
10684
+ *
10685
+ * platform-declaration anchor: `sessionProjections` is declared by
10686
+ * `@deepseek-ai/dsh-session-projection` (its registry; capability-probed here).
10687
+ * Same two readers as {@link sessionReadSkillNames}: the family projection first,
10688
+ * then the structural log view. `undefined` means "no evidence", not "nothing was
10689
+ * read" - the write gate then keeps its fail-open posture.
10690
+ * @param ctx - a context of the runtime.
10691
+ * @param session - the session whose reads are wanted.
10692
+ * @param options - the skills root and the configured file-tool names.
10693
+ * @returns skill -> set of skill-root-relative support paths.
10694
+ */
10695
+ function sessionReadSupportFiles(ctx, session, options) {
10696
+ if (session === void 0) return void 0;
10697
+ if (isProjectableSession(session)) {
10698
+ installEvolutionProjections(ctx);
10699
+ const state = ctx.get("sessionProjections")?.stateOf(session, "evolutionReads");
10700
+ if (state !== void 0) {
10701
+ const toolNames = options.toolNames ?? DEFAULT_SUPPORT_READ_TOOL_NAMES;
10702
+ const reads = /* @__PURE__ */ new Map();
10703
+ for (const entry of state.reads) {
10704
+ if (entry.failed || typeof entry.file !== "string") continue;
10705
+ if (entry.tool !== void 0 && !toolNames.includes(entry.tool)) continue;
10706
+ const hit = supportFileReadFromPath(entry.file, { root: options.root });
10707
+ if (hit === null) continue;
10708
+ const set = reads.get(hit.skill) ?? /* @__PURE__ */ new Set();
10709
+ set.add(hit.rel);
10710
+ reads.set(hit.skill, set);
10711
+ }
10712
+ return reads;
10713
+ }
10714
+ }
10715
+ const events = session.readEvents?.();
10716
+ return events === void 0 ? void 0 : collectReadSupportFiles(events, {
10717
+ toolNames: options.toolNames ?? DEFAULT_SUPPORT_READ_TOOL_NAMES,
10718
+ root: options.root
10719
+ });
10720
+ }
10645
10721
  /** Actions whose target must have been read first (create is authorship, so it is exempt). */
10646
10722
  const READ_REQUIRED_ACTIONS = Object.freeze([
10647
10723
  "edit",
@@ -11258,6 +11334,211 @@ function staleRouteStubs(indexes) {
11258
11334
  return out.sort((a, b) => a.skill.localeCompare(b.skill) || a.v - b.v || a.owner.localeCompare(b.owner));
11259
11335
  }
11260
11336
  //#endregion
11337
+ //#region lib/types/write-kernel.js
11338
+ /**
11339
+ * The family's single write primitive: compare the baseline INSIDE the write
11340
+ * transaction, never overwrite a concurrent value, and compensate only this
11341
+ * unit's own writes. Business state machines stay in their domain owners.
11342
+ */
11343
+ var WriteKernel = class {
11344
+ io;
11345
+ transact;
11346
+ now;
11347
+ constructor(options) {
11348
+ this.io = options.io;
11349
+ this.transact = options.transact;
11350
+ this.now = options.now ?? Date.now;
11351
+ }
11352
+ /** @returns the current time source; exposed for adapters that stamp evidence. */
11353
+ clock() {
11354
+ return this.now();
11355
+ }
11356
+ /**
11357
+ * Run a read-modify-write task inside the same transaction seam. Unlike
11358
+ * writeOne, task errors keep their type (state files rely on WRITE_GATE_ERROR_NAME)
11359
+ * and only committed-only failures become warnings. expected is optional because
11360
+ * the state medium passes the task the locked current value itself.
11361
+ */
11362
+ async run(target, task) {
11363
+ let invoked = false;
11364
+ let conflict = false;
11365
+ const invoke = async (current) => {
11366
+ if (target.expected !== void 0 && current !== target.expected) {
11367
+ conflict = true;
11368
+ throw Object.assign(/* @__PURE__ */ new Error("concurrent modification detected: " + target.path), { noWrite: true });
11369
+ }
11370
+ invoked = true;
11371
+ return await task(current);
11372
+ };
11373
+ try {
11374
+ if (this.transact !== void 0) await this.transact(this.io, target.path, invoke);
11375
+ else if (this.io.transact !== void 0) await this.io.transact(target.path, invoke);
11376
+ else {
11377
+ const current = await this.io.readText(target.path);
11378
+ const next = await invoke(current);
11379
+ if (next === null && current !== null) await this.io.remove(target.path);
11380
+ else if (next !== null && next !== current) await this.io.writeText(target.path, next);
11381
+ }
11382
+ } catch (error) {
11383
+ if (conflict) throw Object.assign(/* @__PURE__ */ new Error("concurrent modification detected: " + target.path), { noWrite: true });
11384
+ if (isCommittedWarning(error)) return { warnings: [error instanceof Error ? error.message : String(error)] };
11385
+ throw error;
11386
+ }
11387
+ if (!invoked) throw new Error("internal error: the write transaction for " + target.path + " did not invoke the task; no write was performed");
11388
+ return {};
11389
+ }
11390
+ /**
11391
+ * Write one target only if the current bytes still equal the baseline.
11392
+ * A conflict performs no write. With guardBaseline:false a stale callback
11393
+ * defers (returns the current bytes) so a retrying transact can re-observe;
11394
+ * if no retry ever writes, the result is still a conflict.
11395
+ */
11396
+ async writeOne(target, options = {}) {
11397
+ const guard = options.guardBaseline !== false;
11398
+ let wrote = false;
11399
+ let deferred = false;
11400
+ let conflict = false;
11401
+ const task = (current) => {
11402
+ if (current !== target.expected) {
11403
+ if (guard) {
11404
+ conflict = true;
11405
+ throw Object.assign(/* @__PURE__ */ new Error("concurrent modification detected: " + target.path), { noWrite: true });
11406
+ }
11407
+ deferred = true;
11408
+ return current;
11409
+ }
11410
+ wrote = true;
11411
+ return target.next;
11412
+ };
11413
+ try {
11414
+ if (this.transact !== void 0) await this.transact(this.io, target.path, task);
11415
+ else if (this.io.transact !== void 0) await this.io.transact(target.path, task);
11416
+ else {
11417
+ const current = await this.io.readText(target.path);
11418
+ const next = task(current);
11419
+ if (next === null && current !== null) await this.io.remove(target.path);
11420
+ else if (next !== null && next !== current) await this.io.writeText(target.path, next);
11421
+ }
11422
+ } catch (error) {
11423
+ if (conflict) return {
11424
+ ok: false,
11425
+ changed: [],
11426
+ errors: [{
11427
+ code: "cas-conflict",
11428
+ message: error instanceof Error ? error.message : String(error),
11429
+ target: target.path
11430
+ }]
11431
+ };
11432
+ if (isCommittedWarning(error)) return {
11433
+ ok: true,
11434
+ changed: [target.path],
11435
+ errors: [],
11436
+ warnings: [error instanceof Error ? error.message : String(error)]
11437
+ };
11438
+ return {
11439
+ ok: false,
11440
+ changed: [],
11441
+ errors: [{
11442
+ code: "write-failed",
11443
+ message: error instanceof Error ? error.message : String(error),
11444
+ target: target.path
11445
+ }]
11446
+ };
11447
+ }
11448
+ if (conflict || !wrote && deferred) return {
11449
+ ok: false,
11450
+ changed: [],
11451
+ errors: [{
11452
+ code: "cas-conflict",
11453
+ message: "concurrent modification detected: " + target.path,
11454
+ target: target.path
11455
+ }]
11456
+ };
11457
+ if (!wrote) return {
11458
+ ok: false,
11459
+ changed: [],
11460
+ errors: [{
11461
+ code: "write-failed",
11462
+ message: "transaction did not invoke the write task: " + target.path,
11463
+ target: target.path
11464
+ }]
11465
+ };
11466
+ return {
11467
+ ok: true,
11468
+ changed: [target.path],
11469
+ errors: []
11470
+ };
11471
+ }
11472
+ /**
11473
+ * Write a plan in order. A preflight drift writes nothing; a later failure
11474
+ * compensates only the targets this commit wrote, and only while they still
11475
+ * hold this commit's bytes.
11476
+ */
11477
+ async commit(targets) {
11478
+ for (const target of targets) if (await this.io.readText(target.path) !== target.expected) return {
11479
+ ok: false,
11480
+ changed: [],
11481
+ errors: [{
11482
+ code: "cas-conflict",
11483
+ message: "target changed after plan: " + target.path,
11484
+ target: target.path
11485
+ }]
11486
+ };
11487
+ const written = [];
11488
+ for (const target of targets) {
11489
+ const result = await this.writeOne(target);
11490
+ if (!result.ok) {
11491
+ const compensation = await this.compensate(written);
11492
+ return {
11493
+ ok: false,
11494
+ changed: written.map((item) => item.path),
11495
+ errors: [...result.errors, ...compensation]
11496
+ };
11497
+ }
11498
+ written.push(target);
11499
+ }
11500
+ return {
11501
+ ok: true,
11502
+ changed: written.map((item) => item.path),
11503
+ errors: []
11504
+ };
11505
+ }
11506
+ /**
11507
+ * Restore a target to its before bytes only if it still holds the bytes this
11508
+ * unit wrote. A concurrent writer wins and the compensation is reported.
11509
+ */
11510
+ async restore(target) {
11511
+ const result = await this.writeOne({
11512
+ path: target.path,
11513
+ expected: target.after,
11514
+ next: target.before
11515
+ });
11516
+ if (result.ok) return result;
11517
+ if (result.errors.some((error) => error.code === "cas-conflict")) return {
11518
+ ok: false,
11519
+ changed: [],
11520
+ errors: [{
11521
+ code: "compensation-blocked",
11522
+ message: "compensation refused: target changed after this unit; leave the concurrent bytes in place",
11523
+ target: target.path
11524
+ }]
11525
+ };
11526
+ return result;
11527
+ }
11528
+ async compensate(written) {
11529
+ const errors = [];
11530
+ for (const target of [...written].reverse()) {
11531
+ const result = await this.restore({
11532
+ path: target.path,
11533
+ before: target.expected,
11534
+ after: target.next
11535
+ });
11536
+ if (!result.ok) errors.push(...result.errors);
11537
+ }
11538
+ return errors;
11539
+ }
11540
+ };
11541
+ //#endregion
11261
11542
  //#region lib/types/mutation-unit.js
11262
11543
  function underRoot(rootDir, target) {
11263
11544
  if (rootDir === void 0 || rootDir === "") return false;
@@ -11393,7 +11674,7 @@ var MutationUnit = class {
11393
11674
  snapshots;
11394
11675
  hooks;
11395
11676
  validateWrite;
11396
- transact;
11677
+ kernel;
11397
11678
  transactGuard;
11398
11679
  now;
11399
11680
  constructor(options) {
@@ -11405,9 +11686,14 @@ var MutationUnit = class {
11405
11686
  this.snapshots = options.snapshots;
11406
11687
  this.hooks = options.hooks;
11407
11688
  this.validateWrite = options.validateWrite;
11408
- this.transact = options.transact;
11409
- this.transactGuard = options.transactGuard ?? true;
11689
+ this.transactGuard = options.transactGuard !== false;
11410
11690
  this.now = options.now ?? Date.now;
11691
+ const transact = options.transact;
11692
+ this.kernel = new WriteKernel({
11693
+ io: this.io,
11694
+ ...transact === void 0 ? {} : { transact },
11695
+ now: this.now
11696
+ });
11411
11697
  }
11412
11698
  preview(request) {
11413
11699
  const validation = validateMutationRequest(request, this.limits);
@@ -11482,6 +11768,7 @@ var MutationUnit = class {
11482
11768
  snapshots.push({
11483
11769
  target: op.target,
11484
11770
  before: current,
11771
+ after: op.kind === "write" ? op.content : null,
11485
11772
  baseline
11486
11773
  });
11487
11774
  }
@@ -11527,7 +11814,8 @@ var MutationUnit = class {
11527
11814
  const snapshot = snapshots.find((entry) => entry.target === op.target);
11528
11815
  if (snapshot === void 0) throw new Error("snapshot missing for " + op.target);
11529
11816
  try {
11530
- await this.applyOp(op, snapshot.baseline);
11817
+ const opWarnings = await this.applyOp(op, snapshot.baseline);
11818
+ warnings.push(...opWarnings);
11531
11819
  changed.push(op.target);
11532
11820
  } catch (error) {
11533
11821
  if (error?.noWrite !== true) changed.push(op.target);
@@ -11542,13 +11830,6 @@ var MutationUnit = class {
11542
11830
  target: primary,
11543
11831
  roots: validation.roots.map((root) => root.name)
11544
11832
  }));
11545
- await bestEffort(async () => this.journal?.write({
11546
- unitId,
11547
- phase: "committed",
11548
- changed,
11549
- target: primary,
11550
- roots: validation.roots.map((root) => root.name)
11551
- }));
11552
11833
  if (this.snapshots !== void 0) await bestEffort(() => this.snapshots.write({
11553
11834
  unitId,
11554
11835
  state: "committed",
@@ -11556,6 +11837,13 @@ var MutationUnit = class {
11556
11837
  ...cleanup,
11557
11838
  createdAt: this.now()
11558
11839
  }));
11840
+ await bestEffort(async () => this.journal?.write({
11841
+ unitId,
11842
+ phase: "committed",
11843
+ changed,
11844
+ target: primary,
11845
+ roots: validation.roots.map((root) => root.name)
11846
+ }));
11559
11847
  try {
11560
11848
  await this.hooks?.committed?.({
11561
11849
  unitId,
@@ -11861,38 +12149,24 @@ var MutationUnit = class {
11861
12149
  });
11862
12150
  }
11863
12151
  async applyOp(op, baseline) {
11864
- if (this.transact !== void 0 && op.kind === "write") {
11865
- let ran = false;
11866
- await this.transact(this.io, op.target, () => {
11867
- ran = true;
11868
- return op.content;
11869
- });
11870
- if (!ran) throw new Error("internal error: the write transaction did not invoke the task; no write was performed");
11871
- return;
11872
- }
11873
- const next = op.kind === "delete" ? null : op.content;
11874
- if (this.io.transact !== void 0) {
11875
- let conflict = false;
11876
- let wrote = false;
11877
- await this.io.transact(op.target, (current) => {
11878
- if (current !== baseline) {
11879
- if (this.transactGuard) throw new Error("concurrent modification detected: " + op.target);
11880
- conflict = true;
11881
- return current;
11882
- }
11883
- wrote = true;
11884
- return next;
11885
- });
11886
- if (conflict && !wrote) throw Object.assign(/* @__PURE__ */ new Error("concurrent modification detected: " + op.target), { noWrite: true });
11887
- return;
11888
- }
11889
- if (await this.io.readText(op.target) !== baseline) throw new Error("concurrent modification detected: " + op.target);
11890
- if (next === null) await this.io.remove(op.target);
11891
- else await this.io.writeText(op.target, next);
12152
+ const result = await this.kernel.writeOne({
12153
+ path: op.target,
12154
+ expected: baseline,
12155
+ next: op.kind === "delete" ? null : op.content,
12156
+ ...op.skill === void 0 ? {} : { skill: op.skill }
12157
+ }, { guardBaseline: this.transactGuard });
12158
+ if (!result.ok) throw Object.assign(new Error(result.errors[0]?.message ?? "write failed: " + op.target), { noWrite: true });
12159
+ return [...result.warnings ?? []];
11892
12160
  }
11893
12161
  async rollback(snapshots) {
11894
- for (const snapshot of [...snapshots].reverse()) if (snapshot.before === null) await this.io.remove(snapshot.target);
11895
- else await this.io.writeText(snapshot.target, snapshot.before);
12162
+ for (const snapshot of [...snapshots].reverse()) {
12163
+ const result = await this.kernel.restore({
12164
+ path: snapshot.target,
12165
+ before: snapshot.before,
12166
+ after: snapshot.after
12167
+ });
12168
+ if (!result.ok) throw new Error(result.errors[0]?.message ?? "rollback failed: " + snapshot.target);
12169
+ }
11896
12170
  }
11897
12171
  };
11898
12172
  function parseFileLock(raw) {
@@ -12079,10 +12353,10 @@ function unitSnapshotPort(io, home) {
12079
12353
  after: op.after,
12080
12354
  ...op.skill === void 0 ? {} : { skill: op.skill }
12081
12355
  }))
12082
- });
12356
+ }, "skill");
12083
12357
  },
12084
12358
  async read(unitId) {
12085
- const snapshot = await readUnitSnapshot(io, home, unitId);
12359
+ const snapshot = await readUnitSnapshot(io, home, unitId, "skill") ?? await readUnitSnapshot(io, home, unitId);
12086
12360
  if (snapshot === null || snapshot.kind !== "tree-change" || snapshot.ops === void 0) return null;
12087
12361
  return {
12088
12362
  unitId,
@@ -12093,31 +12367,63 @@ function unitSnapshotPort(io, home) {
12093
12367
  };
12094
12368
  },
12095
12369
  async listPrepared() {
12096
- const names = await io.list(unitSnapshotsDir(home));
12097
12370
  const out = [];
12098
- for (const name of names) {
12099
- if (!name.endsWith(".json")) continue;
12100
- const raw = await io.readText(join(unitSnapshotsDir(home), name));
12101
- if (raw === null) continue;
12102
- let snapshot;
12103
- try {
12104
- snapshot = JSON.parse(raw);
12105
- } catch {
12106
- continue;
12371
+ const seen = /* @__PURE__ */ new Set();
12372
+ for (const dir of [unitSnapshotsDir(home, "skill"), unitSnapshotsDir(home)]) {
12373
+ const names = await io.list(dir);
12374
+ for (const name of names) {
12375
+ if (!name.endsWith(".json")) continue;
12376
+ const raw = await io.readText(join(dir, name));
12377
+ if (raw === null) continue;
12378
+ let snapshot;
12379
+ try {
12380
+ snapshot = JSON.parse(raw);
12381
+ } catch {
12382
+ continue;
12383
+ }
12384
+ if (snapshot.kind !== "tree-change" || snapshot.mutationState !== "prepared" || snapshot.ops === void 0) continue;
12385
+ if (seen.has(snapshot.unitId)) continue;
12386
+ seen.add(snapshot.unitId);
12387
+ out.push({
12388
+ unitId: snapshot.unitId,
12389
+ state: "prepared",
12390
+ ops: snapshot.ops,
12391
+ ...snapshot.cleanup === void 0 ? {} : { cleanup: snapshot.cleanup },
12392
+ createdAt: snapshot.createdAt
12393
+ });
12107
12394
  }
12108
- if (snapshot.kind !== "tree-change" || snapshot.mutationState !== "prepared" || snapshot.ops === void 0) continue;
12109
- out.push({
12110
- unitId: snapshot.unitId,
12111
- state: "prepared",
12112
- ops: snapshot.ops,
12113
- ...snapshot.cleanup === void 0 ? {} : { cleanup: snapshot.cleanup },
12114
- createdAt: snapshot.createdAt
12115
- });
12116
12395
  }
12117
12396
  return out;
12118
12397
  }
12119
12398
  };
12120
12399
  }
12400
+ /** Keep a bounded number of terminal tree-change snapshots; prepared units are never pruned. */
12401
+ async function pruneTreeChangeUnits(io, home, keep = 500) {
12402
+ if (!Number.isInteger(keep) || keep < 1) return 0;
12403
+ const dir = unitSnapshotsDir(home, "skill");
12404
+ const names = await io.list(dir);
12405
+ const terminal = [];
12406
+ for (const name of names) {
12407
+ if (!name.endsWith(".json")) continue;
12408
+ try {
12409
+ const snapshot = JSON.parse(await io.readText(join(dir, name)) ?? "");
12410
+ if (snapshot.kind !== "tree-change" || snapshot.mutationState === "prepared") continue;
12411
+ terminal.push({
12412
+ name,
12413
+ unitId: snapshot.unitId,
12414
+ createdAt: snapshot.createdAt
12415
+ });
12416
+ } catch {}
12417
+ }
12418
+ terminal.sort((a, b) => b.createdAt - a.createdAt);
12419
+ let removed = 0;
12420
+ for (const entry of terminal.slice(keep)) {
12421
+ await io.remove(join(dir, entry.name));
12422
+ await io.remove(unitJournalPath(home, entry.unitId, "skill")).catch(() => {});
12423
+ removed += 1;
12424
+ }
12425
+ return removed;
12426
+ }
12121
12427
  const PHASE = {
12122
12428
  prepared: "prepared",
12123
12429
  "unit-written": "unit-written",
@@ -12126,8 +12432,9 @@ const PHASE = {
12126
12432
  undone: "rolled-back"
12127
12433
  };
12128
12434
  /**
12129
- * Production adapter onto the existing unit journal. It never writes a second
12130
- * journal file; merge and tree-change units share the one journal directory.
12435
+ * Production adapter onto the skill-owned journal directory. Merge recovery
12436
+ * reads merge/unit-journals only; legacy tree-change journals carry kind and
12437
+ * are skipped by the recovery coordinator.
12131
12438
  */
12132
12439
  function unitJournalPort(io, home) {
12133
12440
  return { async write(record) {
@@ -12141,8 +12448,9 @@ function unitJournalPort(io, home) {
12141
12448
  phase: PHASE[record.phase],
12142
12449
  storageKey: unitStorageKey(record.unitId),
12143
12450
  snapshotSha256: contentHash(JSON.stringify(record)),
12451
+ kind: "tree-change",
12144
12452
  updatedAt: Date.now()
12145
- });
12453
+ }, "skill");
12146
12454
  } };
12147
12455
  }
12148
12456
  //#endregion
@@ -12711,7 +13019,7 @@ var SkillLibrary = class {
12711
13019
  /** Recover every prepared tree-change snapshot in the shared unit store. */
12712
13020
  async recoverPreparedUnits() {
12713
13021
  const home = dirname(this.root);
12714
- return await new MutationUnit({
13022
+ const results = await new MutationUnit({
12715
13023
  io: this.io,
12716
13024
  limits: {
12717
13025
  maxSkillFileBytes: this.limits.maxSkillFileBytes,
@@ -12722,6 +13030,8 @@ var SkillLibrary = class {
12722
13030
  journal: unitJournalPort(this.io, home),
12723
13031
  snapshots: unitSnapshotPort(this.io, home)
12724
13032
  }).recoverPrepared();
13033
+ await pruneTreeChangeUnits(this.io, home).catch(() => {});
13034
+ return results;
12725
13035
  }
12726
13036
  /**
12727
13037
  * Run one single-file read-modify-write for a mutator. When `transact` was
@@ -17479,13 +17789,13 @@ const PARAM_EXPOSURE = Object.freeze([
17479
17789
  owner: "evolution-approval",
17480
17790
  applies: "live",
17481
17791
  docAnchor: "PARAMETERS.md#write-caps",
17482
- summary: "What the confirmation before an APPROVE does: write straight through, ask first, or treat an unanswered prompt as a cancel. The same three words skillWriteConfirm uses for a skill write.",
17792
+ summary: "What the confirmation before an APPROVE does: execute immediately, or ask first.",
17483
17793
  label: "批准前先确认",
17484
- hint: "点「批准」时要不要再确认一次:直接执行 / 先确认 / 等待超时即取消。默认直接执行(不打断批量批准)。",
17794
+ hint: "点「批准」时要不要再确认一次:直接执行 / 先确认。默认直接执行(不打断批量批准)。",
17485
17795
  control: "select",
17486
17796
  unit: "",
17487
- values: "auto|ask|timeout",
17488
- valueLabels: "直接执行|先确认|等待超时即取消",
17797
+ values: "auto|ask",
17798
+ valueLabels: "直接执行|先确认",
17489
17799
  card: "evolution-approval"
17490
17800
  },
17491
17801
  {
@@ -18299,4 +18609,4 @@ function isIgnorableEvent(event) {
18299
18609
  return classifySessionEvent(event) !== "model";
18300
18610
  }
18301
18611
  //#endregion
18302
- 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_MEMORY_CHAR_LIMIT, 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_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, EXTRACT_PROMPT_HASH, EXTRACT_PROMPT_V1, EXTRACT_PROMPT_VERSION, 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, MutationUnit, 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, SkillModel, 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, buildExtractPlanFromLibrary, 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, ensureSkillFrontmatter, entryTarget, errorText, evaluateThreat, eventsFile, evidenceKindIndex, evolutionActivityProjection, evolutionEventPayloadIssue, evolutionEvidenceProjection, evolutionHome, evolutionIoAdapter, evolutionProjectionHistoryProjection, evolutionReadsProjection, evolutionRoot, evolutionSignalsProjection, executeUnitUndo, externalRefs, fileMutationLock, filterUnreadSkillOps, findDriftSignal, findOwnerCandidate, 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, ownerCandidatesFromSummaries, ownerDecisionText, paramNamespace, paramRowId, paramSettingsId, parseCuratorNominations, parseEvolutionEvents, parseFrontmatter, parseHistoryIndex, partitionVersions, payloadText, persistedWriteSite, persistedWriteSites, pickWithPolicy, planExtract, planNamespaceMigration, planReferenceRewrite, planRehoming, planUnitUndoAcross, policyStageLimits, probeAbsent, probeChannelState, probeList, probeMtime, probePresent, probeReason, probeText, probeUnknown, projectExtractBodies, projectionText, proposalFromPlan, proposalReportDir, proposalReportName, protectedSkillNamesOf, readDispatchSignal, readEvolutionEvents, readEvolutionTimeline, readExternalSupport, readHistoryIndex, readJsonObject, readNumberParam, readParam, readProposalReports, 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, selectSections, 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, unitJournalPort, unitMembersAreComplete, unitReceiptPath, unitSnapshotPath, unitSnapshotPort, unitSnapshotsDir, unitStorageKey, unwrapLive, updateSuppressedNames, upsertUnitIndex, usageFile, usageObserved, userSetKeys, validateFrontmatter, validateMutationRequest, validateRestructureTarget, validateSupportPath, valueOr, verifyPromptBundle, versionActionKind, versionRowCells, versionSummaryPrompt, versionTarget, vocabulary, withTreeWrite, withTreeWriteLock, writeDurableTmp, writePathSymbols, writeProposalReport, writeUnitEvidence, writeUnitJournal, writeUnitReceipt, writeUnitSnapshot, yamlPlainScalarNeedsQuotes };
18612
+ 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_MEMORY_CHAR_LIMIT, 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_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, EXTRACT_PROMPT_HASH, EXTRACT_PROMPT_V1, EXTRACT_PROMPT_VERSION, 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, MutationUnit, 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, SkillModel, 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, WriteKernel, 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, buildExtractPlanFromLibrary, buildHealthBaseline, buildLearnPrompt, bumpPatch, bumpSupportRead, bumpUse, bumpView, callingScope, candidateSkills, canonicalWriteId, claimInstance, clampOnce, clampedNumber, classifyNamespaceMigration, classifySessionEvent, clearReviewChannel, collectReadSkillNames, collectReadSupportFiles, computeDedupGroups, computeDriftSignals, computeLifecycleTransitions, computePrefixClusters, computeQualityScores, computeScopeView, contentHash, contentRetentionFeedback, countDispatches, countReferenceFiles, createGateSet, createSubagentChannel, daysSinceIso, declaredReportStamp, describeReferenceRewrite, diffFindings, dispatchKeyOf, dispatchPathOf, dispatchStepOf, displayBodyOf, duplicateHeadings, elapsedSince, emptyRecord, ensureSkillFrontmatter, entryTarget, errorText, evaluateThreat, eventsFile, evidenceKindIndex, evolutionActivityProjection, evolutionEventPayloadIssue, evolutionEvidenceProjection, evolutionHome, evolutionIoAdapter, evolutionProjectionHistoryProjection, evolutionReadsProjection, evolutionRoot, evolutionSignalsProjection, executeUnitUndo, externalRefs, fileMutationLock, filterUnreadSkillOps, findDriftSignal, findOwnerCandidate, 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, isProjectableSession, 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, ownerCandidatesFromSummaries, ownerDecisionText, paramNamespace, paramRowId, paramSettingsId, parseCuratorNominations, parseEvolutionEvents, parseFrontmatter, parseHistoryIndex, partitionVersions, payloadText, persistedWriteSite, persistedWriteSites, pickWithPolicy, planExtract, planNamespaceMigration, planReferenceRewrite, planRehoming, planUnitUndoAcross, policyStageLimits, probeAbsent, probeChannelState, probeList, probeMtime, probePresent, probeReason, probeText, probeUnknown, projectExtractBodies, projectionText, proposalFromPlan, proposalReportDir, proposalReportName, protectedSkillNamesOf, pruneTreeChangeUnits, readDispatchSignal, readEvolutionEvents, readEvolutionTimeline, readExternalSupport, readHistoryIndex, readJsonObject, readNumberParam, readParam, readProposalReports, 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, selectSections, sessionAudited, sessionEvidenceIndex, sessionLastEventTime, sessionReadNames, sessionReadSkillNames, sessionReadSupportFiles, sessionSeesFamilyTools, sessionTurnSignals, skillLibraryUnitBackend, skillReadNameOf, skillRowCells, skillStateKey, skillWriteGateContext, skillsRoot, staleRouteStubs, subagentChannelState, supportFileReadFromPath, supportFileReadOf, supportRefs, suppressedFile, sweepReports, sweepReviewChannelSessions, textDiffFacts, tokenLineFor, transactIo, transactTaskGuard, treeLockFile, trimPatternBoundaries, unhookedSupportPointers, unitEvidenceDigest, unitEvidencePath, unitIndexPath, unitJournalPath, unitJournalPhaseRank, unitJournalPort, unitMembersAreComplete, unitReceiptPath, unitSnapshotPath, unitSnapshotPort, unitSnapshotsDir, unitStorageKey, unwrapLive, updateSuppressedNames, upsertUnitIndex, usageFile, usageObserved, userSetKeys, validateFrontmatter, validateMutationRequest, validateRestructureTarget, validateSupportPath, valueOr, verifyPromptBundle, versionActionKind, versionRowCells, versionSummaryPrompt, versionTarget, vocabulary, withTreeWrite, withTreeWriteLock, writeDurableTmp, writePathSymbols, writeProposalReport, writeUnitEvidence, writeUnitJournal, writeUnitReceipt, writeUnitSnapshot, yamlPlainScalarNeedsQuotes };