@remnic/core 10.0.55 → 10.0.56

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 (35) hide show
  1. package/dist/access-cli.js +8 -8
  2. package/dist/access-http-query.js +2 -2
  3. package/dist/access-http.js +3 -3
  4. package/dist/{chunk-PVG7TCUG.js → chunk-5C44AMRV.js} +2 -2
  5. package/dist/{chunk-2GU6XS4L.js → chunk-CC2ESKHP.js} +7 -7
  6. package/dist/{chunk-R3WZ74B2.js → chunk-CZS7UTXL.js} +5 -3
  7. package/dist/chunk-CZS7UTXL.js.map +1 -0
  8. package/dist/{chunk-4BUJICMI.js → chunk-FCAXGYDT.js} +2 -2
  9. package/dist/{chunk-GGFQAGOT.js → chunk-GMRP3HN3.js} +2 -2
  10. package/dist/{chunk-Y56D5FSD.js → chunk-OGR52N7A.js} +3 -3
  11. package/dist/{chunk-XVTB6BZS.js → chunk-S3OI5DP5.js} +22 -10
  12. package/dist/chunk-S3OI5DP5.js.map +1 -0
  13. package/dist/{chunk-WGFEGBFB.js → chunk-VZ7VJGPL.js} +2 -2
  14. package/dist/cli.js +6 -6
  15. package/dist/index.js +8 -8
  16. package/dist/maintenance/namespace-planner.d.ts.map +1 -1
  17. package/dist/namespaces/catalog.d.ts +9 -1
  18. package/dist/namespaces/catalog.d.ts.map +1 -1
  19. package/dist/operator-toolkit.js +3 -3
  20. package/dist/orchestration/maintenance.js +3 -3
  21. package/dist/orchestrator.js +8 -8
  22. package/package.json +2 -2
  23. package/src/maintenance/namespace-planner.test.ts +41 -1
  24. package/src/maintenance/namespace-planner.ts +8 -1
  25. package/src/namespaces/catalog.test.ts +83 -0
  26. package/src/namespaces/catalog.ts +46 -10
  27. package/src/orchestration/maintenance.test.ts +33 -1
  28. package/dist/chunk-R3WZ74B2.js.map +0 -1
  29. package/dist/chunk-XVTB6BZS.js.map +0 -1
  30. /package/dist/{chunk-PVG7TCUG.js.map → chunk-5C44AMRV.js.map} +0 -0
  31. /package/dist/{chunk-2GU6XS4L.js.map → chunk-CC2ESKHP.js.map} +0 -0
  32. /package/dist/{chunk-4BUJICMI.js.map → chunk-FCAXGYDT.js.map} +0 -0
  33. /package/dist/{chunk-GGFQAGOT.js.map → chunk-GMRP3HN3.js.map} +0 -0
  34. /package/dist/{chunk-Y56D5FSD.js.map → chunk-OGR52N7A.js.map} +0 -0
  35. /package/dist/{chunk-WGFEGBFB.js.map → chunk-VZ7VJGPL.js.map} +0 -0
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  Orchestrator
3
- } from "./chunk-2GU6XS4L.js";
3
+ } from "./chunk-CC2ESKHP.js";
4
4
  import "./chunk-YDIOMDBW.js";
5
5
  import "./chunk-HM3ZTDAX.js";
6
6
  import "./chunk-5PHOU5QI.js";
7
- import "./chunk-PVG7TCUG.js";
7
+ import "./chunk-5C44AMRV.js";
8
8
  import "./chunk-I74SUMNI.js";
9
9
  import "./chunk-ILNPU5W5.js";
10
10
  import "./chunk-VZAKYDMJ.js";
@@ -115,7 +115,7 @@ import "./chunk-PYIR4SSB.js";
115
115
  import "./chunk-7G5NTS7F.js";
116
116
  import "./chunk-FFQNNFHX.js";
117
117
  import "./chunk-3I4FUAVJ.js";
118
- import "./chunk-Y56D5FSD.js";
118
+ import "./chunk-OGR52N7A.js";
119
119
  import "./chunk-MMACM5G2.js";
120
120
  import "./chunk-54BGIBCR.js";
121
121
  import "./chunk-H4CKS5B2.js";
@@ -158,8 +158,8 @@ import "./chunk-HDN7IVIO.js";
158
158
  import "./chunk-LR7RW4T6.js";
159
159
  import "./chunk-3T74IZB3.js";
160
160
  import "./chunk-2LA3H54D.js";
161
- import "./chunk-GGFQAGOT.js";
162
- import "./chunk-R3WZ74B2.js";
161
+ import "./chunk-GMRP3HN3.js";
162
+ import "./chunk-CZS7UTXL.js";
163
163
  import "./chunk-KFY3SGN7.js";
164
164
  import {
165
165
  resolvePluginEntry
@@ -236,7 +236,7 @@ import "./chunk-27NO2KVB.js";
236
236
  import "./chunk-KFZY2OFH.js";
237
237
  import "./chunk-B32WYRXX.js";
238
238
  import "./chunk-QW27DOHG.js";
239
- import "./chunk-4BUJICMI.js";
239
+ import "./chunk-FCAXGYDT.js";
240
240
  import "./chunk-V7IZKJI3.js";
241
241
  import "./chunk-TB6CBZ5V.js";
242
242
  import "./chunk-XW2T4QAW.js";
@@ -281,8 +281,8 @@ import "./chunk-2FLFJTCI.js";
281
281
  import "./chunk-JATHBCAV.js";
282
282
  import "./chunk-ZQUVBZI4.js";
283
283
  import "./chunk-5R627MYY.js";
284
- import "./chunk-WGFEGBFB.js";
285
- import "./chunk-XVTB6BZS.js";
284
+ import "./chunk-VZ7VJGPL.js";
285
+ import "./chunk-S3OI5DP5.js";
286
286
  import "./chunk-AB3A7EFH.js";
287
287
  import "./chunk-KIUVEMBI.js";
288
288
  import "./chunk-HJ4X4BGS.js";
@@ -3,8 +3,8 @@ import {
3
3
  optionalNamespaceKindQueryParam,
4
4
  optionalQueryString,
5
5
  positiveIntQueryParam
6
- } from "./chunk-WGFEGBFB.js";
7
- import "./chunk-XVTB6BZS.js";
6
+ } from "./chunk-VZ7VJGPL.js";
7
+ import "./chunk-S3OI5DP5.js";
8
8
  import "./chunk-QF5EJ5VP.js";
9
9
  import "./chunk-W4F3C7N7.js";
10
10
  import "./chunk-MPC7TYTZ.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  EngramAccessHttpServer,
3
3
  resolveDefaultAdminConsolePublicDir
4
- } from "./chunk-4BUJICMI.js";
4
+ } from "./chunk-FCAXGYDT.js";
5
5
  import "./chunk-V7IZKJI3.js";
6
6
  import "./chunk-TB6CBZ5V.js";
7
7
  import "./chunk-XW2T4QAW.js";
@@ -46,8 +46,8 @@ import "./chunk-2FLFJTCI.js";
46
46
  import "./chunk-JATHBCAV.js";
47
47
  import "./chunk-ZQUVBZI4.js";
48
48
  import "./chunk-5R627MYY.js";
49
- import "./chunk-WGFEGBFB.js";
50
- import "./chunk-XVTB6BZS.js";
49
+ import "./chunk-VZ7VJGPL.js";
50
+ import "./chunk-S3OI5DP5.js";
51
51
  import "./chunk-AB3A7EFH.js";
52
52
  import "./chunk-KIUVEMBI.js";
53
53
  import "./chunk-HJ4X4BGS.js";
@@ -25,7 +25,7 @@ import {
25
25
  import {
26
26
  planNamespaceMaintenance,
27
27
  runNamespaceMaintenanceBatchPlan
28
- } from "./chunk-R3WZ74B2.js";
28
+ } from "./chunk-CZS7UTXL.js";
29
29
  import {
30
30
  rebuildMemoryProjection
31
31
  } from "./chunk-QAHP5SBG.js";
@@ -2874,4 +2874,4 @@ export {
2874
2874
  ActivitySyncScheduler,
2875
2875
  MaintenanceScheduler
2876
2876
  };
2877
- //# sourceMappingURL=chunk-PVG7TCUG.js.map
2877
+ //# sourceMappingURL=chunk-5C44AMRV.js.map
@@ -13,7 +13,7 @@ import {
13
13
  import {
14
14
  ActivityStore,
15
15
  MaintenanceScheduler
16
- } from "./chunk-PVG7TCUG.js";
16
+ } from "./chunk-5C44AMRV.js";
17
17
  import {
18
18
  runPeerProfileReasoner
19
19
  } from "./chunk-I74SUMNI.js";
@@ -234,7 +234,7 @@ import {
234
234
  runTimelinePublishCli,
235
235
  screenCandidateFact,
236
236
  summarizeVaultPublish
237
- } from "./chunk-Y56D5FSD.js";
237
+ } from "./chunk-OGR52N7A.js";
238
238
  import {
239
239
  RoutingRulesStore
240
240
  } from "./chunk-TBUEE7XF.js";
@@ -264,10 +264,10 @@ import {
264
264
  import {
265
265
  runNamespaceMaintenanceFanout,
266
266
  summarizeNamespaceMaintenanceHealth
267
- } from "./chunk-GGFQAGOT.js";
267
+ } from "./chunk-GMRP3HN3.js";
268
268
  import {
269
269
  planNamespaceMaintenance
270
- } from "./chunk-R3WZ74B2.js";
270
+ } from "./chunk-CZS7UTXL.js";
271
271
  import {
272
272
  isAboveImportanceThreshold,
273
273
  scoreImportance
@@ -373,7 +373,7 @@ import {
373
373
  } from "./chunk-QW27DOHG.js";
374
374
  import {
375
375
  MeetingsInputError
376
- } from "./chunk-4BUJICMI.js";
376
+ } from "./chunk-FCAXGYDT.js";
377
377
  import {
378
378
  WearablesInputError,
379
379
  describeErrorForOperator
@@ -391,7 +391,7 @@ import {
391
391
  } from "./chunk-AAANTXCQ.js";
392
392
  import {
393
393
  NamespaceCatalog
394
- } from "./chunk-XVTB6BZS.js";
394
+ } from "./chunk-S3OI5DP5.js";
395
395
  import {
396
396
  RecallResultFormatter,
397
397
  SessionContextCoordinator,
@@ -31617,4 +31617,4 @@ export {
31617
31617
  qmdStartupCollectionChecksWithTimeout,
31618
31618
  Orchestrator
31619
31619
  };
31620
- //# sourceMappingURL=chunk-2GU6XS4L.js.map
31620
+ //# sourceMappingURL=chunk-CC2ESKHP.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  hasMemoryData
3
- } from "./chunk-XVTB6BZS.js";
3
+ } from "./chunk-S3OI5DP5.js";
4
4
  import {
5
5
  resolveNamespaceStorageRoot
6
6
  } from "./chunk-34UVJNSG.js";
@@ -118,7 +118,9 @@ async function planNamespaceMaintenance(config, options) {
118
118
  if (resolveNamespaceCapabilities(config).namespaces && resolveConversationContextCapabilities(config).maintenanceNamespaceFanout !== false) {
119
119
  const configuredSet = new Set(configured);
120
120
  try {
121
- const records = options.catalog?.enabled ? await options.catalog.listNamespaces() : [];
121
+ const records = options.catalog?.enabled ? await options.catalog.listNamespaces(void 0, {
122
+ onIncomplete: (reason) => skipped.push({ namespace: "*", reason: "catalog_read_failed", detail: reason })
123
+ }) : [];
122
124
  for (const record of records) {
123
125
  const namespace = record.namespace.trim();
124
126
  if (!namespace) continue;
@@ -724,4 +726,4 @@ export {
724
726
  runNamespaceMaintenancePlan,
725
727
  runNamespaceMaintenanceBatchPlan
726
728
  };
727
- //# sourceMappingURL=chunk-R3WZ74B2.js.map
729
+ //# sourceMappingURL=chunk-CZS7UTXL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/maintenance/namespace-planner.ts"],"sourcesContent":["import { resolveNamespaceCapabilities } from \"../capabilities.js\";\nimport { createHash, randomUUID } from \"node:crypto\";\nimport type { Dirent } from \"node:fs\";\nimport { lstat, mkdir, open, readFile, readdir, rename, rm, rmdir, stat, utimes, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { NamespaceCatalog, NamespaceKind, NamespaceRecord } from \"../namespaces/catalog.js\";\nimport { hasMemoryData } from \"../namespaces/catalog.js\";\nimport { namespaceIdentityToken } from \"../namespaces/identity.js\";\nimport { resolveNamespaceStorageRoot } from \"../namespaces/storage.js\";\nimport { displayErrorDetail } from \"../runtime/better-sqlite.js\";\nimport type { PluginConfig } from \"../types.js\";\nimport { getConfiguredNamespaces } from \"../scopes/scope-plan.js\";\nimport { resolveConversationContextCapabilities } from \"../capabilities.js\";\n\nexport type NamespaceMaintenanceJobName = string;\n\nexport type NamespaceMaintenanceSkipReason =\n | \"fanout_disabled\"\n | \"empty_root\"\n | \"branch_disabled\"\n | \"project_disabled\"\n | \"team_project_disabled\"\n | \"catalog_read_failed\"\n | \"unsafe_or_stale_root\"\n | \"budget_exhausted\"\n | \"lock_held\"\n | \"batch_lock_incomplete\"\n | \"throttled\"\n | \"job_failed\";\n\nexport interface NamespaceMaintenancePlannerOptions {\n jobName: NamespaceMaintenanceJobName;\n catalog?: NamespaceCatalog;\n now?: Date;\n budgetMode?: \"cycle\" | \"unbounded\";\n}\n\nexport interface NamespaceMaintenanceCandidate {\n namespace: string;\n kind: NamespaceKind;\n storageDir?: string;\n source: \"configured\" | \"catalog\";\n lastWriteAt?: string;\n lastMaintenanceAt?: string;\n}\n\nexport interface NamespaceMaintenancePlan {\n jobName: NamespaceMaintenanceJobName;\n generatedAt: string;\n namespaces: NamespaceMaintenanceCandidate[];\n skipped: NamespaceMaintenanceSkippedNamespace[];\n budget: {\n maxNamespacesPerCycle: number;\n selected: number;\n };\n}\n\nexport interface NamespaceMaintenanceSkippedNamespace {\n namespace: string;\n kind?: NamespaceKind;\n reason: NamespaceMaintenanceSkipReason;\n detail?: string;\n}\n\nexport interface NamespaceMaintenanceRunStatus {\n namespace: string;\n jobName: NamespaceMaintenanceJobName;\n state: \"ran\" | \"skipped\" | \"failed\";\n reason?: NamespaceMaintenanceSkipReason;\n startedAt: string;\n completedAt: string;\n itemCount?: number;\n error?: string;\n}\n\nexport interface NamespaceMaintenanceSummary {\n jobName: NamespaceMaintenanceJobName;\n generatedAt: string;\n ran: number;\n skipped: number;\n failed: number;\n statuses: NamespaceMaintenanceRunStatus[];\n}\n\nexport interface NamespaceMaintenanceBatchRunResult {\n itemCount?: number;\n itemCounts?: Record<string, number> | Map<string, number>;\n}\n\nexport interface NamespaceMaintenanceBatchRunOptions {\n requireAllLocks?: boolean;\n skipReasonForError?: (error: unknown) => NamespaceMaintenanceSkipReason | null | undefined;\n}\n\ninterface LockHandle {\n path: string;\n touch(): Promise<void>;\n release(): Promise<void>;\n}\n\nconst DEFAULT_MAX_NAMESPACES_PER_CYCLE = 20;\nconst DEFAULT_LOCK_STALE_MS = 10 * 60_000;\nconst LOCK_BASE = \"maintenance-locks\";\nconst STATUS_BASE = \"namespace-maintenance-status\";\nconst namespaceMaintenanceFs = { open, rm };\n\nexport function __setNamespaceMaintenanceFsForTest(overrides: Partial<typeof namespaceMaintenanceFs>): () => void {\n const previous = { ...namespaceMaintenanceFs };\n Object.assign(namespaceMaintenanceFs, overrides);\n return () => {\n Object.assign(namespaceMaintenanceFs, previous);\n };\n}\n\n\n\nfunction inferConfiguredKind(config: PluginConfig, namespace: string): NamespaceKind {\n if (namespace === config.defaultNamespace.trim()) return \"default\";\n if (namespace === config.sharedNamespace.trim()) return \"shared\";\n return \"explicit\";\n}\n\nfunction maxNamespacesPerCycle(config: PluginConfig): number {\n return Math.max(\n 1,\n Math.floor(\n typeof config.maintenanceMaxNamespacesPerCycle === \"number\" &&\n Number.isFinite(config.maintenanceMaxNamespacesPerCycle)\n ? config.maintenanceMaxNamespacesPerCycle\n : DEFAULT_MAX_NAMESPACES_PER_CYCLE\n )\n );\n}\n\nfunction namespaceKindAllowed(config: PluginConfig, kind: NamespaceKind): boolean {\n switch (kind) {\n case \"branch\":\n return config.maintenanceIncludeBranchNamespaces === true;\n case \"project\":\n return config.maintenanceIncludeProjectNamespaces !== false;\n case \"team-project\":\n return config.maintenanceIncludeTeamProjectNamespaces !== false;\n default:\n return true;\n }\n}\n\nfunction disabledReasonForKind(kind: NamespaceKind): NamespaceMaintenanceSkipReason {\n if (kind === \"branch\") return \"branch_disabled\";\n if (kind === \"project\") return \"project_disabled\";\n if (kind === \"team-project\") return \"team_project_disabled\";\n return \"fanout_disabled\";\n}\n\nasync function catalogRootIsLive(config: PluginConfig, record: NamespaceRecord): Promise<boolean> {\n if (typeof record.storageDir !== \"string\" || record.storageDir.length === 0) {\n return false;\n }\n try {\n const liveRoot = await resolveNamespaceStorageRoot(config, record.namespace);\n if (path.resolve(liveRoot) !== path.resolve(record.storageDir)) return false;\n return hasMemoryData(liveRoot);\n } catch {\n return false;\n }\n}\n\nfunction candidateSortKey(candidate: NamespaceMaintenanceCandidate): string {\n const write = candidate.lastWriteAt ?? \"\";\n return `${write}\\u0000${candidate.namespace}`;\n}\n\nfunction candidatePriority(candidate: NamespaceMaintenanceCandidate): number {\n if (candidate.kind === \"default\") return 0;\n if (candidate.kind === \"shared\") return 1;\n if (candidate.source === \"configured\") return 2;\n if (candidate.kind === \"team-project\") return 3;\n if (candidate.kind === \"project\") return 4;\n if (candidate.kind === \"branch\") return 8;\n return 7;\n}\n\nfunction sortCandidates(a: NamespaceMaintenanceCandidate, b: NamespaceMaintenanceCandidate): number {\n const priority = candidatePriority(a) - candidatePriority(b);\n if (priority !== 0) return priority;\n const am = Date.parse(a.lastMaintenanceAt ?? \"\");\n const bm = Date.parse(b.lastMaintenanceAt ?? \"\");\n const aMaintained = Number.isFinite(am);\n const bMaintained = Number.isFinite(bm);\n if (aMaintained && bMaintained && am !== bm) return am - bm;\n if (aMaintained !== bMaintained) return aMaintained ? 1 : -1;\n const aw = Date.parse(a.lastWriteAt ?? \"\");\n const bw = Date.parse(b.lastWriteAt ?? \"\");\n const aValid = Number.isFinite(aw);\n const bValid = Number.isFinite(bw);\n if (aValid && bValid && aw !== bw) return bw - aw;\n if (aValid !== bValid) return aValid ? -1 : 1;\n const byKey = candidateSortKey(a).localeCompare(candidateSortKey(b));\n if (byKey !== 0) return byKey;\n return a.namespace.localeCompare(b.namespace);\n}\n\nexport async function planNamespaceMaintenance(\n config: PluginConfig,\n options: NamespaceMaintenancePlannerOptions\n): Promise<NamespaceMaintenancePlan> {\n const generatedAt = (options.now ?? new Date()).toISOString();\n // When namespaces are disabled, storageFor() collapses every namespace name\n // to config.memoryDir. Seeding all configured namespaces (default + shared +\n // policies) would make a mutating maintenance job process the SAME corpus\n // once per configured name. The #1500 contract is \"namespaces disabled:\n // maintain the current default storage only,\" so collapse to the default.\n const configured = resolveNamespaceCapabilities(config).namespaces\n ? getConfiguredNamespaces(config)\n : [config.defaultNamespace.trim()].filter(Boolean);\n const byNamespace = new Map<string, NamespaceMaintenanceCandidate>();\n const skipped: NamespaceMaintenanceSkippedNamespace[] = [];\n\n for (const namespace of configured) {\n const kind = inferConfiguredKind(config, namespace);\n byNamespace.set(namespace, {\n namespace,\n kind,\n source: \"configured\",\n });\n }\n\n if (resolveNamespaceCapabilities(config).namespaces && resolveConversationContextCapabilities(config).maintenanceNamespaceFanout !== false) {\n const configuredSet = new Set(configured);\n try {\n // An incomplete read (unreadable file, malformed rows) still returns the readable records,\n // so they are planned as before; the callback records that the catalog was not whole.\n const records = options.catalog?.enabled\n ? await options.catalog.listNamespaces(undefined, {\n onIncomplete: (reason) =>\n skipped.push({ namespace: \"*\", reason: \"catalog_read_failed\", detail: reason }),\n })\n : [];\n for (const record of records) {\n const namespace = record.namespace.trim();\n if (!namespace) continue;\n const isConfigured = configuredSet.has(namespace);\n const kind = isConfigured ? inferConfiguredKind(config, namespace) : record.kind;\n if (!namespaceKindAllowed(config, kind)) {\n skipped.push({\n namespace,\n kind,\n reason: disabledReasonForKind(kind),\n });\n continue;\n }\n if (!isConfigured && !(await catalogRootIsLive(config, record))) {\n skipped.push({\n namespace,\n kind,\n reason: \"unsafe_or_stale_root\",\n });\n continue;\n }\n byNamespace.set(namespace, {\n namespace,\n kind,\n storageDir: record.storageDir,\n source: isConfigured ? \"configured\" : \"catalog\",\n lastWriteAt: record.lastWriteAt,\n lastMaintenanceAt: record.lastMaintenanceAt?.[options.jobName],\n });\n }\n } catch (error) {\n skipped.push({\n namespace: \"*\",\n reason: \"catalog_read_failed\",\n detail: error instanceof Error ? error.message : String(error),\n });\n }\n } else if (resolveNamespaceCapabilities(config).namespaces) {\n skipped.push({\n namespace: \"*\",\n reason: \"fanout_disabled\",\n });\n }\n\n if (options.budgetMode !== \"unbounded\") {\n const latestStatusAtByNamespace = await readLatestStatusAtByNamespace(config, options.jobName);\n for (const candidate of byNamespace.values()) {\n if (!candidate.lastMaintenanceAt) {\n candidate.lastMaintenanceAt = latestStatusAtByNamespace.get(candidate.namespace);\n }\n }\n }\n\n const candidates = [...byNamespace.values()]\n .filter((candidate) => namespaceKindAllowed(config, candidate.kind))\n .sort(sortCandidates);\n\n const max = maxNamespacesPerCycle(config);\n const applyCycleBudget = options.budgetMode !== \"unbounded\";\n const selected = applyCycleBudget ? candidates.slice(0, max) : candidates;\n if (applyCycleBudget) {\n for (const candidate of candidates.slice(max)) {\n skipped.push({\n namespace: candidate.namespace,\n kind: candidate.kind,\n reason: \"budget_exhausted\",\n });\n }\n }\n\n return {\n jobName: options.jobName,\n generatedAt,\n namespaces: selected,\n skipped,\n budget: {\n maxNamespacesPerCycle: max,\n selected: selected.length,\n },\n };\n}\n\nfunction stablePathSegment(value: string): string {\n const sanitized = value.replace(/[^a-zA-Z0-9._-]/g, \"_\").slice(0, 128) || \"unnamed\";\n if (sanitized.length <= 128 && sanitized === value) return sanitized;\n return `${sanitized.slice(0, 80)}-${createHash(\"sha256\").update(value).digest(\"hex\").slice(0, 16)}`;\n}\n\nfunction namespacePathSegment(namespace: string): string {\n const token = namespaceIdentityToken(namespace);\n if (token.length <= 160) return token;\n return `ns-${createHash(\"sha256\").update(namespace).digest(\"hex\")}`;\n}\n\nfunction lockPath(config: PluginConfig, jobName: string, namespace: string): string {\n return path.join(\n config.memoryDir,\n \"state\",\n LOCK_BASE,\n stablePathSegment(jobName),\n `${namespacePathSegment(namespace)}.lock`\n );\n}\n\nfunction namespaceMaintenanceLockStaleMs(config: PluginConfig): number {\n if (\n typeof config.maintenanceNamespaceLockStaleMs === \"number\" &&\n Number.isFinite(config.maintenanceNamespaceLockStaleMs) &&\n config.maintenanceNamespaceLockStaleMs > 0\n ) {\n return Math.floor(config.maintenanceNamespaceLockStaleMs);\n }\n return DEFAULT_LOCK_STALE_MS;\n}\n\nfunction namespaceMaintenanceLockHeartbeatMs(config: PluginConfig): number {\n const staleMs = namespaceMaintenanceLockStaleMs(config);\n return Math.max(1, Math.min(30_000, Math.floor(staleMs / 3) || 1));\n}\n\nfunction errorCode(error: unknown): string | undefined {\n return typeof error === \"object\" && error !== null && \"code\" in error\n ? (error as { code?: string }).code\n : undefined;\n}\n\nasync function withNamespaceMaintenanceLockHeartbeat<T>(\n config: PluginConfig,\n locks: LockHandle | LockHandle[],\n task: () => Promise<T>,\n): Promise<T> {\n const activeLocks = Array.isArray(locks) ? locks : [locks];\n const interval = setInterval(() => {\n for (const lock of activeLocks) {\n void lock.touch().catch(() => undefined);\n }\n }, namespaceMaintenanceLockHeartbeatMs(config));\n interval.unref?.();\n try {\n return await task();\n } finally {\n clearInterval(interval);\n }\n}\n\nasync function removeStaleLockDirectory(filePath: string): Promise<void> {\n let entries: Dirent[];\n try {\n entries = await readdir(filePath, { withFileTypes: true });\n } catch (error) {\n if (errorCode(error) === \"ENOENT\") return;\n throw error;\n }\n for (const entry of entries) {\n if (!entry.isFile()) continue;\n await namespaceMaintenanceFs.rm(path.join(filePath, entry.name), { force: true });\n }\n try {\n await rmdir(filePath);\n } catch (error) {\n if (errorCode(error) === \"ENOENT\") return;\n throw error;\n }\n}\n\nasync function tryAcquireNamespaceMaintenanceLock(\n config: PluginConfig,\n jobName: string,\n namespace: string\n): Promise<LockHandle | null> {\n const filePath = lockPath(config, jobName, namespace);\n await mkdir(path.dirname(filePath), { recursive: true });\n try {\n const lockId = randomUUID();\n await mkdir(filePath);\n const ownerPath = path.join(filePath, `${lockId}.json`);\n let handle: Awaited<ReturnType<typeof open>> | undefined;\n try {\n handle = await namespaceMaintenanceFs.open(ownerPath, \"wx\");\n await handle.writeFile(\n `${JSON.stringify({\n lockId,\n pid: process.pid,\n jobName,\n namespace,\n acquiredAt: new Date().toISOString(),\n })}\\n`,\n \"utf8\"\n );\n await handle.close();\n } catch (setupError) {\n await handle?.close().catch(() => undefined);\n await namespaceMaintenanceFs.rm(ownerPath, { force: true }).catch(() => undefined);\n await rmdir(filePath).catch(() => undefined);\n throw setupError;\n }\n return {\n path: filePath,\n async touch() {\n try {\n const parsed = JSON.parse(await readFile(ownerPath, \"utf8\")) as { lockId?: unknown };\n if (parsed.lockId === lockId) {\n const now = new Date();\n await utimes(ownerPath, now, now);\n await utimes(filePath, now, now);\n }\n } catch {}\n },\n async release() {\n try {\n const parsed = JSON.parse(await readFile(ownerPath, \"utf8\")) as { lockId?: unknown };\n if (parsed.lockId === lockId) {\n await namespaceMaintenanceFs.rm(ownerPath, { force: true });\n await rmdir(filePath).catch(() => undefined);\n }\n } catch {}\n },\n };\n } catch (error) {\n if (errorCode(error) === \"EEXIST\") {\n const staleMs =\n namespaceMaintenanceLockStaleMs(config);\n try {\n const s = await lstat(filePath);\n if (s.isSymbolicLink()) {\n return null;\n }\n if ((s.isFile() || s.isDirectory()) && Date.now() - s.mtimeMs > staleMs) {\n try {\n if (s.isDirectory()) {\n await removeStaleLockDirectory(filePath);\n } else {\n await namespaceMaintenanceFs.rm(filePath, { force: true });\n }\n } catch (removeError) {\n if (errorCode(removeError) === \"ENOENT\") {\n return tryAcquireNamespaceMaintenanceLock(config, jobName, namespace);\n }\n if (errorCode(removeError) === \"ENOTEMPTY\") {\n return null;\n }\n throw removeError;\n }\n return tryAcquireNamespaceMaintenanceLock(config, jobName, namespace);\n }\n } catch (statError) {\n if (errorCode(statError) === \"ENOENT\") {\n return tryAcquireNamespaceMaintenanceLock(config, jobName, namespace);\n }\n throw statError;\n }\n return null;\n }\n throw error;\n }\n}\n\nfunction statusBasePath(config: PluginConfig): string {\n return path.join(config.memoryDir, \"state\", STATUS_BASE);\n}\n\nfunction statusPath(config: PluginConfig, jobName: string, namespace: string): string {\n return path.join(statusBasePath(config), stablePathSegment(jobName), `${namespacePathSegment(namespace)}.json`);\n}\n\nfunction lastRanStatusPath(config: PluginConfig, jobName: string, namespace: string): string {\n return path.join(statusBasePath(config), stablePathSegment(jobName), `${namespacePathSegment(namespace)}.last-ran.json`);\n}\n\nfunction parseStatus(value: unknown): NamespaceMaintenanceRunStatus | null {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return null;\n const v = value as Partial<NamespaceMaintenanceRunStatus>;\n if (\n typeof v.namespace === \"string\" &&\n typeof v.jobName === \"string\" &&\n (v.state === \"ran\" || v.state === \"skipped\" || v.state === \"failed\") &&\n typeof v.startedAt === \"string\" &&\n typeof v.completedAt === \"string\"\n ) {\n return v as NamespaceMaintenanceRunStatus;\n }\n return null;\n}\n\nasync function readLatestStatusAtByNamespace(config: PluginConfig, jobName: string): Promise<Map<string, string>> {\n const latest = new Map<string, string>();\n const latestMs = new Map<string, number>();\n for (const status of [...(await readStatusFiles(config)), ...(await readLastRanStatusFiles(config))]) {\n if (status.state !== \"ran\") continue;\n if (status.jobName !== jobName) continue;\n const completedAtMs = Date.parse(status.completedAt);\n if (!Number.isFinite(completedAtMs)) continue;\n const previousMs = latestMs.get(status.namespace);\n if (previousMs !== undefined && previousMs >= completedAtMs) continue;\n latestMs.set(status.namespace, completedAtMs);\n latest.set(status.namespace, status.completedAt);\n }\n return latest;\n}\n\nasync function readStatusFile(filePath: string): Promise<NamespaceMaintenanceRunStatus | null> {\n try {\n const parsed = JSON.parse(await readFile(filePath, \"utf8\")) as unknown;\n return parseStatus(parsed);\n } catch {\n return null;\n }\n}\n\nasync function readStatusFiles(config: PluginConfig): Promise<NamespaceMaintenanceRunStatus[]> {\n if (typeof config.memoryDir !== \"string\" || config.memoryDir.length === 0) {\n return [];\n }\n const root = statusBasePath(config);\n const statuses: NamespaceMaintenanceRunStatus[] = [];\n let jobDirs: Dirent[];\n try {\n jobDirs = await readdir(root, { withFileTypes: true });\n } catch {\n return statuses;\n }\n for (const jobDir of jobDirs) {\n if (!jobDir.isDirectory()) continue;\n let files: Dirent[];\n try {\n files = await readdir(path.join(root, jobDir.name), { withFileTypes: true });\n } catch {\n continue;\n }\n for (const file of files) {\n if (!file.isFile() || !file.name.endsWith(\".json\")) continue;\n if (file.name.endsWith(\".last-ran.json\")) continue;\n const status = await readStatusFile(path.join(root, jobDir.name, file.name));\n if (status) statuses.push(status);\n }\n }\n return statuses;\n}\n\nasync function readLastRanStatusFiles(config: PluginConfig): Promise<NamespaceMaintenanceRunStatus[]> {\n if (typeof config.memoryDir !== \"string\" || config.memoryDir.length === 0) {\n return [];\n }\n const root = statusBasePath(config);\n const statuses: NamespaceMaintenanceRunStatus[] = [];\n let jobDirs: Dirent[];\n try {\n jobDirs = await readdir(root, { withFileTypes: true });\n } catch {\n return statuses;\n }\n for (const jobDir of jobDirs) {\n if (!jobDir.isDirectory()) continue;\n let files: Dirent[];\n try {\n files = await readdir(path.join(root, jobDir.name), { withFileTypes: true });\n } catch {\n continue;\n }\n for (const file of files) {\n if (!file.isFile() || !file.name.endsWith(\".last-ran.json\")) continue;\n const status = await readStatusFile(path.join(root, jobDir.name, file.name));\n if (status) statuses.push(status);\n }\n }\n return statuses;\n}\n\nasync function writeStatusPayload(target: string, status: NamespaceMaintenanceRunStatus): Promise<void> {\n const dir = path.dirname(target);\n await mkdir(dir, { recursive: true });\n const temp = `${target}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`;\n const payload = {\n version: 1,\n ...status,\n };\n await writeFile(temp, `${JSON.stringify(payload, null, 2)}\\n`, \"utf8\");\n await rename(temp, target);\n}\n\nasync function writeStatusFile(config: PluginConfig, status: NamespaceMaintenanceRunStatus): Promise<void> {\n await writeStatusPayload(statusPath(config, status.jobName, status.namespace), status);\n if (status.state === \"ran\") {\n await writeStatusPayload(lastRanStatusPath(config, status.jobName, status.namespace), status);\n }\n}\n\nasync function recordNamespaceMaintenanceStatusSafely(\n config: PluginConfig,\n status: NamespaceMaintenanceRunStatus\n): Promise<void> {\n try {\n await writeStatusFile(config, status);\n } catch {\n // Observability must not fail the maintenance operation.\n }\n}\n\nfunction maintenanceErrorDetail(error: unknown): string {\n return displayErrorDetail(error) || \"Error\";\n}\n\nexport async function readNamespaceMaintenanceStatuses(config: PluginConfig): Promise<NamespaceMaintenanceRunStatus[]> {\n return (await readStatusFiles(config)).sort((a, b) => {\n const byJob = a.jobName.localeCompare(b.jobName);\n if (byJob !== 0) return byJob;\n return a.namespace.localeCompare(b.namespace);\n });\n}\n\n/**\n * Read the last SUCCESSFUL run status per job+namespace (the\n * `<namespace>.last-ran.json` files written only when state === \"ran\").\n *\n * The latest status file (`<namespace>.json`) is overwritten on every run,\n * so after a successful run followed by a skip (budget/lock/cadence) the\n * latest file shows \"skipped\" and the prior success is invisible. Merging\n * these last-ran records into the health summary lets `lastRunAt` and run\n * history reflect the most recent successful maintenance (review #1622).\n */\nexport async function readNamespaceMaintenanceLastRanStatuses(\n config: PluginConfig,\n): Promise<NamespaceMaintenanceRunStatus[]> {\n return (await readLastRanStatusFiles(config)).sort((a, b) => {\n const byJob = a.jobName.localeCompare(b.jobName);\n if (byJob !== 0) return byJob;\n return a.namespace.localeCompare(b.namespace);\n });\n}\n\nexport type NamespaceMaintenancePlanRunnerResult = {\n itemCount?: number;\n /**\n * When `true`, the runner performed NO work for this namespace (e.g. the\n * job's own cadence gate throttled it). The planner records the namespace\n * as `state: \"skipped\"` with the given reason and does NOT touch the\n * catalog's `lastMaintenanceAt`, so a throttled namespace is not falsely\n * reported as maintained. Without this signal a runner that resolves\n * without throwing is always recorded as `state: \"ran\"`.\n */\n skipped?: boolean;\n skipReason?: string;\n} | undefined;\n\nexport async function runNamespaceMaintenancePlan(\n config: PluginConfig,\n plan: NamespaceMaintenancePlan,\n runner: (candidate: NamespaceMaintenanceCandidate) => Promise<NamespaceMaintenancePlanRunnerResult>,\n catalog?: NamespaceCatalog\n): Promise<NamespaceMaintenanceSummary> {\n const statuses: NamespaceMaintenanceRunStatus[] = [];\n\n for (const skipped of plan.skipped) {\n if (skipped.namespace === \"*\") continue;\n const now = new Date().toISOString();\n const status: NamespaceMaintenanceRunStatus = {\n namespace: skipped.namespace,\n jobName: plan.jobName,\n state: \"skipped\",\n reason: skipped.reason,\n startedAt: now,\n completedAt: now,\n };\n statuses.push(status);\n await recordNamespaceMaintenanceStatusSafely(config, status);\n }\n\n for (const candidate of plan.namespaces) {\n const startedAt = new Date().toISOString();\n const lock = await tryAcquireNamespaceMaintenanceLock(config, plan.jobName, candidate.namespace);\n if (!lock) {\n const completedAt = new Date().toISOString();\n const status: NamespaceMaintenanceRunStatus = {\n namespace: candidate.namespace,\n jobName: plan.jobName,\n state: \"skipped\",\n reason: \"lock_held\",\n startedAt,\n completedAt,\n };\n statuses.push(status);\n await recordNamespaceMaintenanceStatusSafely(config, status);\n continue;\n }\n try {\n const result = await withNamespaceMaintenanceLockHeartbeat(config, lock, () => runner(candidate));\n const completedAt = new Date().toISOString();\n if (result?.skipped) {\n // The runner performed no work (e.g. the job's own cadence gate\n // throttled this namespace). Record skipped WITHOUT touching the\n // catalog's lastMaintenanceAt so a throttled namespace is not\n // falsely reported as maintained.\n const status: NamespaceMaintenanceRunStatus = {\n namespace: candidate.namespace,\n jobName: plan.jobName,\n state: \"skipped\",\n reason: (result.skipReason ?? \"throttled\") as NamespaceMaintenanceSkipReason,\n startedAt,\n completedAt,\n };\n statuses.push(status);\n await recordNamespaceMaintenanceStatusSafely(config, status);\n } else {\n const status: NamespaceMaintenanceRunStatus = {\n namespace: candidate.namespace,\n jobName: plan.jobName,\n state: \"ran\",\n startedAt,\n completedAt,\n itemCount: result?.itemCount,\n };\n statuses.push(status);\n await recordNamespaceMaintenanceStatusSafely(config, status);\n try {\n await catalog?.markMaintenance(candidate.namespace, plan.jobName, new Date(completedAt));\n } catch {\n // Catalog maintenance touches are best-effort status metadata.\n }\n }\n } catch (error) {\n const completedAt = new Date().toISOString();\n const status: NamespaceMaintenanceRunStatus = {\n namespace: candidate.namespace,\n jobName: plan.jobName,\n state: \"failed\",\n reason: \"job_failed\",\n startedAt,\n completedAt,\n error: maintenanceErrorDetail(error),\n };\n statuses.push(status);\n await recordNamespaceMaintenanceStatusSafely(config, status);\n } finally {\n await lock.release().catch(() => undefined);\n }\n }\n\n return {\n jobName: plan.jobName,\n generatedAt: new Date().toISOString(),\n ran: statuses.filter((s) => s.state === \"ran\").length,\n skipped: statuses.filter((s) => s.state === \"skipped\").length,\n failed: statuses.filter((s) => s.state === \"failed\").length,\n statuses,\n };\n}\n\nexport async function runNamespaceMaintenanceBatchPlan(\n config: PluginConfig,\n plan: NamespaceMaintenancePlan,\n runner: (candidates: NamespaceMaintenanceCandidate[]) => Promise<NamespaceMaintenanceBatchRunResult | undefined>,\n catalog?: NamespaceCatalog,\n options: NamespaceMaintenanceBatchRunOptions = {}\n): Promise<NamespaceMaintenanceSummary> {\n const statuses: NamespaceMaintenanceRunStatus[] = [];\n\n for (const skipped of plan.skipped) {\n if (skipped.namespace === \"*\") continue;\n const now = new Date().toISOString();\n const status: NamespaceMaintenanceRunStatus = {\n namespace: skipped.namespace,\n jobName: plan.jobName,\n state: \"skipped\",\n reason: skipped.reason,\n startedAt: now,\n completedAt: now,\n };\n statuses.push(status);\n await recordNamespaceMaintenanceStatusSafely(config, status);\n }\n\n const acquired: Array<{\n candidate: NamespaceMaintenanceCandidate;\n lock: LockHandle;\n startedAt: string;\n }> = [];\n\n try {\n for (const candidate of plan.namespaces) {\n const startedAt = new Date().toISOString();\n const lock = await tryAcquireNamespaceMaintenanceLock(config, plan.jobName, candidate.namespace);\n if (!lock) {\n const completedAt = new Date().toISOString();\n const status: NamespaceMaintenanceRunStatus = {\n namespace: candidate.namespace,\n jobName: plan.jobName,\n state: \"skipped\",\n reason: \"lock_held\",\n startedAt,\n completedAt,\n };\n statuses.push(status);\n await recordNamespaceMaintenanceStatusSafely(config, status);\n continue;\n }\n acquired.push({ candidate, lock, startedAt });\n }\n } catch (error) {\n await Promise.all(acquired.map(({ lock }) => lock.release().catch(() => undefined)));\n throw error;\n }\n\n if (options.requireAllLocks && acquired.length > 0 && acquired.length < plan.namespaces.length) {\n for (const { candidate, startedAt } of acquired) {\n const completedAt = new Date().toISOString();\n const status: NamespaceMaintenanceRunStatus = {\n namespace: candidate.namespace,\n jobName: plan.jobName,\n state: \"skipped\",\n reason: \"batch_lock_incomplete\",\n startedAt,\n completedAt,\n };\n statuses.push(status);\n await recordNamespaceMaintenanceStatusSafely(config, status);\n }\n await Promise.all(acquired.map(({ lock }) => lock.release().catch(() => undefined)));\n return {\n jobName: plan.jobName,\n generatedAt: new Date().toISOString(),\n ran: statuses.filter((s) => s.state === \"ran\").length,\n skipped: statuses.filter((s) => s.state === \"skipped\").length,\n failed: statuses.filter((s) => s.state === \"failed\").length,\n statuses,\n };\n }\n\n if (acquired.length === 0) {\n return {\n jobName: plan.jobName,\n generatedAt: new Date().toISOString(),\n ran: statuses.filter((s) => s.state === \"ran\").length,\n skipped: statuses.filter((s) => s.state === \"skipped\").length,\n failed: statuses.filter((s) => s.state === \"failed\").length,\n statuses,\n };\n }\n\n try {\n const result = await withNamespaceMaintenanceLockHeartbeat(\n config,\n acquired.map(({ lock }) => lock),\n () => runner(acquired.map(({ candidate }) => candidate)),\n );\n for (const { candidate, startedAt } of acquired) {\n const completedAt = new Date().toISOString();\n const status: NamespaceMaintenanceRunStatus = {\n namespace: candidate.namespace,\n jobName: plan.jobName,\n state: \"ran\",\n startedAt,\n completedAt,\n itemCount: itemCountForNamespace(result, candidate.namespace),\n };\n statuses.push(status);\n await recordNamespaceMaintenanceStatusSafely(config, status);\n try {\n await catalog?.markMaintenance(candidate.namespace, plan.jobName, new Date(completedAt));\n } catch {\n // Catalog maintenance touches are best-effort status metadata.\n }\n }\n } catch (error) {\n const skipReason = options.skipReasonForError?.(error);\n for (const { candidate, startedAt } of acquired) {\n const completedAt = new Date().toISOString();\n const status: NamespaceMaintenanceRunStatus = skipReason\n ? {\n namespace: candidate.namespace,\n jobName: plan.jobName,\n state: \"skipped\",\n reason: skipReason,\n startedAt,\n completedAt,\n }\n : {\n namespace: candidate.namespace,\n jobName: plan.jobName,\n state: \"failed\",\n reason: \"job_failed\",\n startedAt,\n completedAt,\n error: maintenanceErrorDetail(error),\n };\n statuses.push(status);\n await recordNamespaceMaintenanceStatusSafely(config, status);\n }\n } finally {\n await Promise.all(acquired.map(({ lock }) => lock.release().catch(() => undefined)));\n }\n\n return {\n jobName: plan.jobName,\n generatedAt: new Date().toISOString(),\n ran: statuses.filter((s) => s.state === \"ran\").length,\n skipped: statuses.filter((s) => s.state === \"skipped\").length,\n failed: statuses.filter((s) => s.state === \"failed\").length,\n statuses,\n };\n}\n\nfunction itemCountForNamespace(\n result: NamespaceMaintenanceBatchRunResult | undefined,\n namespace: string,\n): number | undefined {\n const itemCounts = result?.itemCounts;\n if (itemCounts instanceof Map) return itemCounts.get(namespace);\n if (itemCounts && Object.prototype.hasOwnProperty.call(itemCounts, namespace)) {\n return itemCounts[namespace];\n }\n return result?.itemCount;\n}\n"],"mappings":"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","names":[]}
@@ -61,7 +61,7 @@ import {
61
61
  optionalNamespaceKindQueryParam,
62
62
  optionalQueryString,
63
63
  positiveIntQueryParam
64
- } from "./chunk-WGFEGBFB.js";
64
+ } from "./chunk-VZ7VJGPL.js";
65
65
  import {
66
66
  respondBriefingHttp
67
67
  } from "./chunk-HJ4X4BGS.js";
@@ -3573,4 +3573,4 @@ export {
3573
3573
  resolveDefaultAdminConsolePublicDir,
3574
3574
  EngramAccessHttpServer
3575
3575
  };
3576
- //# sourceMappingURL=chunk-4BUJICMI.js.map
3576
+ //# sourceMappingURL=chunk-FCAXGYDT.js.map
@@ -3,7 +3,7 @@ import {
3
3
  readNamespaceMaintenanceLastRanStatuses,
4
4
  readNamespaceMaintenanceStatuses,
5
5
  runNamespaceMaintenancePlan
6
- } from "./chunk-R3WZ74B2.js";
6
+ } from "./chunk-CZS7UTXL.js";
7
7
  import {
8
8
  analyzeSessionIntegrity,
9
9
  applySessionRepair,
@@ -1683,4 +1683,4 @@ export {
1683
1683
  runBenchmarkRecall,
1684
1684
  runOperatorRepair
1685
1685
  };
1686
- //# sourceMappingURL=chunk-GGFQAGOT.js.map
1686
+ //# sourceMappingURL=chunk-GMRP3HN3.js.map
@@ -134,7 +134,7 @@ import {
134
134
  runOperatorInventory,
135
135
  runOperatorRepair,
136
136
  runOperatorSetup
137
- } from "./chunk-GGFQAGOT.js";
137
+ } from "./chunk-GMRP3HN3.js";
138
138
  import {
139
139
  analyzeSessionIntegrity,
140
140
  applySessionRepair,
@@ -210,7 +210,7 @@ import {
210
210
  import {
211
211
  EngramAccessHttpServer,
212
212
  MeetingsInputError
213
- } from "./chunk-4BUJICMI.js";
213
+ } from "./chunk-FCAXGYDT.js";
214
214
  import {
215
215
  WearablesInputError
216
216
  } from "./chunk-V7IZKJI3.js";
@@ -10140,4 +10140,4 @@ export {
10140
10140
  listMemoryMarkdownFilePaths,
10141
10141
  registerCli
10142
10142
  };
10143
- //# sourceMappingURL=chunk-Y56D5FSD.js.map
10143
+ //# sourceMappingURL=chunk-OGR52N7A.js.map
@@ -395,9 +395,9 @@ var NamespaceCatalog = class {
395
395
  }
396
396
  return [...byStorageDir.values()];
397
397
  }
398
- loadSanitizedRecords() {
398
+ loadSanitizedRecords(health) {
399
399
  return this.queueCritical(async () => {
400
- const records = await this.loadCompacted();
400
+ const records = await this.loadCompacted(false, health);
401
401
  const sanitized = await Promise.all(
402
402
  [...records.values()].map((r) => this.sanitizeRecordForRead(r))
403
403
  );
@@ -406,9 +406,11 @@ var NamespaceCatalog = class {
406
406
  );
407
407
  });
408
408
  }
409
- async listNamespaces(filter) {
409
+ async listNamespaces(filter, options) {
410
410
  if (!this.enabled) return [];
411
- let out = await this.loadSanitizedRecords();
411
+ const health = {};
412
+ let out = await this.loadSanitizedRecords(health);
413
+ if (health.incomplete !== void 0) options?.onIncomplete?.(health.incomplete);
412
414
  if (filter?.kind) out = out.filter((r) => r.kind === filter.kind);
413
415
  if (filter?.discoveredBy) out = out.filter((r) => r.discoveredBy === filter.discoveredBy);
414
416
  if (filter?.writtenSince) {
@@ -1291,13 +1293,14 @@ var NamespaceCatalog = class {
1291
1293
  }
1292
1294
  // ── Persistence ──────────────────────────────────────────────────────────
1293
1295
  /** Load the JSONL log and fold it into current state (last-record-wins). */
1294
- async loadCompacted(forceFresh = false) {
1296
+ async loadCompacted(forceFresh = false, health) {
1295
1297
  const records = /* @__PURE__ */ new Map();
1296
1298
  let handle;
1297
1299
  try {
1298
1300
  handle = await open(this.catalogPath, "r");
1299
- } catch {
1301
+ } catch (error) {
1300
1302
  this.compactedCache = void 0;
1303
+ if (health && !isNotFoundError(error)) health.incomplete = `catalog unreadable: ${String(error)}`;
1301
1304
  return records;
1302
1305
  }
1303
1306
  let identity;
@@ -1311,10 +1314,12 @@ var NamespaceCatalog = class {
1311
1314
  };
1312
1315
  if (!forceFresh && this.compactedCache && this.compactedCache.identity.size === identity.size && this.compactedCache.identity.mtimeMs === identity.mtimeMs && this.compactedCache.identity.ctimeMs === identity.ctimeMs && this.compactedCache.identity.ino === identity.ino) {
1313
1316
  await handle.close().catch(() => void 0);
1317
+ if (health && this.compactedCache.incomplete) health.incomplete = this.compactedCache.incomplete;
1314
1318
  return this.cloneCompactedRecords(this.compactedCache.records);
1315
1319
  }
1316
1320
  } catch {
1317
1321
  }
1322
+ let malformed = 0;
1318
1323
  try {
1319
1324
  this.onCatalogReadForTest?.();
1320
1325
  const CHUNK_BYTES = 1 << 16;
@@ -1330,10 +1335,14 @@ var NamespaceCatalog = class {
1330
1335
  try {
1331
1336
  parsed = JSON.parse(trimmed);
1332
1337
  } catch {
1338
+ malformed += 1;
1333
1339
  return;
1334
1340
  }
1335
1341
  const record = coerceRecord(parsed);
1336
- if (!record) return;
1342
+ if (!record) {
1343
+ malformed += 1;
1344
+ return;
1345
+ }
1337
1346
  const prior = records.get(record.namespace);
1338
1347
  records.set(record.namespace, prior ? mergeNewerTouchFields(record, prior) : record);
1339
1348
  };
@@ -1354,13 +1363,16 @@ var NamespaceCatalog = class {
1354
1363
  }
1355
1364
  leftover += decoder.end();
1356
1365
  foldLine(leftover);
1357
- } catch {
1366
+ } catch (error) {
1358
1367
  this.compactedCache = void 0;
1368
+ if (health) health.incomplete = `catalog unreadable: ${String(error)}`;
1359
1369
  return /* @__PURE__ */ new Map();
1360
1370
  } finally {
1361
1371
  await handle.close().catch(() => void 0);
1362
1372
  }
1363
- this.compactedCache = identity ? { identity, records } : void 0;
1373
+ const incomplete = malformed > 0 ? `${malformed} malformed catalog line(s) skipped` : void 0;
1374
+ if (health && incomplete) health.incomplete = incomplete;
1375
+ this.compactedCache = identity ? { identity, records, incomplete } : void 0;
1364
1376
  return this.cloneCompactedRecords(records);
1365
1377
  }
1366
1378
  cloneCompactedRecords(records) {
@@ -1473,4 +1485,4 @@ export {
1473
1485
  isNamespaceKind,
1474
1486
  NamespaceCatalog
1475
1487
  };
1476
- //# sourceMappingURL=chunk-XVTB6BZS.js.map
1488
+ //# sourceMappingURL=chunk-S3OI5DP5.js.map