@cleocode/cleo 2026.9.24 → 2026.9.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/cli/index.js +401 -236
  2. package/package.json +13 -13
  3. package/studio-dist/client/_app/immutable/chunks/BeqrF76J.js +3 -0
  4. package/studio-dist/client/_app/immutable/chunks/{iXXfYtUd.js → CcEmirN4.js} +1 -1
  5. package/studio-dist/client/_app/immutable/chunks/DRFhIGr1.js +1 -0
  6. package/studio-dist/client/_app/immutable/chunks/{BeSHW-PI.js → Dj9Ite4c.js} +1 -1
  7. package/studio-dist/client/_app/immutable/entry/{app.D0MhB1gq.js → app.tPQyYZoK.js} +2 -2
  8. package/studio-dist/client/_app/immutable/entry/start.TCOC0qnN.js +1 -0
  9. package/studio-dist/client/_app/immutable/nodes/{0.CPm_3d_8.js → 0.BVYdqJjU.js} +1 -1
  10. package/studio-dist/client/_app/immutable/nodes/{1.kD8K_ebT.js → 1.DJbQn5Aq.js} +1 -1
  11. package/studio-dist/client/_app/immutable/nodes/{15.WEaAYVEy.js → 15.DFLciLwG.js} +1 -1
  12. package/studio-dist/client/_app/immutable/nodes/{16.SxplBCYx.js → 16.BgshH5yX.js} +1 -1
  13. package/studio-dist/client/_app/immutable/nodes/{17.HawOwgFr.js → 17.BQZJRQ5A.js} +1 -1
  14. package/studio-dist/client/_app/immutable/nodes/{18.CU1uc6aV.js → 18.B_YK1P9Z.js} +1 -1
  15. package/studio-dist/client/_app/immutable/nodes/{20.Dj3In1mD.js → 20.Dls8MCe1.js} +1 -1
  16. package/studio-dist/client/_app/immutable/nodes/{24.BABzil92.js → 24.IXvinnru.js} +1 -1
  17. package/studio-dist/client/_app/immutable/nodes/{25.K9V1t9FS.js → 25.BEebPQVq.js} +1 -1
  18. package/studio-dist/client/_app/immutable/nodes/{26.Ber4zDmK.js → 26.B7CS0G5p.js} +1 -1
  19. package/studio-dist/client/_app/immutable/nodes/{3.CDH1-JKn.js → 3.CdayxXUQ.js} +1 -1
  20. package/studio-dist/client/_app/version.json +1 -1
  21. package/studio-dist/server/chunks/{0-CzucydBz.js → 0-AF3xrUkn.js} +3 -3
  22. package/studio-dist/server/chunks/1-DcpAzosv.js +9 -0
  23. package/studio-dist/server/chunks/{15-B36yiClS.js → 15-D0fpXhAY.js} +3 -3
  24. package/studio-dist/server/chunks/{16-TEN2Xs7g.js → 16-DvOEuR2L.js} +3 -3
  25. package/studio-dist/server/chunks/{17-CDqPwV0A.js → 17-B0jymkfA.js} +3 -3
  26. package/studio-dist/server/chunks/{18-C9SojWQi.js → 18-s4VnOMua.js} +3 -3
  27. package/studio-dist/server/chunks/{20-D2rDiJCy.js → 20-B1I-AIgl.js} +3 -3
  28. package/studio-dist/server/chunks/{24-DFin4XEU.js → 24-Cd9TIy6S.js} +3 -3
  29. package/studio-dist/server/chunks/{25-byalahiX.js → 25-CqxPBOK6.js} +3 -3
  30. package/studio-dist/server/chunks/{26-BctSc53D.js → 26-CSVz9wrd.js} +3 -3
  31. package/studio-dist/server/chunks/{3-u3g5-V70.js → 3-CnvKWYCF.js} +3 -3
  32. package/studio-dist/server/chunks/{_layout.svelte-BkWa8zMq.js → _layout.svelte-DHaVs7sR.js} +4 -4
  33. package/studio-dist/server/chunks/{_page.svelte-D1ImKwNa.js → _page.svelte-3f1I0RBM.js} +3 -3
  34. package/studio-dist/server/chunks/{_page.svelte-CEoJA3np.js → _page.svelte-B4hpnUVn.js} +3 -3
  35. package/studio-dist/server/chunks/{_page.svelte-Balyz5No.js → _page.svelte-BQ3d309E.js} +3 -3
  36. package/studio-dist/server/chunks/{_page.svelte-DdieDDqt.js → _page.svelte-Birr_Gmr.js} +4 -4
  37. package/studio-dist/server/chunks/{_page.svelte-DdRs2eQU.js → _page.svelte-C2xIuyWy.js} +3 -3
  38. package/studio-dist/server/chunks/{_page.svelte-Nf_2u2sG.js → _page.svelte-CHQ7E1xk.js} +3 -3
  39. package/studio-dist/server/chunks/{_page.svelte-SpNaTPY3.js → _page.svelte-CW--O2H7.js} +3 -3
  40. package/studio-dist/server/chunks/{_page.svelte-D1GgG_0J.js → _page.svelte-DHso8H-7.js} +3 -3
  41. package/studio-dist/server/chunks/{_page.svelte-ClYQv-J6.js → _page.svelte-Do5ujrFm.js} +4 -4
  42. package/studio-dist/server/chunks/{_server.ts-BFAKIrzM.js → _server.ts-DvaFTJ0E.js} +2 -2
  43. package/studio-dist/server/chunks/{client-NfsjQdjU.js → client-CPa0CHb-.js} +2 -2
  44. package/studio-dist/server/chunks/{error.svelte-xf-NkEuU.js → error.svelte-B4-aI-CN.js} +3 -3
  45. package/studio-dist/server/chunks/{internal-OCcHamz2.js → internal-Ba4D4YGm.js} +2 -2
  46. package/studio-dist/server/chunks/{stores-Dyo9kN1m.js → stores-DsgjOOHe.js} +2 -2
  47. package/studio-dist/server/index.js +1 -1
  48. package/studio-dist/server/manifest.js +13 -13
  49. package/studio-dist/client/_app/immutable/chunks/BmmibeAn.js +0 -1
  50. package/studio-dist/client/_app/immutable/chunks/CqxUYDwj.js +0 -3
  51. package/studio-dist/client/_app/immutable/entry/start.Z2uJ5V0K.js +0 -1
  52. package/studio-dist/server/chunks/1-BgfY0ktP.js +0 -9
package/dist/cli/index.js CHANGED
@@ -1234,6 +1234,7 @@ var init_tree = __esm({
1234
1234
  // packages/animations/src/render/index.ts
1235
1235
  var init_render = __esm({
1236
1236
  "packages/animations/src/render/index.ts"() {
1237
+ "use strict";
1237
1238
  init_legend();
1238
1239
  init_tree();
1239
1240
  }
@@ -1351,7 +1352,6 @@ var init_spinner_handle = __esm({
1351
1352
  var init_src = __esm({
1352
1353
  "packages/animations/src/index.ts"() {
1353
1354
  init_animate_context();
1354
- init_render();
1355
1355
  init_spinner_handle();
1356
1356
  }
1357
1357
  });
@@ -31247,29 +31247,25 @@ var init_memory2 = __esm({
31247
31247
  }
31248
31248
  bindArgs.push(limitVal);
31249
31249
  const whereClause = clauses.join(" AND ");
31250
- let rows = [];
31251
- try {
31252
- const rawRows = nativeDb.prepare(
31253
- `SELECT id, title, text, type, source_session_id, memory_tier, created_at
31254
- FROM brain_observations
31255
- WHERE ${whereClause}
31256
- ORDER BY created_at DESC
31257
- LIMIT ?`
31258
- ).all(...bindArgs);
31259
- rows = rawRows.map((raw) => {
31260
- const r = raw;
31261
- return {
31262
- id: String(r["id"] ?? ""),
31263
- title: r["title"] != null ? String(r["title"]) : null,
31264
- text: String(r["text"] ?? ""),
31265
- type: r["type"] != null ? String(r["type"]) : null,
31266
- source_session_id: r["source_session_id"] != null ? String(r["source_session_id"]) : null,
31267
- memory_tier: r["memory_tier"] != null ? String(r["memory_tier"]) : null,
31268
- created_at: String(r["created_at"] ?? "")
31269
- };
31270
- });
31271
- } catch {
31272
- }
31250
+ const rawRows = nativeDb.prepare(
31251
+ `SELECT id, title, narrative AS text, type, source_session_id, memory_tier, created_at
31252
+ FROM brain_observations
31253
+ WHERE ${whereClause}
31254
+ ORDER BY created_at DESC
31255
+ LIMIT ?`
31256
+ ).all(...bindArgs);
31257
+ const rows = rawRows.map((raw) => {
31258
+ const r = raw;
31259
+ return {
31260
+ id: String(r["id"] ?? ""),
31261
+ title: r["title"] != null ? String(r["title"]) : null,
31262
+ text: String(r["text"] ?? ""),
31263
+ type: r["type"] != null ? String(r["type"]) : null,
31264
+ source_session_id: r["source_session_id"] != null ? String(r["source_session_id"]) : null,
31265
+ memory_tier: r["memory_tier"] != null ? String(r["memory_tier"]) : null,
31266
+ created_at: String(r["created_at"] ?? "")
31267
+ };
31268
+ });
31273
31269
  return wrapResult(
31274
31270
  {
31275
31271
  success: true,
@@ -31305,29 +31301,25 @@ var init_memory2 = __esm({
31305
31301
  startTime
31306
31302
  );
31307
31303
  }
31308
- let rows = [];
31309
- try {
31310
- const rawRows = nativeDb.prepare(
31311
- `SELECT id, title, text, source_session_id, memory_tier, created_at
31312
- FROM brain_observations
31313
- WHERE type = 'diary'
31314
- AND invalid_at IS NULL
31315
- ORDER BY created_at DESC
31316
- LIMIT ?`
31317
- ).all(limitVal);
31318
- rows = rawRows.map((raw) => {
31319
- const r = raw;
31320
- return {
31321
- id: String(r["id"] ?? ""),
31322
- title: r["title"] != null ? String(r["title"]) : null,
31323
- text: String(r["text"] ?? ""),
31324
- source_session_id: r["source_session_id"] != null ? String(r["source_session_id"]) : null,
31325
- memory_tier: r["memory_tier"] != null ? String(r["memory_tier"]) : null,
31326
- created_at: String(r["created_at"] ?? "")
31327
- };
31328
- });
31329
- } catch {
31330
- }
31304
+ const rawRows = nativeDb.prepare(
31305
+ `SELECT id, title, narrative AS text, source_session_id, memory_tier, created_at
31306
+ FROM brain_observations
31307
+ WHERE type = 'diary'
31308
+ AND invalid_at IS NULL
31309
+ ORDER BY created_at DESC
31310
+ LIMIT ?`
31311
+ ).all(limitVal);
31312
+ const rows = rawRows.map((raw) => {
31313
+ const r = raw;
31314
+ return {
31315
+ id: String(r["id"] ?? ""),
31316
+ title: r["title"] != null ? String(r["title"]) : null,
31317
+ text: String(r["text"] ?? ""),
31318
+ source_session_id: r["source_session_id"] != null ? String(r["source_session_id"]) : null,
31319
+ memory_tier: r["memory_tier"] != null ? String(r["memory_tier"]) : null,
31320
+ created_at: String(r["created_at"] ?? "")
31321
+ };
31322
+ });
31331
31323
  return wrapResult(
31332
31324
  {
31333
31325
  success: true,
@@ -31373,28 +31365,24 @@ var init_memory2 = __esm({
31373
31365
  bindArgs.push(cursorParam);
31374
31366
  }
31375
31367
  bindArgs.push(limitVal);
31376
- let rows = [];
31377
- try {
31378
- const rawRows = nativeDb.prepare(
31379
- `SELECT id, title, text, type, memory_tier, created_at
31380
- FROM brain_observations
31381
- WHERE ${clauses.join(" AND ")}
31382
- ORDER BY created_at ASC
31383
- LIMIT ?`
31384
- ).all(...bindArgs);
31385
- rows = rawRows.map((raw) => {
31386
- const r = raw;
31387
- return {
31388
- id: String(r["id"] ?? ""),
31389
- title: r["title"] != null ? String(r["title"]) : null,
31390
- text: String(r["text"] ?? ""),
31391
- type: r["type"] != null ? String(r["type"]) : null,
31392
- memory_tier: r["memory_tier"] != null ? String(r["memory_tier"]) : null,
31393
- created_at: String(r["created_at"] ?? "")
31394
- };
31395
- });
31396
- } catch {
31397
- }
31368
+ const rawRows = nativeDb.prepare(
31369
+ `SELECT id, title, narrative AS text, type, memory_tier, created_at
31370
+ FROM brain_observations
31371
+ WHERE ${clauses.join(" AND ")}
31372
+ ORDER BY created_at ASC
31373
+ LIMIT ?`
31374
+ ).all(...bindArgs);
31375
+ const rows = rawRows.map((raw) => {
31376
+ const r = raw;
31377
+ return {
31378
+ id: String(r["id"] ?? ""),
31379
+ title: r["title"] != null ? String(r["title"]) : null,
31380
+ text: String(r["text"] ?? ""),
31381
+ type: r["type"] != null ? String(r["type"]) : null,
31382
+ memory_tier: r["memory_tier"] != null ? String(r["memory_tier"]) : null,
31383
+ created_at: String(r["created_at"] ?? "")
31384
+ };
31385
+ });
31398
31386
  const nextCursor = rows.length > 0 ? rows[rows.length - 1].created_at : cursorParam ?? null;
31399
31387
  return wrapResult(
31400
31388
  {
@@ -38009,8 +37997,8 @@ async function loadPlaybookByName(name) {
38009
37997
  return null;
38010
37998
  }
38011
37999
  try {
38012
- const { getProjectRoot: getProjectRoot73 } = await import("@cleocode/core/internal");
38013
- const projectRoot = __playbookRuntimeOverrides.projectRoot ?? getProjectRoot73();
38000
+ const { getProjectRoot: getProjectRoot74 } = await import("@cleocode/core/internal");
38001
+ const projectRoot = __playbookRuntimeOverrides.projectRoot ?? getProjectRoot74();
38014
38002
  const resolved = resolvePlaybook(name, {
38015
38003
  projectRoot,
38016
38004
  globalPlaybooksDir: __playbookRuntimeOverrides.globalPlaybooksDir,
@@ -38055,7 +38043,7 @@ async function buildDefaultDispatcher() {
38055
38043
  if (__playbookRuntimeOverrides.dispatcher) return __playbookRuntimeOverrides.dispatcher;
38056
38044
  const { orchestrateSpawnExecute: orchestrateSpawnExecute2 } = await import("@cleocode/runtime/gateway");
38057
38045
  const {
38058
- getProjectRoot: getProjectRoot73,
38046
+ getProjectRoot: getProjectRoot74,
38059
38047
  createToolGuard,
38060
38048
  runSkillNodeOrSpawn,
38061
38049
  maybeCreatePiRunner,
@@ -38063,7 +38051,7 @@ async function buildDefaultDispatcher() {
38063
38051
  hasCantbookProfilePin,
38064
38052
  DEFAULT_DETERMINISTIC_DENIED_COMMANDS
38065
38053
  } = await import("@cleocode/core/internal");
38066
- const projectRoot = getProjectRoot73();
38054
+ const projectRoot = getProjectRoot74();
38067
38055
  const tools = createToolGuard({
38068
38056
  allowedRoots: [projectRoot],
38069
38057
  deniedCommands: DEFAULT_DETERMINISTIC_DENIED_COMMANDS,
@@ -38156,12 +38144,12 @@ async function buildDefaultDeterministicRunner() {
38156
38144
  return void 0;
38157
38145
  }
38158
38146
  const {
38159
- getProjectRoot: getProjectRoot73,
38147
+ getProjectRoot: getProjectRoot74,
38160
38148
  createToolGuard,
38161
38149
  createGuardedDeterministicRunner,
38162
38150
  DEFAULT_DETERMINISTIC_DENIED_COMMANDS
38163
38151
  } = await import("@cleocode/core/internal");
38164
- const projectRoot = getProjectRoot73();
38152
+ const projectRoot = getProjectRoot74();
38165
38153
  const tools = createToolGuard({
38166
38154
  allowedRoots: [projectRoot],
38167
38155
  deniedCommands: DEFAULT_DETERMINISTIC_DENIED_COMMANDS,
@@ -38319,8 +38307,8 @@ var init_playbook2 = __esm({
38319
38307
  projectRoot = __playbookRuntimeOverrides.projectRoot;
38320
38308
  } else {
38321
38309
  try {
38322
- const { getProjectRoot: getProjectRoot73 } = await import("@cleocode/core/internal");
38323
- projectRoot = getProjectRoot73();
38310
+ const { getProjectRoot: getProjectRoot74 } = await import("@cleocode/core/internal");
38311
+ projectRoot = getProjectRoot74();
38324
38312
  } catch {
38325
38313
  projectRoot = void 0;
38326
38314
  }
@@ -38385,14 +38373,14 @@ var init_playbook2 = __esm({
38385
38373
  const deterministicRunner = await buildDefaultDeterministicRunner();
38386
38374
  let result;
38387
38375
  try {
38388
- const { getProjectRoot: getProjectRoot73 } = await import("@cleocode/core/internal");
38376
+ const { getProjectRoot: getProjectRoot74 } = await import("@cleocode/core/internal");
38389
38377
  const opts = {
38390
38378
  db,
38391
38379
  playbook: parsed.definition,
38392
38380
  playbookHash: parsed.sourceHash,
38393
38381
  initialContext,
38394
38382
  dispatcher,
38395
- projectRoot: getProjectRoot73()
38383
+ projectRoot: getProjectRoot74()
38396
38384
  };
38397
38385
  if (deterministicRunner !== void 0) opts.deterministicRunner = deterministicRunner;
38398
38386
  if (__playbookRuntimeOverrides.approvalSecret !== void 0) {
@@ -40089,7 +40077,7 @@ async function manifestStatsOp(params) {
40089
40077
  return pipelineManifestStats(params.epicId, getProjectRoot12());
40090
40078
  }
40091
40079
  async function manifestAppendOp(params) {
40092
- return pipelineManifestAppend(params.entry, getProjectRoot12());
40080
+ return pipelineManifestAppend(params.entry, getProjectRoot12(), { requireExistingTasks: true });
40093
40081
  }
40094
40082
  async function manifestArchiveOp(params) {
40095
40083
  return pipelineManifestArchive(params.beforeDate, getProjectRoot12());
@@ -45730,11 +45718,11 @@ var init_security = __esm({
45730
45718
  });
45731
45719
 
45732
45720
  // packages/cleo/src/dispatch/middleware/sanitizer.ts
45733
- function createSanitizer(getProjectRoot73) {
45721
+ function createSanitizer(getProjectRoot74) {
45734
45722
  return async (req, next) => {
45735
45723
  if (req.params) {
45736
45724
  try {
45737
- const root = getProjectRoot73 ? getProjectRoot73() : void 0;
45725
+ const root = getProjectRoot74 ? getProjectRoot74() : void 0;
45738
45726
  req.params = sanitizeParams(req.params, root, {
45739
45727
  domain: req.domain,
45740
45728
  operation: req.operation
@@ -45836,14 +45824,14 @@ var init_session_resolver = __esm({
45836
45824
  });
45837
45825
 
45838
45826
  // packages/cleo/src/dispatch/middleware/store-write-guard.ts
45839
- function createStoreWriteGuard(getProjectRoot73) {
45827
+ function createStoreWriteGuard(getProjectRoot74) {
45840
45828
  return async (req, next) => {
45841
45829
  if (req.gateway !== "mutate" || ALLOWED_WHILE_READ_ONLY.has(`${req.domain}.${req.operation}`)) {
45842
45830
  return next();
45843
45831
  }
45844
45832
  let projectRoot;
45845
45833
  try {
45846
- projectRoot = getProjectRoot73();
45834
+ projectRoot = getProjectRoot74();
45847
45835
  } catch {
45848
45836
  return next();
45849
45837
  }
@@ -52858,14 +52846,14 @@ var init_backup = __esm({
52858
52846
  return;
52859
52847
  }
52860
52848
  const { exportPortableBundle, PortableBundleError } = await import("@cleocode/core/store/portable-bundle.js");
52861
- const { getProjectRoot: getProjectRoot73 } = await import("@cleocode/core");
52849
+ const { getProjectRoot: getProjectRoot74 } = await import("@cleocode/core");
52862
52850
  const passphrase = args.encrypt === true ? await resolvePassphrase() : void 0;
52863
52851
  if (args.encrypt === true && passphrase === void 0) return;
52864
52852
  const encSuffix = args.encrypt === true ? "enc." : "";
52865
52853
  try {
52866
52854
  const result = await exportPortableBundle({
52867
52855
  scope,
52868
- projectRoot: scope === "project" || scope === "all" ? getProjectRoot73() : void 0,
52856
+ projectRoot: scope === "project" || scope === "all" ? getProjectRoot74() : void 0,
52869
52857
  outputPath: args.out ?? `./${args.name}.${encSuffix}cleobundle.tar.gz`,
52870
52858
  encrypt: args.encrypt === true,
52871
52859
  passphrase,
@@ -52922,12 +52910,12 @@ var init_backup = __esm({
52922
52910
  );
52923
52911
  return;
52924
52912
  }
52925
- const { getProjectRoot: getProjectRoot73, getCleoHome: getCleoHome8, getCleoVersion } = await import("@cleocode/core");
52913
+ const { getProjectRoot: getProjectRoot74, getCleoHome: getCleoHome8, getCleoVersion } = await import("@cleocode/core");
52926
52914
  const { BundleError, cleanupStaging, unpackBundle } = await import("@cleocode/core/store/backup-unpack.js");
52927
52915
  const { regenerateConfigJson, regenerateProjectContextJson, regenerateProjectInfoJson } = await import("@cleocode/core/store/regenerators.js");
52928
52916
  const { regenerateAndCompare } = await import("@cleocode/core/store/restore-json-merge.js");
52929
52917
  const { buildConflictReport, writeConflictReport } = await import("@cleocode/core/store/restore-conflict-report.js");
52930
- const projectRoot = getProjectRoot73();
52918
+ const projectRoot = getProjectRoot74();
52931
52919
  const { assertOwnerStoreRewriteConfirmed } = await import("@cleocode/core/store/worktree-isolation-guard.js");
52932
52920
  try {
52933
52921
  assertOwnerStoreRewriteConfirmed("backup import", path2.join(projectRoot, ".cleo"), {
@@ -58465,12 +58453,12 @@ var init_decide2 = __esm({
58465
58453
  decideBenchCommand = defineCommand({
58466
58454
  meta: {
58467
58455
  name: "bench",
58468
- description: "System One accuracy benchmark (T12495): build a labelled dataset from this project's own history (duplicate task pairs, explicitly typed observations, superseding decisions; redacted), write a stratified spot-check sample for the owner, then compare providers against each site's heuristic with batched calls (provider cache off, 30s or longer deadline): accuracy, precision, recall, F1, false-positive rate, p50/p95 latency, cost and fallbacks, mean and spread over --runs. A hard total cap (--max-usd, default 5) is checked before every batch; the run stops cleanly at it. Profiles resolve from CLEO_DECIDE_PROFILE_<NAME>_KEY/_URL/_MODEL or the stored provider kind. --sample-only never contacts a provider."
58456
+ description: "System One accuracy benchmark (T12495): build a labelled dataset from this project's own history (duplicate task pairs, explicitly typed observations, superseding decisions; redacted), write a stratified spot-check sample for the owner, then compare providers against each site's heuristic with batched calls (provider cache off, 30s or longer deadline): accuracy, precision, recall, F1, false-positive rate, p50/p95 latency, cost and fallbacks, mean and spread over --runs. A hard total cap (--max-usd, default 5) is checked before every batch; the run stops cleanly at it. Each --profiles entry is a System One profile (cleo decide profiles): an id <provider>/<name> (e.g. layahost/work), or a bare provider meaning its active profile, else <provider>/default; a default URL resolves to the provider preset. A name no profile holds falls back to CLEO_DECIDE_PROFILE_<NAME>_KEY (plus _URL, _MODEL, _PROVIDER) for a one-off key. An unknown name fails listing the stored profiles (keys masked). --sample-only never contacts a provider."
58469
58457
  },
58470
58458
  args: {
58471
58459
  profiles: {
58472
58460
  type: "string",
58473
- description: "Comma list of provider profiles to compare, e.g. layahost,jev"
58461
+ description: "Comma list of profiles to compare: <provider>/<name> ids or bare providers, e.g. layahost/work,jev"
58474
58462
  },
58475
58463
  sites: {
58476
58464
  type: "string",
@@ -63120,12 +63108,74 @@ var init_docs3 = __esm({
63120
63108
  }
63121
63109
  });
63122
63110
 
63111
+ // packages/cleo/src/cli/commands/doctor-ac-bindings.ts
63112
+ var doctor_ac_bindings_exports = {};
63113
+ __export(doctor_ac_bindings_exports, {
63114
+ doctorAcBindingsCommand: () => doctorAcBindingsCommand
63115
+ });
63116
+ import { scanOrphanAcBindings } from "@cleocode/core/doctor/orphan-ac-bindings.js";
63117
+ import { getProjectRoot as getProjectRoot41 } from "@cleocode/core/paths.js";
63118
+ var doctorAcBindingsCommand;
63119
+ var init_doctor_ac_bindings = __esm({
63120
+ "packages/cleo/src/cli/commands/doctor-ac-bindings.ts"() {
63121
+ "use strict";
63122
+ init_src2();
63123
+ init_define_cli_command();
63124
+ init_renderers();
63125
+ doctorAcBindingsCommand = defineCommand({
63126
+ meta: {
63127
+ name: "ac-bindings",
63128
+ description: "Report evidence bindings whose acceptance criterion no longer exists (dangling tasks_evidence_ac_bindings rows). Read-only unless --fix is given; --fix removes them, recording each removed row in the task audit log (ac.bindings.pruned)."
63129
+ },
63130
+ args: {
63131
+ fix: {
63132
+ type: "boolean",
63133
+ description: "Delete the orphan bindings in one transaction, after writing each row to the task audit log so binding history (alias-drift detection) is kept."
63134
+ },
63135
+ limit: {
63136
+ type: "string",
63137
+ description: "Maximum orphan rows echoed in the report (default 50; counts are exact)"
63138
+ },
63139
+ json: { type: "boolean", description: "Output as JSON" },
63140
+ human: { type: "boolean", description: "Force human-readable output" },
63141
+ quiet: { type: "boolean", description: "Suppress non-essential output" }
63142
+ },
63143
+ async run({ args }) {
63144
+ let limit;
63145
+ if (typeof args.limit === "string") {
63146
+ if (!/^\d+$/.test(args.limit.trim())) {
63147
+ cliError(
63148
+ `--limit must be a non-negative integer (got '${args.limit}')`,
63149
+ 6 /* VALIDATION_ERROR */,
63150
+ { name: "E_VALIDATION" }
63151
+ );
63152
+ return;
63153
+ }
63154
+ limit = Number.parseInt(args.limit, 10);
63155
+ }
63156
+ const report = await scanOrphanAcBindings(getProjectRoot41(), {
63157
+ fix: args.fix === true,
63158
+ limit
63159
+ });
63160
+ cliOutput(report, {
63161
+ command: "doctor",
63162
+ operation: "doctor.ac-bindings.run"
63163
+ });
63164
+ const unresolved = report.orphanCount > report.removed;
63165
+ if (unresolved && (process.exitCode === void 0 || process.exitCode === 0)) {
63166
+ process.exitCode = 1;
63167
+ }
63168
+ }
63169
+ });
63170
+ }
63171
+ });
63172
+
63123
63173
  // packages/cleo/src/cli/commands/doctor-acceptance-drift.ts
63124
63174
  var doctor_acceptance_drift_exports = {};
63125
63175
  __export(doctor_acceptance_drift_exports, {
63126
63176
  doctorAcceptanceDriftCommand: () => doctorAcceptanceDriftCommand
63127
63177
  });
63128
- import { getProjectRoot as getProjectRoot41 } from "@cleocode/core";
63178
+ import { getProjectRoot as getProjectRoot42 } from "@cleocode/core";
63129
63179
  import {
63130
63180
  scanAcceptanceDrift,
63131
63181
  writeAcceptanceDriftBaseline
@@ -63155,7 +63205,7 @@ var init_doctor_acceptance_drift = __esm({
63155
63205
  quiet: { type: "boolean", description: "Suppress non-essential output" }
63156
63206
  },
63157
63207
  async run(ctx) {
63158
- const result = scanAcceptanceDrift(getProjectRoot41());
63208
+ const result = scanAcceptanceDrift(getProjectRoot42());
63159
63209
  cliOutput(result, {
63160
63210
  command: "doctor",
63161
63211
  operation: "doctor.acceptance-drift.run"
@@ -63179,7 +63229,7 @@ __export(doctor_credentials_exports, {
63179
63229
  doctorCredentialsCommand: () => doctorCredentialsCommand
63180
63230
  });
63181
63231
  import { join as join22 } from "node:path";
63182
- import { getCleoHome as getCleoHome5, getProjectRoot as getProjectRoot42 } from "@cleocode/core/paths.js";
63232
+ import { getCleoHome as getCleoHome5, getProjectRoot as getProjectRoot43 } from "@cleocode/core/paths.js";
63183
63233
  import {
63184
63234
  auditAgentRegistryKeys,
63185
63235
  migrateProjectCredentialsAtRoot
@@ -63206,7 +63256,7 @@ var init_doctor_credentials = __esm({
63206
63256
  },
63207
63257
  async run({ args }) {
63208
63258
  const dryRun = args.fix !== true;
63209
- const result = await migrateProjectCredentialsAtRoot(getProjectRoot42(), { dryRun });
63259
+ const result = await migrateProjectCredentialsAtRoot(getProjectRoot43(), { dryRun });
63210
63260
  const agents = await auditAgentRegistryKeys(join22(getCleoHome5(), "cleo.db"), { dryRun });
63211
63261
  cliOutput(
63212
63262
  {
@@ -63241,12 +63291,26 @@ __export(doctor_db_substrate_exports, {
63241
63291
  doctorDbSubstrateCommand: () => doctorDbSubstrateCommand
63242
63292
  });
63243
63293
  import { dirname as dirname9 } from "node:path";
63244
- import { getProjectRoot as getProjectRoot43, pushWarning as pushWarning4 } from "@cleocode/core";
63294
+ import { getProjectRoot as getProjectRoot44, pushWarning as pushWarning4 } from "@cleocode/core";
63245
63295
  import { surveyDbSubstrate, surveyFleetDbSubstrate } from "@cleocode/core/doctor/db-substrate.js";
63296
+ import { NexusRegistryReadError } from "@cleocode/core/nexus/registry-errors.js";
63246
63297
  import { listRegistryParentRoots } from "@cleocode/core/nexus/registry-roots.js";
63247
63298
  async function defaultFleetRoots() {
63248
63299
  const roots = await listRegistryParentRoots();
63249
- return roots.length > 0 ? roots : [dirname9(getProjectRoot43())];
63300
+ return roots.length > 0 ? roots : [dirname9(getProjectRoot44())];
63301
+ }
63302
+ function reportRegistryReadError(error) {
63303
+ cliError(
63304
+ error.message,
63305
+ error.code,
63306
+ {
63307
+ name: error.codeName,
63308
+ fix: `Pass \`--fleet-root <dir>\` to survey without the registry. ${error.fix ?? ""}`.trim(),
63309
+ details: error.details
63310
+ },
63311
+ { operation: "doctor.db-substrate.run" }
63312
+ );
63313
+ process.exitCode = error.code;
63250
63314
  }
63251
63315
  function pushSubstrateWarnings(result) {
63252
63316
  for (const warning of result.warnings) {
@@ -63384,10 +63448,21 @@ var init_doctor_db_substrate = __esm({
63384
63448
  cwd: process.cwd(),
63385
63449
  confirmOwnerStore: args["confirm-owner-store"] === true
63386
63450
  };
63387
- const result = isFleet ? surveyFleetDbSubstrate(
63388
- typeof args["fleet-root"] === "string" && args["fleet-root"].length > 0 ? args["fleet-root"] : await defaultFleetRoots(),
63389
- options
63390
- ) : surveyDbSubstrate(getProjectRoot43(), options);
63451
+ let fleetRoots;
63452
+ if (isFleet) {
63453
+ if (typeof args["fleet-root"] === "string" && args["fleet-root"].length > 0) {
63454
+ fleetRoots = args["fleet-root"];
63455
+ } else {
63456
+ try {
63457
+ fleetRoots = await defaultFleetRoots();
63458
+ } catch (error) {
63459
+ if (!(error instanceof NexusRegistryReadError)) throw error;
63460
+ reportRegistryReadError(error);
63461
+ return;
63462
+ }
63463
+ }
63464
+ }
63465
+ const result = fleetRoots !== void 0 ? surveyFleetDbSubstrate(fleetRoots, options) : surveyDbSubstrate(getProjectRoot44(), options);
63391
63466
  pushSubstrateWarnings(result);
63392
63467
  pushPerDbWarnings(result);
63393
63468
  cliOutput(result, {
@@ -63719,7 +63794,7 @@ var doctor_legacy_backups_exports = {};
63719
63794
  __export(doctor_legacy_backups_exports, {
63720
63795
  doctorLegacyBackupsCommand: () => doctorLegacyBackupsCommand
63721
63796
  });
63722
- import { getProjectRoot as getProjectRoot44 } from "@cleocode/core";
63797
+ import { getProjectRoot as getProjectRoot45 } from "@cleocode/core";
63723
63798
  import { pruneLegacyBackups, scanLegacyBackups } from "@cleocode/core/doctor/legacy-backups.js";
63724
63799
  function parsePositiveInt(raw, fallback) {
63725
63800
  if (raw === void 0 || raw === null) return fallback;
@@ -63763,7 +63838,7 @@ var init_doctor_legacy_backups = __esm({
63763
63838
  async run({ args }) {
63764
63839
  const softRetentionDays = parsePositiveInt(args["soft-retention-days"], 30);
63765
63840
  const hardRetentionDays = parsePositiveInt(args["hard-retention-days"], 90);
63766
- const projectRoot = getProjectRoot44();
63841
+ const projectRoot = getProjectRoot45();
63767
63842
  let result;
63768
63843
  if (args.prune === true) {
63769
63844
  const dryRun = args["dry-run"] !== false;
@@ -63829,7 +63904,7 @@ var doctor_malformed_ids_exports = {};
63829
63904
  __export(doctor_malformed_ids_exports, {
63830
63905
  doctorMalformedIdsCommand: () => doctorMalformedIdsCommand
63831
63906
  });
63832
- import { getProjectRoot as getProjectRoot45 } from "@cleocode/core";
63907
+ import { getProjectRoot as getProjectRoot46 } from "@cleocode/core";
63833
63908
  import { scanMalformedTaskIds } from "@cleocode/core/doctor/malformed-task-ids.js";
63834
63909
  var doctorMalformedIdsCommand;
63835
63910
  var init_doctor_malformed_ids = __esm({
@@ -63852,7 +63927,7 @@ var init_doctor_malformed_ids = __esm({
63852
63927
  quiet: { type: "boolean", description: "Suppress non-essential output" }
63853
63928
  },
63854
63929
  async run({ args }) {
63855
- const report = await scanMalformedTaskIds(getProjectRoot45(), { fix: args.fix === true });
63930
+ const report = await scanMalformedTaskIds(getProjectRoot46(), { fix: args.fix === true });
63856
63931
  cliOutput(report, {
63857
63932
  command: "doctor",
63858
63933
  operation: "doctor.malformed-ids.run"
@@ -63873,12 +63948,13 @@ __export(doctor_manifest_rows_exports, {
63873
63948
  });
63874
63949
  import {
63875
63950
  listMalformedManifestRows,
63951
+ listManifestIdentityProblems,
63876
63952
  MANIFEST_ROW_APPLY_COMMAND,
63877
63953
  MANIFEST_ROW_REPAIR_COMMAND,
63878
63954
  repairMalformedManifestRows,
63879
63955
  rollbackManifestRepair
63880
63956
  } from "@cleocode/core/memory/pipeline-manifest-sqlite.js";
63881
- import { getProjectRoot as getProjectRoot46 } from "@cleocode/core/paths.js";
63957
+ import { getProjectRoot as getProjectRoot47 } from "@cleocode/core/paths.js";
63882
63958
  var doctorManifestRowsCommand;
63883
63959
  var init_doctor_manifest_rows = __esm({
63884
63960
  "packages/cleo/src/cli/commands/doctor-manifest-rows.ts"() {
@@ -63888,7 +63964,7 @@ var init_doctor_manifest_rows = __esm({
63888
63964
  doctorManifestRowsCommand = defineCommand({
63889
63965
  meta: {
63890
63966
  name: "manifest-rows",
63891
- description: "List manifest rows whose metadata violates the stored field contract. --repair shows the plan (writes nothing); --repair --apply moves each bad field under _malformed (nothing lost) with a receipt; --rollback <receipt> undoes it."
63967
+ description: "List manifest rows whose metadata violates the stored field contract, and (read-only) rows with an invalid id, linked task id or file reference. --repair shows the plan (writes nothing); --repair --apply moves each bad field under _malformed (nothing lost) with a receipt; --rollback <receipt> undoes it."
63892
63968
  },
63893
63969
  args: {
63894
63970
  repair: {
@@ -63909,7 +63985,7 @@ var init_doctor_manifest_rows = __esm({
63909
63985
  quiet: { type: "boolean", description: "Suppress non-essential output" }
63910
63986
  },
63911
63987
  async run({ args }) {
63912
- const projectRoot = getProjectRoot46();
63988
+ const projectRoot = getProjectRoot47();
63913
63989
  if (typeof args.rollback === "string" && args.rollback !== "") {
63914
63990
  const result = await rollbackManifestRepair(args.rollback, projectRoot);
63915
63991
  cliOutput(result, { command: "doctor", operation: "doctor.manifest-rows.rollback" });
@@ -63928,11 +64004,13 @@ var init_doctor_manifest_rows = __esm({
63928
64004
  return;
63929
64005
  }
63930
64006
  const rows = await listMalformedManifestRows(projectRoot);
64007
+ const identity = await listManifestIdentityProblems(projectRoot);
63931
64008
  cliOutput(
63932
- { rows, repair: rows.length > 0 ? MANIFEST_ROW_REPAIR_COMMAND : null },
64009
+ { rows, repair: rows.length > 0 ? MANIFEST_ROW_REPAIR_COMMAND : null, identity },
63933
64010
  { command: "doctor", operation: "doctor.manifest-rows.run" }
63934
64011
  );
63935
- if (rows.length > 0 && (process.exitCode === void 0 || process.exitCode === 0)) {
64012
+ const invalidIdentity = identity.some((r) => r.issues.some((i) => i.code === "E_VALIDATION"));
64013
+ if ((rows.length > 0 || invalidIdentity) && (process.exitCode === void 0 || process.exitCode === 0)) {
63936
64014
  process.exitCode = 1;
63937
64015
  }
63938
64016
  }
@@ -64009,7 +64087,7 @@ var doctor_nexus_residency_exports = {};
64009
64087
  __export(doctor_nexus_residency_exports, {
64010
64088
  doctorNexusResidencyCommand: () => doctorNexusResidencyCommand
64011
64089
  });
64012
- import { getCleoHome as getCleoHome6, getProjectRoot as getProjectRoot47 } from "@cleocode/core";
64090
+ import { getCleoHome as getCleoHome6, getProjectRoot as getProjectRoot48 } from "@cleocode/core";
64013
64091
  import { scanNexusSchemaResidency } from "@cleocode/core/doctor/nexus-schema-residency.js";
64014
64092
  var doctorNexusResidencyCommand;
64015
64093
  var init_doctor_nexus_residency = __esm({
@@ -64028,7 +64106,7 @@ var init_doctor_nexus_residency = __esm({
64028
64106
  quiet: { type: "boolean", description: "Suppress non-essential output" }
64029
64107
  },
64030
64108
  async run() {
64031
- const result = scanNexusSchemaResidency(getProjectRoot47(), getCleoHome6());
64109
+ const result = scanNexusSchemaResidency(getProjectRoot48(), getCleoHome6());
64032
64110
  cliOutput(result, {
64033
64111
  command: "doctor",
64034
64112
  operation: "doctor.nexus-residency.run"
@@ -64046,7 +64124,7 @@ var doctor_project_identity_exports = {};
64046
64124
  __export(doctor_project_identity_exports, {
64047
64125
  doctorProjectIdentityCommand: () => doctorProjectIdentityCommand
64048
64126
  });
64049
- import { getProjectRoot as getProjectRoot48 } from "@cleocode/core";
64127
+ import { getProjectRoot as getProjectRoot49 } from "@cleocode/core";
64050
64128
  import {
64051
64129
  inspectProjectIdentity,
64052
64130
  inspectProjectNameDrift,
@@ -64071,7 +64149,7 @@ var init_doctor_project_identity = __esm({
64071
64149
  quiet: { type: "boolean", description: "Suppress non-essential output" }
64072
64150
  },
64073
64151
  async run({ args }) {
64074
- const projectRoot = getProjectRoot48();
64152
+ const projectRoot = getProjectRoot49();
64075
64153
  if (!args.resolve) {
64076
64154
  const report = inspectProjectIdentity(projectRoot);
64077
64155
  const nameDrift = await inspectProjectNameDrift(projectRoot);
@@ -64104,6 +64182,7 @@ import {
64104
64182
  RegistryRepairError,
64105
64183
  rollbackProjectRegistryRepair
64106
64184
  } from "@cleocode/core/doctor/projects.js";
64185
+ import { NexusRegistryReadError as NexusRegistryReadError2 } from "@cleocode/core/nexus/registry-errors.js";
64107
64186
  var positiveInt, doctorRegistryCommand;
64108
64187
  var init_doctor_projects_registry = __esm({
64109
64188
  "packages/cleo/src/cli/commands/doctor-projects-registry.ts"() {
@@ -64157,6 +64236,16 @@ var init_doctor_projects_registry = __esm({
64157
64236
  if ((report.findings.some((f) => f.kind !== "other-device") || report.ambiguousAliases.length > 0) && (process.exitCode ?? 0) === 0)
64158
64237
  process.exitCode = 1;
64159
64238
  } catch (error) {
64239
+ if (error instanceof NexusRegistryReadError2) {
64240
+ cliError(
64241
+ error.message,
64242
+ error.code,
64243
+ { name: error.codeName, fix: error.fix, details: error.details },
64244
+ { operation }
64245
+ );
64246
+ process.exitCode = error.code;
64247
+ return;
64248
+ }
64160
64249
  const code = error instanceof RegistryRepairError ? error.code : "E_DOCTOR_PROJECTS_FAILED";
64161
64250
  const exitCode = code === "E_NOT_FOUND" ? 4 : 1;
64162
64251
  cliError(
@@ -64198,6 +64287,17 @@ function deriveExitCode(summary, ignoreUnreachable) {
64198
64287
  return 0;
64199
64288
  }
64200
64289
  function printDoctorProjectsReport(report, opts, nameLookup) {
64290
+ if (report.registryError) {
64291
+ const { registryError } = report;
64292
+ cliError(
64293
+ registryError.message,
64294
+ registryError.exitCode,
64295
+ { name: registryError.code, fix: registryError.fix, details: { report } },
64296
+ { operation: "doctor.projects" }
64297
+ );
64298
+ process.exitCode = registryError.exitCode;
64299
+ return;
64300
+ }
64201
64301
  const { summary } = report;
64202
64302
  const exitCode = deriveExitCode(summary, opts.ignoreUnreachable === true);
64203
64303
  process.exitCode = exitCode;
@@ -64250,13 +64350,15 @@ async function runDoctorProjects(opts = {}) {
64250
64350
  includeGlobal: opts.skipGlobal !== true
64251
64351
  });
64252
64352
  const nameLookup = /* @__PURE__ */ new Map();
64253
- try {
64254
- const { nexusList } = await import("@cleocode/core/internal");
64255
- const rows = await nexusList();
64256
- for (const row of rows) {
64257
- nameLookup.set(row.hash, row.name);
64353
+ if (!report.registryError) {
64354
+ try {
64355
+ const { nexusList } = await import("@cleocode/core/internal");
64356
+ const rows = await nexusList();
64357
+ for (const row of rows) {
64358
+ nameLookup.set(row.hash, row.name);
64359
+ }
64360
+ } catch {
64258
64361
  }
64259
- } catch {
64260
64362
  }
64261
64363
  printDoctorProjectsReport(report, opts, nameLookup);
64262
64364
  return report;
@@ -64586,7 +64688,7 @@ var doctor_repair_exports = {};
64586
64688
  __export(doctor_repair_exports, {
64587
64689
  doctorRepairCommand: () => doctorRepairCommand
64588
64690
  });
64589
- import { getLogger as getLogger21, getProjectRoot as getProjectRoot49 } from "@cleocode/core";
64691
+ import { getLogger as getLogger21, getProjectRoot as getProjectRoot50 } from "@cleocode/core";
64590
64692
  import { repairMalformedDbs } from "@cleocode/core/store/repair-malformed-dbs.js";
64591
64693
  var doctorRepairCommand;
64592
64694
  var init_doctor_repair = __esm({
@@ -64635,7 +64737,7 @@ var init_doctor_repair = __esm({
64635
64737
  return;
64636
64738
  }
64637
64739
  const result = repairMalformedDbs({
64638
- projectRoot: getProjectRoot49(),
64740
+ projectRoot: getProjectRoot50(),
64639
64741
  roles: roleArg.length > 0 ? [roleArg] : void 0,
64640
64742
  dryRun,
64641
64743
  logger: getLogger21("doctor-repair"),
@@ -64837,7 +64939,7 @@ var doctor_superseded_store_exports = {};
64837
64939
  __export(doctor_superseded_store_exports, {
64838
64940
  doctorSupersededStoreCommand: () => doctorSupersededStoreCommand
64839
64941
  });
64840
- import { getProjectRoot as getProjectRoot50 } from "@cleocode/core";
64942
+ import { getProjectRoot as getProjectRoot51 } from "@cleocode/core";
64841
64943
  import { scanSupersededStores } from "@cleocode/core/doctor/superseded-store.js";
64842
64944
  import { reconcileSupersededStores } from "@cleocode/core/store/exodus/index.js";
64843
64945
  var doctorSupersededStoreCommand;
@@ -64870,7 +64972,7 @@ var init_doctor_superseded_store = __esm({
64870
64972
  },
64871
64973
  async run({ args }) {
64872
64974
  if (args.reconcile === true) {
64873
- const receipt = await reconcileSupersededStores(getProjectRoot50(), {
64975
+ const receipt = await reconcileSupersededStores(getProjectRoot51(), {
64874
64976
  dryRun: args["dry-run"] === true,
64875
64977
  additive: args.additive === true
64876
64978
  });
@@ -64892,7 +64994,7 @@ var init_doctor_superseded_store = __esm({
64892
64994
  );
64893
64995
  return;
64894
64996
  }
64895
- const result = scanSupersededStores(getProjectRoot50());
64997
+ const result = scanSupersededStores(getProjectRoot51());
64896
64998
  cliOutput(result, {
64897
64999
  command: "doctor",
64898
65000
  operation: "doctor.superseded-store.run"
@@ -64988,11 +65090,12 @@ __export(doctor_twin_collapse_exports, {
64988
65090
  import {
64989
65091
  inspectProjectTwinCollapse,
64990
65092
  recoverTwinCollapse,
65093
+ releaseProjectTwinCollapseSnapshot,
64991
65094
  retryTwinCollapse,
64992
65095
  rollbackTwinCollapse
64993
65096
  } from "@cleocode/core/doctor/twin-collapse.js";
64994
65097
  import { CleoError as CleoError8 } from "@cleocode/core/errors";
64995
- import { getProjectRoot as getProjectRoot51 } from "@cleocode/core/paths.js";
65098
+ import { getProjectRoot as getProjectRoot52 } from "@cleocode/core/paths.js";
64996
65099
  function reportTwinCollapseError(error, retry) {
64997
65100
  if (retry && !(error instanceof CleoError8)) throw error;
64998
65101
  const message = error instanceof Error ? error.message : String(error);
@@ -65005,6 +65108,15 @@ function reportTwinCollapseError(error, retry) {
65005
65108
  });
65006
65109
  process.exitCode = error instanceof CleoError8 ? error.code : 1;
65007
65110
  }
65111
+ function twinCollapseActions(args) {
65112
+ const named = (key) => typeof args[key] === "string" && args[key].length > 0;
65113
+ return [
65114
+ args.recover === true ? "--recover" : "",
65115
+ named("release-snapshot") ? "--release-snapshot" : "",
65116
+ named("rollback") ? "--rollback" : "",
65117
+ args.retry === true ? "--retry" : ""
65118
+ ].filter(Boolean);
65119
+ }
65008
65120
  var doctorTwinCollapseCommand;
65009
65121
  var init_doctor_twin_collapse = __esm({
65010
65122
  "packages/cleo/src/cli/commands/doctor-twin-collapse.ts"() {
@@ -65014,7 +65126,7 @@ var init_doctor_twin_collapse = __esm({
65014
65126
  doctorTwinCollapseCommand = defineCommand({
65015
65127
  meta: {
65016
65128
  name: "twin-collapse",
65017
- description: "Report the twin collapses (bare schema_meta / sticky_tags kept in step with their prefixed twins): state, last failure, snapshot path and space needed. --retry re-runs them."
65129
+ description: "Report the twin collapses (bare schema_meta / sticky_tags kept in step with their prefixed twins): state, last failure, snapshot path and space needed. --retry re-runs them; --recover restores what 2026.9.21 dropped; --release-snapshot lets a checked snapshot rotate."
65018
65130
  },
65019
65131
  args: {
65020
65132
  retry: {
@@ -65029,10 +65141,22 @@ var init_doctor_twin_collapse = __esm({
65029
65141
  type: "boolean",
65030
65142
  description: "With --recover: print the plan, write nothing"
65031
65143
  },
65144
+ "pin-snapshot": {
65145
+ type: "boolean",
65146
+ description: "With --recover: pin an unpinned pre-collapse snapshot (its .meta.json sidecar only) before applying"
65147
+ },
65032
65148
  rollback: {
65033
65149
  type: "string",
65034
65150
  description: "Undo one --recover apply by its receipt id (twin_collapse_recovery:<recoveredAt>)"
65035
65151
  },
65152
+ "release-snapshot": {
65153
+ type: "string",
65154
+ description: "Release a pre-collapse snapshot (backup id, e.g. migration-20260928-153200) after a verified recovery or a no-recovery-needed check, so it rotates normally. Needs --confirm; --dry-run shows the bytes reclaimed"
65155
+ },
65156
+ confirm: {
65157
+ type: "boolean",
65158
+ description: "With --release-snapshot: the owner's decision to release (obtained by the calling agent; the CLI never prompts)"
65159
+ },
65036
65160
  "confirm-owner-store": {
65037
65161
  type: "boolean",
65038
65162
  description: "From a git worktree: allow --recover, --rollback or --retry to write the owning project's live store"
@@ -65042,8 +65166,18 @@ var init_doctor_twin_collapse = __esm({
65042
65166
  quiet: { type: "boolean", description: "Suppress non-essential output" }
65043
65167
  },
65044
65168
  async run({ args }) {
65045
- const projectRoot = getProjectRoot51();
65169
+ const projectRoot = getProjectRoot52();
65046
65170
  const guard = { cwd: process.cwd(), confirmOwnerStore: args["confirm-owner-store"] === true };
65171
+ const actions = twinCollapseActions(args);
65172
+ if (actions.length > 1) {
65173
+ cliError(
65174
+ `E_INVALID_INPUT: ${actions.join(" and ")} are separate actions; run them one at a time (--recover before --release-snapshot)`,
65175
+ "E_INVALID_INPUT",
65176
+ { name: "Error", fix: "cleo doctor twin-collapse --recover --dry-run" }
65177
+ );
65178
+ process.exitCode = 2;
65179
+ return;
65180
+ }
65047
65181
  try {
65048
65182
  if (typeof args.rollback === "string" && args.rollback.length > 0) {
65049
65183
  const result = await rollbackTwinCollapse(projectRoot, args.rollback, guard);
@@ -65053,10 +65187,27 @@ var init_doctor_twin_collapse = __esm({
65053
65187
  );
65054
65188
  return;
65055
65189
  }
65190
+ if (typeof args["release-snapshot"] === "string" && args["release-snapshot"].length > 0) {
65191
+ const result = await releaseProjectTwinCollapseSnapshot(
65192
+ projectRoot,
65193
+ args["release-snapshot"],
65194
+ {
65195
+ ...guard,
65196
+ dryRun: args["dry-run"] === true,
65197
+ confirm: args.confirm === true
65198
+ }
65199
+ );
65200
+ cliOutput(
65201
+ { kind: "generic", ...result },
65202
+ { command: "doctor", operation: "doctor.twin-collapse.release-snapshot" }
65203
+ );
65204
+ return;
65205
+ }
65056
65206
  if (args.recover === true) {
65057
65207
  const result = await recoverTwinCollapse(projectRoot, {
65058
65208
  ...guard,
65059
- dryRun: args["dry-run"] === true
65209
+ dryRun: args["dry-run"] === true,
65210
+ pinSnapshot: args["pin-snapshot"] === true
65060
65211
  });
65061
65212
  cliOutput(
65062
65213
  { kind: "generic", ...result },
@@ -65093,7 +65244,7 @@ __export(doctor_worktree_stores_exports, {
65093
65244
  doctorWorktreeStoresCommand: () => doctorWorktreeStoresCommand
65094
65245
  });
65095
65246
  import { scanWorktreeStores } from "@cleocode/core/doctor/worktree-stores.js";
65096
- import { getProjectRoot as getProjectRoot52, resolveStoreOwnerRoot } from "@cleocode/core/paths.js";
65247
+ import { getProjectRoot as getProjectRoot53, resolveStoreOwnerRoot } from "@cleocode/core/paths.js";
65097
65248
  var doctorWorktreeStoresCommand;
65098
65249
  var init_doctor_worktree_stores = __esm({
65099
65250
  "packages/cleo/src/cli/commands/doctor-worktree-stores.ts"() {
@@ -65115,7 +65266,7 @@ var init_doctor_worktree_stores = __esm({
65115
65266
  quiet: { type: "boolean", description: "Suppress non-essential output" }
65116
65267
  },
65117
65268
  async run({ args }) {
65118
- const projectRoot = resolveStoreOwnerRoot(getProjectRoot52());
65269
+ const projectRoot = resolveStoreOwnerRoot(getProjectRoot53());
65119
65270
  const result = scanWorktreeStores(projectRoot, { skipCompare: args["skip-compare"] === true });
65120
65271
  cliOutput(result, {
65121
65272
  command: "doctor",
@@ -65267,7 +65418,7 @@ import {
65267
65418
  resumePreparedKnowledgeRepair,
65268
65419
  runKnowledgeDoctor as runKnowledgeDoctor2
65269
65420
  } from "@cleocode/core/doctor/knowledge.js";
65270
- import { getProjectRoot as getProjectRoot53 } from "@cleocode/core/paths.js";
65421
+ import { getProjectRoot as getProjectRoot54 } from "@cleocode/core/paths.js";
65271
65422
  var doctorKnowledgeSubcommand;
65272
65423
  var init_doctor_knowledge = __esm({
65273
65424
  "packages/cleo/src/cli/commands/doctor-knowledge.ts"() {
@@ -65342,7 +65493,7 @@ var init_doctor_knowledge = __esm({
65342
65493
  },
65343
65494
  async run({ args }) {
65344
65495
  const startedAt = Date.now();
65345
- const root = getProjectRoot53();
65496
+ const root = getProjectRoot54();
65346
65497
  let context;
65347
65498
  let pending;
65348
65499
  try {
@@ -65510,7 +65661,7 @@ import { join as join24 } from "node:path";
65510
65661
  import {
65511
65662
  ensureGlobalAgentRegistryDb,
65512
65663
  getGlobalAgentRegistryNativeDb,
65513
- getProjectRoot as getProjectRoot54,
65664
+ getProjectRoot as getProjectRoot55,
65514
65665
  installAgentFromCant
65515
65666
  } from "@cleocode/core/internal";
65516
65667
  function sha256Hex(bytes) {
@@ -65698,7 +65849,7 @@ var init_migrate_agents_v2 = __esm({
65698
65849
  }
65699
65850
  },
65700
65851
  async run({ args }) {
65701
- const projectRoot = getProjectRoot54();
65852
+ const projectRoot = getProjectRoot55();
65702
65853
  const verbose = args.quiet !== true;
65703
65854
  if (verbose) {
65704
65855
  humanInfo("Scanning .cleo/cant/agents/ and .cleo/agents/ for unregistered agents...");
@@ -65742,7 +65893,7 @@ __export(doctor_exports, {
65742
65893
  });
65743
65894
  import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync5 } from "node:fs";
65744
65895
  import { join as join25 } from "node:path";
65745
- import { getProjectRoot as getProjectRoot55, pushWarning as pushWarning5 } from "@cleocode/core";
65896
+ import { getProjectRoot as getProjectRoot56, pushWarning as pushWarning5 } from "@cleocode/core";
65746
65897
  import { renderInvariantAuditLines } from "@cleocode/core/doctor/invariant-audit-render.js";
65747
65898
  import {
65748
65899
  quarantineRogueCleoDir,
@@ -65858,6 +66009,7 @@ var init_doctor = __esm({
65858
66009
  init_subcommand_guard();
65859
66010
  init_progress();
65860
66011
  init_renderers();
66012
+ init_doctor_ac_bindings();
65861
66013
  init_doctor_acceptance_drift();
65862
66014
  init_doctor_credentials();
65863
66015
  init_doctor_db_substrate();
@@ -65925,6 +66077,8 @@ var init_doctor = __esm({
65925
66077
  "split-brain": doctorSplitBrainCommand,
65926
66078
  // T12157 — the two acceptance stores (json column vs text+child rows) must agree
65927
66079
  "acceptance-drift": doctorAcceptanceDriftCommand,
66080
+ // T12790 — evidence bindings whose AC row is gone (no FK): report + --fix (audited)
66081
+ "ac-bindings": doctorAcBindingsCommand,
65928
66082
  // T12158 — tables nexus resolves by bare name must actually live where it assumes
65929
66083
  "nexus-residency": doctorNexusResidencyCommand,
65930
66084
  // T12113 (gh#1222) — evidence-tool semaphore holders + orphan reaping
@@ -66143,7 +66297,7 @@ var init_doctor = __esm({
66143
66297
  const { join: pathJoin } = await import("node:path");
66144
66298
  const { existsSync: existsSync22 } = await import("node:fs");
66145
66299
  const { detectAndHealCoreWorktreeLeak } = await import("@cleocode/worktree");
66146
- const projectRoot = getProjectRoot55();
66300
+ const projectRoot = getProjectRoot56();
66147
66301
  let gitRoot = projectRoot;
66148
66302
  try {
66149
66303
  gitRoot = execFile2("git", ["rev-parse", "--show-toplevel"], {
@@ -66195,7 +66349,7 @@ var init_doctor = __esm({
66195
66349
  }
66196
66350
  if (args.brain) {
66197
66351
  const { computeBrainHealthDashboard } = await import("@cleocode/core/memory/brain-health-dashboard.js");
66198
- const projectRoot = getProjectRoot55();
66352
+ const projectRoot = getProjectRoot56();
66199
66353
  const dashboard = await computeBrainHealthDashboard(projectRoot);
66200
66354
  cliOutput(dashboard, { command: "doctor", operation: "doctor.brain" });
66201
66355
  if (dashboard.hasP0Failure) {
@@ -66204,7 +66358,7 @@ var init_doctor = __esm({
66204
66358
  return;
66205
66359
  }
66206
66360
  if (args["scan-test-fixtures-in-prod"]) {
66207
- const projectRoot = getProjectRoot55();
66361
+ const projectRoot = getProjectRoot56();
66208
66362
  const matches = await scanTestFixturesInProd(projectRoot);
66209
66363
  const dryRun = args["dry-run"] !== false && args.quarantine !== true;
66210
66364
  const quarantined = !dryRun && matches.length > 0 ? await quarantineTestFixtures(projectRoot, matches) : void 0;
@@ -66292,7 +66446,7 @@ var init_doctor = __esm({
66292
66446
  progress.complete("Comprehensive diagnostics complete");
66293
66447
  } else if (args["scan-rogue-cleo-dirs"]) {
66294
66448
  progress.step(0, "Scanning for rogue .cleo/ directories");
66295
- const projectRoot = getProjectRoot55();
66449
+ const projectRoot = getProjectRoot56();
66296
66450
  const reports = scanRogueCleoDirs(projectRoot);
66297
66451
  progress.complete(
66298
66452
  `Found ${reports.length} rogue .cleo/ director${reports.length === 1 ? "y" : "ies"}`
@@ -66301,7 +66455,7 @@ var init_doctor = __esm({
66301
66455
  } else if (args["quarantine-rogue-cleo-dirs"]) {
66302
66456
  const isDryRun = args["dry-run"] === true;
66303
66457
  progress.step(0, `${isDryRun ? "[DRY RUN] " : ""}Scanning for rogue .cleo/ directories`);
66304
- const projectRoot = getProjectRoot55();
66458
+ const projectRoot = getProjectRoot56();
66305
66459
  const reports = scanRogueCleoDirs(projectRoot);
66306
66460
  if (reports.length === 0) {
66307
66461
  progress.complete("No rogue .cleo/ directories found \u2014 nothing to quarantine");
@@ -66355,7 +66509,7 @@ var init_doctor = __esm({
66355
66509
  const { detectAndRemoveLegacyGlobalFiles, detectAndRemoveStrayProjectNexus } = await import("@cleocode/core/store/cleanup-legacy.js");
66356
66510
  const { getCleoHome: getCleoHome8 } = await import("@cleocode/core");
66357
66511
  const cleoHome = getCleoHome8();
66358
- const projectRoot = getProjectRoot55();
66512
+ const projectRoot = getProjectRoot56();
66359
66513
  const legacyResult = detectAndRemoveLegacyGlobalFiles(cleoHome);
66360
66514
  const strayResult = detectAndRemoveStrayProjectNexus(projectRoot);
66361
66515
  const isDryRun = args["dry-run"] === true;
@@ -66388,7 +66542,7 @@ var init_doctor = __esm({
66388
66542
  } else if (args["audit-worktree-orphans"]) {
66389
66543
  progress.step(0, "Comprehensive worktree anomaly audit (T9808 / council D009)");
66390
66544
  const { auditWorktreeOrphansComprehensive, scanWorktreeOrphansBudgeted } = await import("@cleocode/core/doctor/worktree-orphans.js");
66391
- const projectRoot = getProjectRoot55();
66545
+ const projectRoot = getProjectRoot56();
66392
66546
  const timeoutSecs = args["timeout"] !== void 0 ? Number.parseInt(String(args["timeout"]), 10) : 30;
66393
66547
  const timeoutMs = Number.isFinite(timeoutSecs) && timeoutSecs > 0 ? timeoutSecs * 1e3 : 3e4;
66394
66548
  const maxEntriesPerLevel = args["max-entries-per-level"] !== void 0 ? Number.parseInt(String(args["max-entries-per-level"]), 10) : 500;
@@ -66445,7 +66599,7 @@ var init_doctor = __esm({
66445
66599
  `${isDryRun ? "[DRY RUN] " : ""}Scanning + pruning worktree-orphan .cleo/ directories`
66446
66600
  );
66447
66601
  const { pruneWorktreeOrphans, scanWorktreeOrphansBudgeted } = await import("@cleocode/core/doctor/worktree-orphans.js");
66448
- const projectRoot = getProjectRoot55();
66602
+ const projectRoot = getProjectRoot56();
66449
66603
  const timeoutSecs = args["timeout"] !== void 0 ? Number.parseInt(String(args["timeout"]), 10) : 30;
66450
66604
  const timeoutMs = Number.isFinite(timeoutSecs) && timeoutSecs > 0 ? timeoutSecs * 1e3 : 3e4;
66451
66605
  const maxEntriesPerLevel = args["max-entries-per-level"] !== void 0 ? Number.parseInt(String(args["max-entries-per-level"]), 10) : 500;
@@ -66524,7 +66678,7 @@ var init_doctor = __esm({
66524
66678
  `${isDryRun ? "[DRY RUN] " : ""}Migrating .cleo/worktree-include \u2192 .worktreeinclude`
66525
66679
  );
66526
66680
  const { migrateWorktreeIncludeFile } = await import("@cleocode/core");
66527
- const projectRoot = getProjectRoot55();
66681
+ const projectRoot = getProjectRoot56();
66528
66682
  const result = await migrateWorktreeIncludeFile(projectRoot, { dryRun: isDryRun });
66529
66683
  progress.complete(`Migration ${result.action}`);
66530
66684
  cliOutput(result, { command: "doctor", operation: "doctor.migrate-worktree-include" });
@@ -66543,7 +66697,7 @@ var init_doctor = __esm({
66543
66697
  const stepLabel = isFocusedAlias ? "Auditing Saga hierarchy for ADR-073 invariants" : "Walking central INVARIANTS_REGISTRY";
66544
66698
  progress.step(0, stepLabel);
66545
66699
  const { auditInvariantRegistry } = await import("@cleocode/core/doctor/invariant-audit.js");
66546
- const projectRoot = getProjectRoot55();
66700
+ const projectRoot = getProjectRoot56();
66547
66701
  const result = await auditInvariantRegistry(projectRoot, { adrFilter });
66548
66702
  const operation = isFocusedAlias ? "doctor.audit-sagas" : "doctor.audit-invariants";
66549
66703
  const summary = `Invariant audit complete \u2014 ${result.totalCount} entries walked, ${result.errorCount} error / ${result.warningCount} warning / ${result.infoCount} info violation(s), ${result.notApplicableCount} not-applicable, ${result.documentedCount} documented`;
@@ -66565,7 +66719,7 @@ var init_doctor = __esm({
66565
66719
  { command: "doctor", operation: "admin.health" }
66566
66720
  );
66567
66721
  try {
66568
- const projectRoot = getProjectRoot55();
66722
+ const projectRoot = getProjectRoot56();
66569
66723
  const conflicts = readMigrationConflicts(projectRoot);
66570
66724
  if (conflicts.length > 0) {
66571
66725
  progress.complete(
@@ -66596,7 +66750,7 @@ var init_doctor = __esm({
66596
66750
  progress.complete("Health check complete");
66597
66751
  }
66598
66752
  try {
66599
- const projectRoot = getProjectRoot55();
66753
+ const projectRoot = getProjectRoot56();
66600
66754
  const { auditSagaHierarchy } = await import("@cleocode/core/doctor/saga-audit.js");
66601
66755
  const sagaAudit = await auditSagaHierarchy(projectRoot);
66602
66756
  if (sagaAudit.sagas.length === 0) {
@@ -66715,8 +66869,8 @@ var init_done = __esm({
66715
66869
  process.exitCode = 2;
66716
66870
  return;
66717
66871
  }
66718
- const { getProjectRoot: getProjectRoot73 } = await import("@cleocode/core/paths.js");
66719
- const options = { projectRoot: getProjectRoot73(), ...parsed.options };
66872
+ const { getProjectRoot: getProjectRoot74 } = await import("@cleocode/core/paths.js");
66873
+ const options = { projectRoot: getProjectRoot74(), ...parsed.options };
66720
66874
  const requested = [
66721
66875
  ...new Set([args.taskId, ...args._ ?? []].map(String))
66722
66876
  ];
@@ -68076,7 +68230,7 @@ __export(gateway_exports, {
68076
68230
  gatewayOpenapiSubCommand: () => gatewayOpenapiSubCommand
68077
68231
  });
68078
68232
  import { resolve as resolve8 } from "node:path";
68079
- import { generateOpenApi, getProjectRoot as getProjectRoot56 } from "@cleocode/core";
68233
+ import { generateOpenApi, getProjectRoot as getProjectRoot57 } from "@cleocode/core";
68080
68234
  var gatewayOpenapiSubCommand, gatewayCommand;
68081
68235
  var init_gateway = __esm({
68082
68236
  "packages/cleo/src/cli/commands/gateway.ts"() {
@@ -68108,7 +68262,7 @@ var init_gateway = __esm({
68108
68262
  const pathCount = Object.keys(doc.paths).length;
68109
68263
  if (typeof args.out === "string" && args.out.length > 0) {
68110
68264
  const { writeFileSync: writeFileSync8 } = await import("node:fs");
68111
- const target = resolve8(getProjectRoot56(), args.out);
68265
+ const target = resolve8(getProjectRoot57(), args.out);
68112
68266
  writeFileSync8(target, json2, "utf8");
68113
68267
  cliOutput(
68114
68268
  { out: target, pathCount, version: doc.info.version, openapi: doc.openapi },
@@ -68569,7 +68723,7 @@ var go_exports = {};
68569
68723
  __export(go_exports, {
68570
68724
  goCommand: () => goCommand
68571
68725
  });
68572
- import { getProjectRoot as getProjectRoot57, go } from "@cleocode/core";
68726
+ import { getProjectRoot as getProjectRoot58, go } from "@cleocode/core";
68573
68727
  var goCommand;
68574
68728
  var init_go = __esm({
68575
68729
  "packages/cleo/src/cli/commands/go.ts"() {
@@ -68595,7 +68749,7 @@ var init_go = __esm({
68595
68749
  }
68596
68750
  },
68597
68751
  async run({ args }) {
68598
- const projectRoot = getProjectRoot57();
68752
+ const projectRoot = getProjectRoot58();
68599
68753
  const { getCurrentSessionId, resolveBoundSessionId } = await import("@cleocode/core/internal");
68600
68754
  let sessionId = getCurrentSessionId(projectRoot) ?? void 0;
68601
68755
  if (sessionId === void 0) {
@@ -68623,7 +68777,7 @@ var goal_exports = {};
68623
68777
  __export(goal_exports, {
68624
68778
  goalCommand: () => goalCommand
68625
68779
  });
68626
- import { getProjectRoot as getProjectRoot58, goal } from "@cleocode/core";
68780
+ import { getProjectRoot as getProjectRoot59, goal } from "@cleocode/core";
68627
68781
  function resolveGoalKind(task) {
68628
68782
  if (typeof task === "string" && task.length > 0) {
68629
68783
  if (!isValidGoalTargetTaskId(task)) {
@@ -68670,7 +68824,7 @@ var init_goal2 = __esm({
68670
68824
  }
68671
68825
  const record = await goal.createGoal(
68672
68826
  { goalKind: kindResult.kind, intent, turnBudget: resolveTurnBudget(args.turns) },
68673
- getProjectRoot58()
68827
+ getProjectRoot59()
68674
68828
  );
68675
68829
  cliOutput(record, { command: "goal set", operation: "goal.set" });
68676
68830
  }
@@ -68681,7 +68835,7 @@ var init_goal2 = __esm({
68681
68835
  description: "Show the current agent's active goal (per-agent scoped)."
68682
68836
  },
68683
68837
  async run() {
68684
- const record = await goal.getActiveGoal(getProjectRoot58());
68838
+ const record = await goal.getActiveGoal(getProjectRoot59());
68685
68839
  cliOutput(record ?? { active: null }, { command: "goal status", operation: "goal.status" });
68686
68840
  }
68687
68841
  });
@@ -68703,7 +68857,7 @@ var init_goal2 = __esm({
68703
68857
  });
68704
68858
  return;
68705
68859
  }
68706
- const cwd = getProjectRoot58();
68860
+ const cwd = getProjectRoot59();
68707
68861
  const parent = await goal.getActiveGoal(cwd);
68708
68862
  if (!parent) {
68709
68863
  cliError(
@@ -68751,7 +68905,7 @@ var init_goal2 = __esm({
68751
68905
  });
68752
68906
  return;
68753
68907
  }
68754
- const cwd = getProjectRoot58();
68908
+ const cwd = getProjectRoot59();
68755
68909
  const result = await goal.advanceGoalWithPersist(goalId, { cwd });
68756
68910
  if (!result) {
68757
68911
  cliError(`Goal '${goalId}' not found.`, 4 /* NOT_FOUND */, { name: "E_NOT_FOUND" });
@@ -68776,7 +68930,7 @@ var init_goal2 = __esm({
68776
68930
  });
68777
68931
  return;
68778
68932
  }
68779
- const cwd = getProjectRoot58();
68933
+ const cwd = getProjectRoot59();
68780
68934
  const active = await goal.getActiveGoal(cwd);
68781
68935
  if (!active) {
68782
68936
  cliError(
@@ -69823,7 +69977,7 @@ var hygiene_exports = {};
69823
69977
  __export(hygiene_exports, {
69824
69978
  hygieneCommand: () => hygieneCommand
69825
69979
  });
69826
- import { getProjectRoot as getProjectRoot59 } from "@cleocode/core";
69980
+ import { getProjectRoot as getProjectRoot60 } from "@cleocode/core";
69827
69981
  import { runSpawnReadinessHygieneCli } from "@cleocode/core/hygiene/validate-spawn-readiness.js";
69828
69982
  var hygieneCommand;
69829
69983
  var init_hygiene = __esm({
@@ -69852,7 +70006,7 @@ var init_hygiene = __esm({
69852
70006
  }
69853
70007
  },
69854
70008
  async run({ args }) {
69855
- const projectRoot = args["project-root"] || getProjectRoot59() || process.cwd();
70009
+ const projectRoot = args["project-root"] || getProjectRoot60() || process.cwd();
69856
70010
  const worktreePath = args["worktree-path"];
69857
70011
  await runSpawnReadinessHygieneCli(projectRoot, worktreePath);
69858
70012
  }
@@ -71195,7 +71349,7 @@ var llm_cost_exports = {};
71195
71349
  __export(llm_cost_exports, {
71196
71350
  costCommand: () => costCommand
71197
71351
  });
71198
- import { getProjectRoot as getProjectRoot60 } from "@cleocode/core/internal";
71352
+ import { getProjectRoot as getProjectRoot61 } from "@cleocode/core/internal";
71199
71353
  import { computeCost } from "@cleocode/core/llm/usage-pricing";
71200
71354
  function resolveSessionId(raw) {
71201
71355
  if (raw === "current") {
@@ -71268,7 +71422,7 @@ var init_llm_cost = __esm({
71268
71422
  process.exit(6);
71269
71423
  }
71270
71424
  const sessionId = resolveSessionId(rawSessionId);
71271
- const projectRoot = getProjectRoot60(process.cwd());
71425
+ const projectRoot = getProjectRoot61(process.cwd());
71272
71426
  let breakdown;
71273
71427
  try {
71274
71428
  breakdown = await loadSessionCostBreakdown(projectRoot, sessionId);
@@ -72657,7 +72811,7 @@ var memory_exports = {};
72657
72811
  __export(memory_exports, {
72658
72812
  memoryCommand: () => memoryCommand
72659
72813
  });
72660
- import { getProjectRoot as getProjectRoot61 } from "@cleocode/core";
72814
+ import { getProjectRoot as getProjectRoot62 } from "@cleocode/core";
72661
72815
  import {
72662
72816
  getBrainDb as getBrainDb2,
72663
72817
  getDreamStatus,
@@ -73615,7 +73769,7 @@ var init_memory3 = __esm({
73615
73769
  },
73616
73770
  args: {},
73617
73771
  async run() {
73618
- const root = getProjectRoot61();
73772
+ const root = getProjectRoot62();
73619
73773
  try {
73620
73774
  const result = await runConsolidation(root);
73621
73775
  cliOutput(result, { command: "memory-consolidate", operation: "memory.consolidate" });
@@ -73639,7 +73793,7 @@ var init_memory3 = __esm({
73639
73793
  }
73640
73794
  },
73641
73795
  async run({ args }) {
73642
- const root = getProjectRoot61();
73796
+ const root = getProjectRoot62();
73643
73797
  if (args.status) {
73644
73798
  try {
73645
73799
  const status = await getDreamStatus(root);
@@ -73676,7 +73830,7 @@ var init_memory3 = __esm({
73676
73830
  }
73677
73831
  },
73678
73832
  async run({ args }) {
73679
- const root = getProjectRoot61();
73833
+ const root = getProjectRoot62();
73680
73834
  try {
73681
73835
  const { runObserver, runReflector } = await import("@cleocode/core/memory");
73682
73836
  const observerResult = await runObserver(root, args.session, {
@@ -73716,7 +73870,7 @@ var init_memory3 = __esm({
73716
73870
  }
73717
73871
  },
73718
73872
  async run({ args }) {
73719
- const root = getProjectRoot61();
73873
+ const root = getProjectRoot62();
73720
73874
  await getBrainDb2(root);
73721
73875
  const { getBrainNativeDb: getBrainNativeDb3 } = await import("@cleocode/core/internal");
73722
73876
  const nativeDb = getBrainNativeDb3();
@@ -73754,7 +73908,7 @@ var init_memory3 = __esm({
73754
73908
  },
73755
73909
  async run({ args }) {
73756
73910
  const core2 = await import("@cleocode/core/internal");
73757
- const nexusDb = await core2.getNexusDb(getProjectRoot61());
73911
+ const nexusDb = await core2.getNexusDb(getProjectRoot62());
73758
73912
  const result = args.restore ? await core2.restorePrunedTraits(
73759
73913
  nexusDb,
73760
73914
  String(args.restore),
@@ -73784,7 +73938,7 @@ var init_memory3 = __esm({
73784
73938
  return;
73785
73939
  }
73786
73940
  const core2 = await import("@cleocode/core/internal");
73787
- const nexusDb = await core2.getNexusDb(getProjectRoot61());
73941
+ const nexusDb = await core2.getNexusDb(getProjectRoot62());
73788
73942
  const previous = await core2.setUserProfileTraitScope(nexusDb, String(args.key), scope);
73789
73943
  if (previous === null) {
73790
73944
  cliError(`No user-profile trait "${args.key}"`, "E_NOT_FOUND", { name: "E_NOT_FOUND" });
@@ -73808,7 +73962,7 @@ var init_memory3 = __esm({
73808
73962
  }
73809
73963
  },
73810
73964
  async run({ args }) {
73811
- const root = getProjectRoot61();
73965
+ const root = getProjectRoot62();
73812
73966
  try {
73813
73967
  await getBrainDb2(root);
73814
73968
  const { totalDuplicateRows, groups } = await scanDuplicateEntries();
@@ -73854,7 +74008,7 @@ var init_memory3 = __esm({
73854
74008
  async run({ args }) {
73855
74009
  const sourceDir = args.from;
73856
74010
  const isDryRun = !!args["dry-run"];
73857
- const projectRoot = getProjectRoot61();
74011
+ const projectRoot = getProjectRoot62();
73858
74012
  try {
73859
74013
  const result = await importMemoryFiles({
73860
74014
  sourceDir,
@@ -74005,7 +74159,7 @@ var init_memory3 = __esm({
74005
74159
  },
74006
74160
  args: {},
74007
74161
  async run() {
74008
- const root = getProjectRoot61();
74162
+ const root = getProjectRoot62();
74009
74163
  try {
74010
74164
  await getBrainDb2(root);
74011
74165
  const result = await getTierStats(root);
@@ -74048,7 +74202,7 @@ var init_memory3 = __esm({
74048
74202
  }
74049
74203
  },
74050
74204
  async run({ args }) {
74051
- const root = getProjectRoot61();
74205
+ const root = getProjectRoot62();
74052
74206
  const targetTier = args.to;
74053
74207
  const reason = args.reason;
74054
74208
  const validTiers = ["medium", "long"];
@@ -74114,7 +74268,7 @@ var init_memory3 = __esm({
74114
74268
  }
74115
74269
  },
74116
74270
  async run({ args }) {
74117
- const root = getProjectRoot61();
74271
+ const root = getProjectRoot62();
74118
74272
  const targetTier = args.to;
74119
74273
  const reason = args.reason;
74120
74274
  const validTiers = ["short", "medium"];
@@ -74587,7 +74741,7 @@ var migrate_claude_mem_exports = {};
74587
74741
  __export(migrate_claude_mem_exports, {
74588
74742
  migrateClaudeMemCommand: () => migrateClaudeMemCommand
74589
74743
  });
74590
- import { getProjectRoot as getProjectRoot62, migrateClaudeMem } from "@cleocode/core/internal";
74744
+ import { getProjectRoot as getProjectRoot63, migrateClaudeMem } from "@cleocode/core/internal";
74591
74745
  import { ingestLooseAgentOutputs, ingestRcasdDirectories } from "@cleocode/core/memory";
74592
74746
  import { getDb as getDb2 } from "@cleocode/core/store/sqlite";
74593
74747
  var storageCommand, claudeMemCommand, manifestIngestCommand, migrateClaudeMemCommand;
@@ -74650,7 +74804,7 @@ var init_migrate_claude_mem = __esm({
74650
74804
  }
74651
74805
  },
74652
74806
  async run({ args }) {
74653
- const root = getProjectRoot62();
74807
+ const root = getProjectRoot63();
74654
74808
  try {
74655
74809
  const result = await migrateClaudeMem(root, {
74656
74810
  sourcePath: args.source,
@@ -74699,7 +74853,7 @@ var init_migrate_claude_mem = __esm({
74699
74853
  }
74700
74854
  },
74701
74855
  async run({ args }) {
74702
- const projectRoot = getProjectRoot62();
74856
+ const projectRoot = getProjectRoot63();
74703
74857
  try {
74704
74858
  const db = await getDb2(projectRoot);
74705
74859
  const rcasdFlag = Boolean(args.rcasd);
@@ -74817,7 +74971,7 @@ __export(nexus_exports, {
74817
74971
  import { statSync as statSync2 } from "node:fs";
74818
74972
  import { appendFile as appendFile2, mkdir as mkdir5 } from "node:fs/promises";
74819
74973
  import path4 from "node:path";
74820
- import { getProjectRoot as getProjectRoot63 } from "@cleocode/core";
74974
+ import { getProjectRoot as getProjectRoot64 } from "@cleocode/core";
74821
74975
  import { getSymbolImpact } from "@cleocode/core/nexus";
74822
74976
  import { runNexusAnalysis } from "@cleocode/core/nexus/analyze-orchestrator.js";
74823
74977
  import {
@@ -74988,7 +75142,7 @@ var init_nexus3 = __esm({
74988
75142
  async run({ args }) {
74989
75143
  applyJsonFlag2(args.json);
74990
75144
  const projectIdOverride = args["project-id"];
74991
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
75145
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot64();
74992
75146
  const startTime = Date.now();
74993
75147
  if (args.path) {
74994
75148
  let isDir = false;
@@ -75048,7 +75202,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648), so the coun
75048
75202
  process.exitCode = 2 /* INVALID_INPUT */;
75049
75203
  return;
75050
75204
  }
75051
- const currentRoot = getProjectRoot63();
75205
+ const currentRoot = getProjectRoot64();
75052
75206
  if (args.path && path4.resolve(repoPath) !== path4.resolve(currentRoot)) {
75053
75207
  cliError(
75054
75208
  `nexus status cannot report on '${repoPath}' from this project.
@@ -75602,7 +75756,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
75602
75756
  applyJsonFlag2(args.json);
75603
75757
  const startTime = Date.now();
75604
75758
  const projectIdOverride = args["project-id"];
75605
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
75759
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot64();
75606
75760
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
75607
75761
  const response = await dispatchRaw("query", "nexus", "clusters", { projectId, repoPath });
75608
75762
  const durationMs = Date.now() - startTime;
@@ -75646,7 +75800,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
75646
75800
  applyJsonFlag2(args.json);
75647
75801
  const startTime = Date.now();
75648
75802
  const projectIdOverride = args["project-id"];
75649
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
75803
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot64();
75650
75804
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
75651
75805
  const response = await dispatchRaw("query", "nexus", "flows", { projectId, repoPath });
75652
75806
  const durationMs = Date.now() - startTime;
@@ -75689,7 +75843,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
75689
75843
  void appendDeprecationTelemetry("nexus.context", "cleo graph context");
75690
75844
  const startTime = Date.now();
75691
75845
  const projectIdOverride = args["project-id"];
75692
- const repoPath = getProjectRoot63();
75846
+ const repoPath = getProjectRoot64();
75693
75847
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
75694
75848
  const limit = parseInt(args.limit, 10);
75695
75849
  const symbolName = args.symbol;
@@ -75752,7 +75906,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
75752
75906
  const startTime = Date.now();
75753
75907
  const whyFlag = !!args.why;
75754
75908
  const projectIdOverride = args["project-id"];
75755
- const repoPath = getProjectRoot63();
75909
+ const repoPath = getProjectRoot64();
75756
75910
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
75757
75911
  const maxDepth = Math.min(parseInt(args.depth, 10), 5);
75758
75912
  const symbolName = args.symbol;
@@ -75856,7 +76010,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
75856
76010
  const projectIdOverride = args["project-id"];
75857
76011
  const full = !!args.full;
75858
76012
  const ctx = getFormatContext();
75859
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
76013
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot64();
75860
76014
  if (args.incremental)
75861
76015
  humanWarn(
75862
76016
  "[nexus] --incremental is deprecated and has no effect: incremental is the default."
@@ -75986,7 +76140,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
75986
76140
  async run({ args }) {
75987
76141
  applyJsonFlag2(args.json);
75988
76142
  const startTime = Date.now();
75989
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
76143
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot64();
75990
76144
  const name = args.name;
75991
76145
  const response = await dispatchRaw("mutate", "nexus", "projects.register", {
75992
76146
  path: repoPath,
@@ -76505,7 +76659,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
76505
76659
  applyJsonFlag2(args.json);
76506
76660
  const startTime = Date.now();
76507
76661
  const projectIdOverride = args["project-id"];
76508
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
76662
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot64();
76509
76663
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
76510
76664
  const response = await dispatchRaw("mutate", "nexus", "refresh-bridge", {
76511
76665
  repoPath,
@@ -76611,7 +76765,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
76611
76765
  async run({ args }) {
76612
76766
  applyJsonFlag2(args.json);
76613
76767
  const startTime = Date.now();
76614
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
76768
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot64();
76615
76769
  const projectIdOverride = args["project-id"];
76616
76770
  const beforeRef = args.before ?? "HEAD~1";
76617
76771
  const afterRef = args.after ?? "HEAD";
@@ -76729,7 +76883,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
76729
76883
  applyJsonFlag2(args.json);
76730
76884
  const startTime = Date.now();
76731
76885
  const projectIdOverride = args["project-id"];
76732
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
76886
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot64();
76733
76887
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
76734
76888
  const response = await dispatchRaw("query", "nexus", "route-map", { projectId });
76735
76889
  const durationMs = Date.now() - startTime;
@@ -76785,7 +76939,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
76785
76939
  const startTime = Date.now();
76786
76940
  const routeSymbol = args.routeSymbol;
76787
76941
  const projectIdOverride = args["project-id"];
76788
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
76942
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot64();
76789
76943
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
76790
76944
  const response = await dispatchRaw("query", "nexus", "shape-check", { routeSymbol, projectId });
76791
76945
  const durationMs = Date.now() - startTime;
@@ -77181,7 +77335,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
77181
77335
  async run({ args }) {
77182
77336
  applyJsonFlag2(args.json);
77183
77337
  const startTime = Date.now();
77184
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
77338
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot64();
77185
77339
  const projectIdOverride = args["project-id"];
77186
77340
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
77187
77341
  const response = await dispatchRaw("mutate", "nexus", "contracts-sync", {
@@ -77291,7 +77445,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
77291
77445
  async run({ args }) {
77292
77446
  applyJsonFlag2(args.json);
77293
77447
  const startTime = Date.now();
77294
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
77448
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot64();
77295
77449
  const projectId = Buffer.from(repoPath).toString("base64url").slice(0, 32);
77296
77450
  const response = await dispatchRaw("mutate", "nexus", "contracts-link-tasks", {
77297
77451
  projectId,
@@ -77375,7 +77529,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
77375
77529
  const isIncremental = !!args.incremental;
77376
77530
  try {
77377
77531
  const result = await runNexusWiki({
77378
- projectRoot: getProjectRoot63(),
77532
+ projectRoot: getProjectRoot64(),
77379
77533
  outputDir,
77380
77534
  communityFilter,
77381
77535
  incremental: isIncremental
@@ -77725,7 +77879,7 @@ __export(orchestrate_exports, {
77725
77879
  });
77726
77880
  import { execFileSync as execFileSync5 } from "node:child_process";
77727
77881
  import { orchestration } from "@cleocode/core";
77728
- import { BUILD_CONFIG as BUILD_CONFIG2, getProjectRoot as getProjectRoot64 } from "@cleocode/core/internal";
77882
+ import { BUILD_CONFIG as BUILD_CONFIG2, getProjectRoot as getProjectRoot65 } from "@cleocode/core/internal";
77729
77883
  function formatRollupTable(rollup) {
77730
77884
  const waves = "waves" in rollup ? rollup.waves : [rollup];
77731
77885
  const lines = [];
@@ -77868,7 +78022,7 @@ var init_orchestrate3 = __esm({
77868
78022
  },
77869
78023
  async run({ args }) {
77870
78024
  const rateWindowHours = args.window !== void 0 ? Number.parseFloat(String(args.window)) : void 0;
77871
- const metrics = await orchestration.collectOrchestrateDashboard(getProjectRoot64(), {
78025
+ const metrics = await orchestration.collectOrchestrateDashboard(getProjectRoot65(), {
77872
78026
  ...rateWindowHours !== void 0 && Number.isFinite(rateWindowHours) && rateWindowHours > 0 ? { rateWindowHours } : {}
77873
78027
  });
77874
78028
  cliOutput(metrics, {
@@ -79328,7 +79482,7 @@ __export(project_exports, {
79328
79482
  import { resolve as resolve9 } from "node:path";
79329
79483
  import {
79330
79484
  CleoError as CleoError11,
79331
- getProjectRoot as getProjectRoot65,
79485
+ getProjectRoot as getProjectRoot66,
79332
79486
  moveProject,
79333
79487
  projectLifecycle,
79334
79488
  renameProject,
@@ -79350,7 +79504,7 @@ function emitEngineFailure(error, operation) {
79350
79504
  }
79351
79505
  function resolveRootOrFail(operation) {
79352
79506
  try {
79353
- return getProjectRoot65();
79507
+ return getProjectRoot66();
79354
79508
  } catch (err) {
79355
79509
  const code = err instanceof CleoError11 && typeof err.details?.["code"] === "string" ? err.details["code"] : "E_NOT_CLEO_PROJECT";
79356
79510
  emitEngineFailure(
@@ -80178,7 +80332,7 @@ var refresh_memory_exports = {};
80178
80332
  __export(refresh_memory_exports, {
80179
80333
  refreshMemoryCommand: () => refreshMemoryCommand
80180
80334
  });
80181
- import { getProjectRoot as getProjectRoot66 } from "@cleocode/core";
80335
+ import { getProjectRoot as getProjectRoot67 } from "@cleocode/core";
80182
80336
  var refreshMemoryCommand;
80183
80337
  var init_refresh_memory = __esm({
80184
80338
  "packages/cleo/src/cli/commands/refresh-memory.ts"() {
@@ -80191,7 +80345,7 @@ var init_refresh_memory = __esm({
80191
80345
  description: "Regenerate .cleo/memory-bridge.md from brain.db"
80192
80346
  },
80193
80347
  async run() {
80194
- const projectDir = getProjectRoot66();
80348
+ const projectDir = getProjectRoot67();
80195
80349
  const { writeMemoryBridge } = await import("@cleocode/core/internal");
80196
80350
  const result = await writeMemoryBridge(projectDir);
80197
80351
  if (result.written) {
@@ -81777,7 +81931,7 @@ import fs3 from "node:fs";
81777
81931
  import path5 from "node:path";
81778
81932
  import {
81779
81933
  CleoError as CleoError13,
81780
- getProjectRoot as getProjectRoot67,
81934
+ getProjectRoot as getProjectRoot68,
81781
81935
  getTaskAccessor as getTaskAccessor3,
81782
81936
  parseConflictReport,
81783
81937
  setAtPath
@@ -81798,7 +81952,7 @@ var init_restore = __esm({
81798
81952
  description: "Apply manually-resolved conflicts from .cleo/restore-conflicts.md"
81799
81953
  },
81800
81954
  async run() {
81801
- const projectRoot = getProjectRoot67();
81955
+ const projectRoot = getProjectRoot68();
81802
81956
  const reportPath = path5.join(projectRoot, CLEO_DIR_NAME3, RESTORE_CONFLICTS_MD);
81803
81957
  if (!fs3.existsSync(reportPath)) {
81804
81958
  humanLine("No pending restore conflicts. Nothing to finalize.");
@@ -82727,8 +82881,8 @@ var init_saga = __esm({
82727
82881
  }
82728
82882
  },
82729
82883
  async run({ args }) {
82730
- const { sagas: sagas2, getProjectRoot: getProjectRoot73 } = await import("@cleocode/core");
82731
- const projectRoot = getProjectRoot73();
82884
+ const { sagas: sagas2, getProjectRoot: getProjectRoot74 } = await import("@cleocode/core");
82885
+ const projectRoot = getProjectRoot74();
82732
82886
  const sagaId = typeof args.sagaId === "string" && args.sagaId.length > 0 ? args.sagaId : void 0;
82733
82887
  const result = await sagas2.sagaNext(projectRoot, { sagaId });
82734
82888
  cliOutput(result.success ? result.data : result, { command: "saga", operation: "saga.next" });
@@ -84559,7 +84713,7 @@ var sequence_exports = {};
84559
84713
  __export(sequence_exports, {
84560
84714
  sequenceCommand: () => sequenceCommand
84561
84715
  });
84562
- import { getProjectRoot as getProjectRoot68 } from "@cleocode/core/internal";
84716
+ import { getProjectRoot as getProjectRoot69 } from "@cleocode/core/internal";
84563
84717
  var showCommand12, checkCommand7, repairCommand3, sequenceCommand;
84564
84718
  var init_sequence = __esm({
84565
84719
  "packages/cleo/src/cli/commands/sequence.ts"() {
@@ -84595,7 +84749,7 @@ var init_sequence = __esm({
84595
84749
  meta: { name: "repair", description: "Reset counter to max + 1 if behind" },
84596
84750
  async run() {
84597
84751
  const { repairSequence } = await import("@cleocode/core/internal");
84598
- const projectRoot = getProjectRoot68();
84752
+ const projectRoot = getProjectRoot69();
84599
84753
  const repair = await repairSequence(projectRoot);
84600
84754
  const result = {
84601
84755
  repaired: repair.repaired,
@@ -85192,8 +85346,8 @@ var init_session4 = __esm({
85192
85346
  "audit-scope": { type: "string", description: "Audit log scope (global|local)" }
85193
85347
  },
85194
85348
  async run({ args }) {
85195
- const { detectSessionDrift, getProjectRoot: getProjectRoot73 } = await import("@cleocode/core");
85196
- const projectRoot = await getProjectRoot73();
85349
+ const { detectSessionDrift, getProjectRoot: getProjectRoot74 } = await import("@cleocode/core");
85350
+ const projectRoot = await getProjectRoot74();
85197
85351
  const scope = args["audit-scope"] === "local" ? "local" : "global";
85198
85352
  const report = await detectSessionDrift({ projectRoot, auditScope: scope });
85199
85353
  cliOutput(report, { command: "session drift", operation: "session.drift" });
@@ -87894,13 +88048,13 @@ var init_telemetry2 = __esm({
87894
88048
  // packages/cleo/src/cli/commands/templates/lib.ts
87895
88049
  import { readFileSync as readFileSync13 } from "node:fs";
87896
88050
  import { isAbsolute as isAbsolute3, resolve as resolve10 } from "node:path";
87897
- import { getProjectRoot as getProjectRoot69 } from "@cleocode/core";
88051
+ import { getProjectRoot as getProjectRoot70 } from "@cleocode/core";
87898
88052
  import { resolveSourcePathAbsolute } from "@cleocode/core/templates/registry";
87899
88053
  function resolveProjectRoot6(raw) {
87900
88054
  if (typeof raw === "string" && raw.length > 0) {
87901
88055
  return isAbsolute3(raw) ? raw : resolve10(process.cwd(), raw);
87902
88056
  }
87903
- return getProjectRoot69();
88057
+ return getProjectRoot70();
87904
88058
  }
87905
88059
  function readTemplateSource(entry) {
87906
88060
  const sourceAbsolute = resolveSourcePathAbsolute(entry);
@@ -88684,7 +88838,7 @@ __export(token_exports, {
88684
88838
  tokenCommand: () => tokenCommand
88685
88839
  });
88686
88840
  import { readFileSync as readFileSync17 } from "node:fs";
88687
- import { getProjectRoot as getProjectRoot70, measureTokenExchange, recordTokenExchange as recordTokenExchange2 } from "@cleocode/core/internal";
88841
+ import { getProjectRoot as getProjectRoot71, measureTokenExchange, recordTokenExchange as recordTokenExchange2 } from "@cleocode/core/internal";
88688
88842
  function readPayload(args, textKey, fileKey) {
88689
88843
  const text = args[textKey];
88690
88844
  const file = args[fileKey];
@@ -88848,7 +89002,7 @@ var init_token = __esm({
88848
89002
  domain: args.domain,
88849
89003
  operation: args.operation
88850
89004
  };
88851
- const result = args.record ? await recordTokenExchange2(getProjectRoot70(), input2) : await measureTokenExchange(input2);
89005
+ const result = args.record ? await recordTokenExchange2(getProjectRoot71(), input2) : await measureTokenExchange(input2);
88852
89006
  cliOutput(result, {
88853
89007
  command: "token",
88854
89008
  operation: args.record ? "admin.token.record" : "token.estimate"
@@ -88884,7 +89038,7 @@ __export(transcript_exports, {
88884
89038
  });
88885
89039
  import { homedir as homedir3 } from "node:os";
88886
89040
  import { join as join35 } from "node:path";
88887
- import { getProjectRoot as getProjectRoot71 } from "@cleocode/core";
89041
+ import { getProjectRoot as getProjectRoot72 } from "@cleocode/core";
88888
89042
  import {
88889
89043
  parseDurationMs,
88890
89044
  pruneTranscripts,
@@ -88914,7 +89068,7 @@ var init_transcript = __esm({
88914
89068
  async run({ args }) {
88915
89069
  if (args.pending) {
88916
89070
  try {
88917
- const projectRoot = getProjectRoot71();
89071
+ const projectRoot = getProjectRoot72();
88918
89072
  const { scanPendingTranscripts } = await import("@cleocode/core/memory/transcript-scanner.js");
88919
89073
  const pending = await scanPendingTranscripts(projectRoot);
88920
89074
  cliOutput(
@@ -89011,7 +89165,7 @@ var init_transcript = __esm({
89011
89165
  async run({ args }) {
89012
89166
  const tier = args.tier ?? "warm";
89013
89167
  const dryRun = args["dry-run"] ?? false;
89014
- const projectRoot = getProjectRoot71();
89168
+ const projectRoot = getProjectRoot72();
89015
89169
  try {
89016
89170
  const { extractTranscript } = await import("@cleocode/core/memory/transcript-extractor.js");
89017
89171
  const { findSessionTranscriptPath, listAllTranscripts } = await import("@cleocode/core/memory/transcript-scanner.js");
@@ -89127,7 +89281,7 @@ var init_transcript = __esm({
89127
89281
  const dryRun = args["dry-run"] ?? false;
89128
89282
  const olderThanHours = args["older-than-hours"] ? Number.parseInt(args["older-than-hours"], 10) : 24;
89129
89283
  const limit = args.limit ? Number.parseInt(args.limit, 10) : void 0;
89130
- const projectRoot = getProjectRoot71();
89284
+ const projectRoot = getProjectRoot72();
89131
89285
  try {
89132
89286
  const { extractTranscript } = await import("@cleocode/core/memory/transcript-extractor.js");
89133
89287
  const { listAllTranscripts } = await import("@cleocode/core/memory/transcript-scanner.js");
@@ -91065,9 +91219,9 @@ var init_verify = __esm({
91065
91219
  return;
91066
91220
  }
91067
91221
  const { recordTaskDone } = await import("@cleocode/core/tasks/done-record.js");
91068
- const { getProjectRoot: getProjectRoot73 } = await import("@cleocode/core/paths.js");
91222
+ const { getProjectRoot: getProjectRoot74 } = await import("@cleocode/core/paths.js");
91069
91223
  const r = await recordTaskDone(args.taskId, {
91070
- projectRoot: getProjectRoot73(),
91224
+ projectRoot: getProjectRoot74(),
91071
91225
  ...parsed.options,
91072
91226
  ...args.agent ? { agent: args.agent } : {}
91073
91227
  });
@@ -91490,9 +91644,9 @@ var init_workgraph2 = __esm({
91490
91644
  },
91491
91645
  async run({ args }) {
91492
91646
  const { generatePlanningDoc } = await import("@cleocode/core/workgraph");
91493
- const { getProjectRoot: getProjectRoot73 } = await import("@cleocode/core");
91647
+ const { getProjectRoot: getProjectRoot74 } = await import("@cleocode/core");
91494
91648
  const { cliOutput: cliOutput2 } = await Promise.resolve().then(() => (init_renderers(), renderers_exports));
91495
- const projectRoot = getProjectRoot73();
91649
+ const projectRoot = getProjectRoot74();
91496
91650
  const audience = String(args.audience) === "agent" ? "agent" : "maintainer";
91497
91651
  const result = await generatePlanningDoc(projectRoot, {
91498
91652
  sagaId: String(args.sagaId),
@@ -91509,9 +91663,9 @@ var init_workgraph2 = __esm({
91509
91663
  async run() {
91510
91664
  const { validateWorkGraphStructure } = await import("@cleocode/core/workgraph");
91511
91665
  const { taskList: taskList2 } = await import("@cleocode/core/internal");
91512
- const { getProjectRoot: getProjectRoot73 } = await import("@cleocode/core");
91666
+ const { getProjectRoot: getProjectRoot74 } = await import("@cleocode/core");
91513
91667
  const { cliOutput: cliOutput2 } = await Promise.resolve().then(() => (init_renderers(), renderers_exports));
91514
- const projectRoot = getProjectRoot73();
91668
+ const projectRoot = getProjectRoot74();
91515
91669
  const listResult = await taskList2(projectRoot, { limit: 5e3 });
91516
91670
  const tasks = listResult.success ? listResult.data?.tasks ?? [] : [];
91517
91671
  const nodes = tasks.map((t) => ({
@@ -91530,9 +91684,9 @@ var init_workgraph2 = __esm({
91530
91684
  description: "One-shot saga-to-saga workgraph dashboard (tracking checklist)"
91531
91685
  },
91532
91686
  async run() {
91533
- const { sagas: sagas2, getProjectRoot: getProjectRoot73 } = await import("@cleocode/core");
91687
+ const { sagas: sagas2, getProjectRoot: getProjectRoot74 } = await import("@cleocode/core");
91534
91688
  const { cliOutput: cliOutput2 } = await Promise.resolve().then(() => (init_renderers(), renderers_exports));
91535
- const projectRoot = getProjectRoot73();
91689
+ const projectRoot = getProjectRoot74();
91536
91690
  const listResult = await sagas2.sagaList(projectRoot);
91537
91691
  if (!listResult.success) {
91538
91692
  cliOutput2(listResult, { command: "workgraph", operation: "workgraph.status" });
@@ -91598,7 +91752,7 @@ __export(worktree_exports, {
91598
91752
  worktreeCommand: () => worktreeCommand
91599
91753
  });
91600
91754
  import readline4 from "node:readline";
91601
- import { getProjectRoot as getProjectRoot72, listWorktrees as listWorktrees2 } from "@cleocode/core/internal";
91755
+ import { getProjectRoot as getProjectRoot73, listWorktrees as listWorktrees2 } from "@cleocode/core/internal";
91602
91756
  async function promptYesNo2(question) {
91603
91757
  return new Promise((resolve13) => {
91604
91758
  const rl = readline4.createInterface({ input: process.stdin, output: process.stdout });
@@ -91703,7 +91857,7 @@ var init_worktree3 = __esm({
91703
91857
  const staleDays = staleDaysRaw !== void 0 ? Number.parseInt(staleDaysRaw, 10) : void 0;
91704
91858
  const idleDaysRaw = typeof args["idle-days"] === "string" ? args["idle-days"] : void 0;
91705
91859
  const idleDays = idleDaysRaw !== void 0 ? Number.parseInt(idleDaysRaw, 10) : void 0;
91706
- const projectRoot = getProjectRoot72();
91860
+ const projectRoot = getProjectRoot73();
91707
91861
  const listResult = await listWorktrees2({
91708
91862
  projectRoot,
91709
91863
  ...staleDays !== void 0 && !Number.isNaN(staleDays) ? { staleDays } : {}
@@ -91962,6 +92116,16 @@ function cittyErrorFix(code) {
91962
92116
  return `Run 'cleo <command> --help' to see required arguments.`;
91963
92117
  }
91964
92118
 
92119
+ // packages/cleo/src/cli/cleo-error-like.ts
92120
+ function asCleoErrorLike(err) {
92121
+ if (!(err instanceof Error)) return null;
92122
+ const candidate = err;
92123
+ return typeof candidate.code === "number" && Number.isInteger(candidate.code) && typeof candidate.toLAFSError === "function" ? candidate : null;
92124
+ }
92125
+ function cleoErrorCodeName(typed) {
92126
+ return typeof typed.codeName === "string" && typed.codeName.length > 0 ? typed.codeName : typed.toLAFSError().code;
92127
+ }
92128
+
91965
92129
  // packages/cleo/src/cli/index.ts
91966
92130
  init_describe_context();
91967
92131
  init_field_context();
@@ -92287,6 +92451,12 @@ var COMMAND_MANIFEST = [
92287
92451
  description: "Canonical six-verb docs path: add, update, fetch, list, remove, publish. ",
92288
92452
  load: async () => (await Promise.resolve().then(() => (init_docs3(), docs_exports))).docsCommand
92289
92453
  },
92454
+ {
92455
+ exportName: "doctorAcBindingsCommand",
92456
+ name: "ac-bindings",
92457
+ description: "Report evidence bindings whose acceptance criterion no longer exists (dangling ",
92458
+ load: async () => (await Promise.resolve().then(() => (init_doctor_ac_bindings(), doctor_ac_bindings_exports))).doctorAcBindingsCommand
92459
+ },
92290
92460
  {
92291
92461
  exportName: "doctorAcceptanceDriftCommand",
92292
92462
  name: "acceptance-drift",
@@ -92350,7 +92520,7 @@ var COMMAND_MANIFEST = [
92350
92520
  {
92351
92521
  exportName: "doctorManifestRowsCommand",
92352
92522
  name: "manifest-rows",
92353
- description: "List manifest rows whose metadata violates the stored field contract. --repair shows the plan (writes nothing); --repair --apply moves each bad field under _malformed (nothing lost) with a receipt; --rollback <receipt> undoes it.",
92523
+ description: "List manifest rows whose metadata violates the stored field contract, and (read-only) rows with an invalid id, linked task id or file reference. --repair shows the plan (writes nothing); --repair --apply moves each bad field under _malformed (nothing lost) with a receipt; --rollback <receipt> undoes it.",
92354
92524
  load: async () => (await Promise.resolve().then(() => (init_doctor_manifest_rows(), doctor_manifest_rows_exports))).doctorManifestRowsCommand
92355
92525
  },
92356
92526
  {
@@ -93548,11 +93718,6 @@ Valid modes: ${validModes.join(", ")}
93548
93718
  const dispatchArgv = describeFlag && !isHelpOrVersion ? [...normalizedArgv, "__cleo_describe__"] : normalizedArgv;
93549
93719
  await runMainWithLafsEnvelope(main, dispatchArgv, customShowUsage);
93550
93720
  }
93551
- function asCleoErrorLike(err) {
93552
- if (!(err instanceof Error) || err.name !== "CleoError") return null;
93553
- const candidate = err;
93554
- return typeof candidate.code === "number" && typeof candidate.toLAFSError === "function" ? candidate : null;
93555
- }
93556
93721
  function asCittyCliError(value) {
93557
93722
  if (!(value instanceof Error)) return null;
93558
93723
  if (value.name !== "CLIError") return null;
@@ -93632,7 +93797,7 @@ async function runMainWithLafsEnvelope(cmd, rawArgs, showUsage2) {
93632
93797
  const typed = asCleoErrorLike(err);
93633
93798
  if (typed) {
93634
93799
  cliError2(typed.message, typed.code, {
93635
- name: typed.toLAFSError().code,
93800
+ name: cleoErrorCodeName(typed),
93636
93801
  fix: typed.fix,
93637
93802
  alternatives: typed.alternatives,
93638
93803
  details: typed.details
@@ -93658,7 +93823,7 @@ async function runStartupMaintenance() {
93658
93823
  detectAndRemoveStrayProjectNexus,
93659
93824
  getGlobalSalt,
93660
93825
  getLogger: getLogger22,
93661
- getProjectRoot: getProjectRoot73,
93826
+ getProjectRoot: getProjectRoot74,
93662
93827
  isCleanupMarkerSet,
93663
93828
  isMissingProjectError,
93664
93829
  migrateSignaldockToConduit,
@@ -93668,7 +93833,7 @@ async function runStartupMaintenance() {
93668
93833
  } = await import("@cleocode/core/internal");
93669
93834
  let projectRootForCleanup = "";
93670
93835
  try {
93671
- projectRootForCleanup = getProjectRoot73();
93836
+ projectRootForCleanup = getProjectRoot74();
93672
93837
  } catch {
93673
93838
  }
93674
93839
  if (!isCleanupMarkerSet(CLI_VERSION, projectRootForCleanup)) {
@@ -93688,7 +93853,7 @@ async function runStartupMaintenance() {
93688
93853
  const isInitInvocation = process.argv.slice(2).some((a) => a === "init");
93689
93854
  if (!isInitInvocation) {
93690
93855
  try {
93691
- const _projectRootForMigration = getProjectRoot73();
93856
+ const _projectRootForMigration = getProjectRoot74();
93692
93857
  if (needsSignaldockToConduitMigration(_projectRootForMigration)) {
93693
93858
  const migrationResult = await migrateSignaldockToConduit(_projectRootForMigration);
93694
93859
  if (migrationResult.status === "failed") {