@productbrain/mcp 0.0.1-beta.168 → 0.0.1-beta.171

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.
@@ -86,7 +86,7 @@ function getToolContext() {
86
86
  return toolContextStore.getStore() ?? null;
87
87
  }
88
88
  var DEFAULT_CLOUD_URL = "https://gateway.productbrain.io";
89
- var McpCallError = class extends Error {
89
+ var KernelCallError = class extends Error {
90
90
  status;
91
91
  code;
92
92
  /** WP-316 S1a: Structured commit validation — required field keys missing from entry.data. */
@@ -95,7 +95,7 @@ var McpCallError = class extends Error {
95
95
  fieldErrors;
96
96
  constructor(message, status, code, missingRequiredFields, fieldErrors) {
97
97
  super(message);
98
- this.name = "McpCallError";
98
+ this.name = "KernelCallError";
99
99
  this.status = status;
100
100
  this.code = code;
101
101
  this.missingRequiredFields = missingRequiredFields;
@@ -184,7 +184,7 @@ async function startAgentSession() {
184
184
  if (!s.apiKeyId) {
185
185
  throw new Error("Cannot start session: API key ID not resolved. Ensure workspace resolution completed.");
186
186
  }
187
- const result = await mcpCall("agent.startSession", {
187
+ const result = await kernelCall("agent.startSession", {
188
188
  workspaceId,
189
189
  apiKeyId: s.apiKeyId,
190
190
  clientKind: "mcp"
@@ -204,7 +204,7 @@ async function closeAgentSession() {
204
204
  if (!s.agentSessionId) return;
205
205
  const sessionId = s.agentSessionId;
206
206
  try {
207
- await mcpCall("agent.closeSession", {
207
+ await kernelCall("agent.closeSession", {
208
208
  sessionId,
209
209
  status: "closed"
210
210
  });
@@ -220,7 +220,7 @@ async function orphanAgentSession() {
220
220
  if (!s.agentSessionId) return;
221
221
  const sessionId = s.agentSessionId;
222
222
  try {
223
- await mcpCall("agent.closeSession", {
223
+ await kernelCall("agent.closeSession", {
224
224
  sessionId,
225
225
  status: "orphaned"
226
226
  });
@@ -241,7 +241,7 @@ function touchSessionActivity() {
241
241
  const lastTouchAt = _lastTouchAtBySession.get(sessionId) ?? 0;
242
242
  if (now - lastTouchAt < TOUCH_THROTTLE_MS) return;
243
243
  _lastTouchAtBySession.set(sessionId, now);
244
- mcpCall("agent.touchSession", {
244
+ kernelCall("agent.touchSession", {
245
245
  sessionId
246
246
  }).catch(() => {
247
247
  });
@@ -257,7 +257,7 @@ async function recordSessionActivity(activity) {
257
257
  const s = state();
258
258
  if (!s.agentSessionId) return;
259
259
  try {
260
- await mcpCall("agent.recordActivity", {
260
+ await kernelCall("agent.recordActivity", {
261
261
  sessionId: s.agentSessionId,
262
262
  ...activity
263
263
  });
@@ -341,7 +341,7 @@ async function callGateway(fn, args) {
341
341
  const errJson = json;
342
342
  const msg = errJson.error ?? errJson.message ?? "unknown error";
343
343
  audit(fn, "error", Date.now() - start, errJson.code ? `${msg} [${errJson.code}]` : msg);
344
- throw new McpCallError(
344
+ throw new KernelCallError(
345
345
  `MCP call "${fn}" failed (${res.status}): ${msg}`,
346
346
  res.status,
347
347
  errJson.code,
@@ -358,7 +358,7 @@ async function callGateway(fn, args) {
358
358
  _meta
359
359
  };
360
360
  }
361
- async function mcpCall(fn, args = {}) {
361
+ async function kernelCall(fn, args = {}) {
362
362
  const cached = getCached(fn, args);
363
363
  if (cached !== void 0) {
364
364
  return cached;
@@ -375,7 +375,7 @@ async function mcpCall(fn, args = {}) {
375
375
  }
376
376
  return data;
377
377
  }
378
- async function mcpCallEnvelope(fn, args = {}) {
378
+ async function kernelCallEnvelope(fn, args = {}) {
379
379
  const { data, summary, next, _meta } = await callGateway(fn, args);
380
380
  const s = state();
381
381
  if (s.agentSessionId && !TOUCH_EXCLUDED.has(fn)) {
@@ -398,7 +398,7 @@ async function resolveWorkspaceWithRetry(maxRetries = 2) {
398
398
  let lastError = null;
399
399
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
400
400
  try {
401
- const workspace = await mcpCall("resolveWorkspace", {});
401
+ const workspace = await kernelCall("resolveWorkspace", {});
402
402
  if (!workspace) {
403
403
  throw new Error(
404
404
  `API key is valid but no workspace is associated. Run \`npx ${MCP_NPX_PACKAGE} setup\` or regenerate your key.`
@@ -438,13 +438,13 @@ async function getWorkspaceContext() {
438
438
  governanceMode: s.workspaceGovernanceMode ?? "open"
439
439
  };
440
440
  }
441
- async function mcpQuery(fn, args = {}) {
441
+ async function kernelQuery(fn, args = {}) {
442
442
  const workspaceId = await getWorkspaceId();
443
- return mcpCall(fn, { ...args, workspaceId });
443
+ return kernelCall(fn, { ...args, workspaceId });
444
444
  }
445
- async function mcpMutation(fn, args = {}) {
445
+ async function kernelMutation(fn, args = {}) {
446
446
  const workspaceId = await getWorkspaceId();
447
- return mcpCall(fn, { ...args, workspaceId });
447
+ return kernelCall(fn, { ...args, workspaceId });
448
448
  }
449
449
  function requireActiveSession() {
450
450
  const s = state();
@@ -491,7 +491,7 @@ async function recoverSessionState() {
491
491
  const s = state();
492
492
  if (!s.workspaceId) return;
493
493
  try {
494
- const session = await mcpCall("agent.getActiveSession", { workspaceId: s.workspaceId });
494
+ const session = await kernelCall("agent.getActiveSession", { workspaceId: s.workspaceId });
495
495
  if (session && session.status === "active") {
496
496
  s.agentSessionId = session._id;
497
497
  s.sessionOriented = session.oriented;
@@ -724,7 +724,7 @@ function recordGap(gap) {
724
724
  }
725
725
  function persistGap(gap) {
726
726
  const sessionId = getAgentSessionId();
727
- mcpMutation("gaps.record", {
727
+ kernelMutation("gaps.record", {
728
728
  sessionId: sessionId ?? void 0,
729
729
  query: gap.query,
730
730
  tool: gap.tool,
@@ -756,7 +756,7 @@ function clearSessionGaps() {
756
756
  sessionGaps.delete(sessionKey);
757
757
  }
758
758
  function resolveGapsForEntry(entryName, entryId) {
759
- mcpMutation("gaps.resolve", { entryName, entryId }).catch(() => {
759
+ kernelMutation("gaps.resolve", { entryName, entryId }).catch(() => {
760
760
  });
761
761
  }
762
762
 
@@ -764,7 +764,7 @@ function resolveGapsForEntry(entryName, entryId) {
764
764
  async function resolveCollection(params) {
765
765
  const { name, description, typeHint, allowReviewRouting } = params;
766
766
  const sessionId = getAgentSessionId();
767
- const result = await mcpCall("chain.resolveCollection", {
767
+ const result = await kernelCall("chain.resolveCollection", {
768
768
  entryName: name,
769
769
  entryDescription: description,
770
770
  ...typeHint ? { typeHint } : {},
@@ -779,7 +779,7 @@ import { z } from "zod";
779
779
 
780
780
  // src/errors.ts
781
781
  var MCP_CALL_ERROR_RE = /^MCP call "[^"]+" failed \(\d+\): (.+)$/s;
782
- function asMcpCallError(err) {
782
+ function asKernelCallError(err) {
783
783
  if (err instanceof Error && typeof err.code === "string") {
784
784
  const code = err.code;
785
785
  const match = MCP_CALL_ERROR_RE.exec(err.message);
@@ -855,7 +855,7 @@ function classifyError(err) {
855
855
  if (err instanceof ValidationError) {
856
856
  return { code: "VALIDATION_ERROR", message };
857
857
  }
858
- const mcpErr = asMcpCallError(err);
858
+ const mcpErr = asKernelCallError(err);
859
859
  if (mcpErr) {
860
860
  const { code: convexCode, cleanMessage, missingRequiredFields, fieldErrors } = mcpErr;
861
861
  if (convexCode === "VALIDATION_FAILED") {
@@ -1073,12 +1073,43 @@ function formatFieldGuidance(fields) {
1073
1073
  return lines.join("\n");
1074
1074
  }
1075
1075
 
1076
+ // src/lib/inferSourceDate.ts
1077
+ function inferSourceDate(...values) {
1078
+ const combined = values.filter((value) => typeof value === "string" && value.trim().length > 0).join("\n");
1079
+ if (!combined) return void 0;
1080
+ const isoMatch = combined.match(/\b(20\d{2}-\d{2}-\d{2})\b/);
1081
+ if (isoMatch) return isoMatch[1];
1082
+ const monthMatch = combined.match(
1083
+ /\b(january|february|march|april|may|june|july|august|september|october|november|december)\s+(\d{1,2})(?:st|nd|rd|th)?(?:,?\s+(20\d{2}))?\b/i
1084
+ );
1085
+ if (!monthMatch) return void 0;
1086
+ const monthIndex = [
1087
+ "january",
1088
+ "february",
1089
+ "march",
1090
+ "april",
1091
+ "may",
1092
+ "june",
1093
+ "july",
1094
+ "august",
1095
+ "september",
1096
+ "october",
1097
+ "november",
1098
+ "december"
1099
+ ].indexOf(monthMatch[1].toLowerCase());
1100
+ if (monthIndex < 0) return void 0;
1101
+ const inferredYear = monthMatch[3] ?? combined.match(/\b(20\d{2})\b/)?.[1] ?? String((/* @__PURE__ */ new Date()).getUTCFullYear());
1102
+ const month = String(monthIndex + 1).padStart(2, "0");
1103
+ const day = monthMatch[2].padStart(2, "0");
1104
+ return `${inferredYear}-${month}-${day}`;
1105
+ }
1106
+
1076
1107
  // src/lib/collectionCache.ts
1077
1108
  var cachedCollections = null;
1078
1109
  var cachedBySlug = null;
1079
1110
  async function getCollections() {
1080
1111
  if (cachedCollections !== null) return cachedCollections;
1081
- const result = await mcpQuery("chain.listCollections");
1112
+ const result = await kernelQuery("chain.listCollections");
1082
1113
  cachedCollections = result ?? [];
1083
1114
  cachedBySlug = new Map(cachedCollections.map((c) => [c.slug, c]));
1084
1115
  return cachedCollections;
@@ -1137,35 +1168,6 @@ function inferFieldOption(text, collectionFields, fieldKeys) {
1137
1168
  }
1138
1169
  return bestOption;
1139
1170
  }
1140
- function inferSourceDate(...values) {
1141
- const combined = values.filter((value) => typeof value === "string" && value.trim().length > 0).join("\n");
1142
- if (!combined) return void 0;
1143
- const isoMatch = combined.match(/\b(20\d{2}-\d{2}-\d{2})\b/);
1144
- if (isoMatch) return isoMatch[1];
1145
- const monthMatch = combined.match(
1146
- /\b(january|february|march|april|may|june|july|august|september|october|november|december)\s+(\d{1,2})(?:st|nd|rd|th)?(?:,?\s+(20\d{2}))?\b/i
1147
- );
1148
- if (!monthMatch) return void 0;
1149
- const monthIndex = [
1150
- "january",
1151
- "february",
1152
- "march",
1153
- "april",
1154
- "may",
1155
- "june",
1156
- "july",
1157
- "august",
1158
- "september",
1159
- "october",
1160
- "november",
1161
- "december"
1162
- ].indexOf(monthMatch[1].toLowerCase());
1163
- if (monthIndex < 0) return void 0;
1164
- const inferredYear = monthMatch[3] ?? combined.match(/\b(20\d{2})\b/)?.[1] ?? String((/* @__PURE__ */ new Date()).getUTCFullYear());
1165
- const month = String(monthIndex + 1).padStart(2, "0");
1166
- const day = monthMatch[2].padStart(2, "0");
1167
- return `${inferredYear}-${month}-${day}`;
1168
- }
1169
1171
  var COMMON_CHECKS = {
1170
1172
  clearName: {
1171
1173
  id: "clear-name",
@@ -1778,7 +1780,7 @@ function formatQualityReport(result) {
1778
1780
  return lines.join("\n");
1779
1781
  }
1780
1782
  async function checkEntryQuality(entryId) {
1781
- const entry = await mcpQuery("chain.getEntry", { entryId });
1783
+ const entry = await kernelQuery("chain.getEntry", { entryId });
1782
1784
  if (!entry) {
1783
1785
  return {
1784
1786
  text: `Entry \`${entryId}\` not found. Try search to find the right ID.`,
@@ -1790,7 +1792,7 @@ async function checkEntryQuality(entryId) {
1790
1792
  for (const c of collections) collMap.set(c._id, c.slug);
1791
1793
  const collectionSlug = collMap.get(entry.collectionId) ?? "unknown";
1792
1794
  const profile = await getProfile(collectionSlug);
1793
- const relations = await mcpQuery("chain.listEntryRelations", { entryId });
1795
+ const relations = await kernelQuery("chain.listEntryRelations", { entryId });
1794
1796
  const linksCreated = [];
1795
1797
  for (const r of relations) {
1796
1798
  const otherId = r.fromId === entry._id ? r.toId : r.fromId;
@@ -2341,7 +2343,7 @@ function registerSmartCaptureTools(server) {
2341
2343
  };
2342
2344
  }
2343
2345
  const profile = await getProfile(resolvedCollection);
2344
- const col = await mcpQuery("chain.getCollection", { slug: resolvedCollection });
2346
+ const col = await kernelQuery("chain.getCollection", { slug: resolvedCollection });
2345
2347
  if (!col) {
2346
2348
  const displayName = resolvedCollection.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
2347
2349
  return {
@@ -2369,7 +2371,7 @@ Or use \`collections action=list\` to see available collections.`
2369
2371
  }
2370
2372
  const skipAutoDiscoveryEarly = links && links.length > 0;
2371
2373
  const groundingStart = Date.now();
2372
- const groundingPromise = !skipAutoDiscoveryEarly && (name || description) ? mcpQuery("chain.suggestLinksForCapture", {
2374
+ const groundingPromise = !skipAutoDiscoveryEarly && (name || description) ? kernelQuery("chain.suggestLinksForCapture", {
2373
2375
  entries: [{ name, description: description ?? "", collectionHint: resolvedCollection }],
2374
2376
  limit: 5,
2375
2377
  threshold: 2
@@ -2478,7 +2480,7 @@ ${groundingReport.governance.map((g) => `- **${g.entryId}** ${g.name} [${g.colle
2478
2480
  const shouldDecompose = (isStrategyCapture || isBetCapture) && description.trim().length > 0;
2479
2481
  if (shouldDecompose) {
2480
2482
  try {
2481
- const decomposed = await mcpCall(
2483
+ const decomposed = await kernelCall(
2482
2484
  "chain.decomposeContent",
2483
2485
  {
2484
2486
  collectionSlug: resolvedCollection,
@@ -2509,7 +2511,7 @@ ${groundingReport.governance.map((g) => `- **${g.entryId}** ${g.name} [${g.colle
2509
2511
  let formativeHints = [];
2510
2512
  let relationSuggestionsFromCreate = [];
2511
2513
  try {
2512
- const result = await mcpMutation("chain.createEntry", {
2514
+ const result = await kernelMutation("chain.createEntry", {
2513
2515
  collectionSlug: resolvedCollection,
2514
2516
  entryId: entryId ?? void 0,
2515
2517
  name,
@@ -2588,7 +2590,7 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
2588
2590
  throw error;
2589
2591
  }
2590
2592
  const tAfterCreate = Date.now();
2591
- void mcpMutation("chain.recordGroundingOutcome", {
2593
+ void kernelMutation("chain.recordGroundingOutcome", {
2592
2594
  surface: "mcp",
2593
2595
  promptShown: groundingReport.governance.length > 0,
2594
2596
  highestRatio: Math.max(
@@ -2609,7 +2611,7 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
2609
2611
  if (searchQuery && !skipAutoDiscovery) {
2610
2612
  await populateHubCache();
2611
2613
  const [searchResults, allCollections] = await Promise.all([
2612
- mcpQuery("chain.searchEntries", { query: searchQuery }),
2614
+ kernelQuery("chain.searchEntries", { query: searchQuery }),
2613
2615
  getCollections()
2614
2616
  ]);
2615
2617
  const collMap = /* @__PURE__ */ new Map();
@@ -2664,7 +2666,7 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
2664
2666
  }
2665
2667
  }
2666
2668
  const resolvedCK = canonicalKey;
2667
- const batchRelationsPromise = pendingRelations.length > 0 ? mcpMutation(
2669
+ const batchRelationsPromise = pendingRelations.length > 0 ? kernelMutation(
2668
2670
  "chain.createEntryRelations",
2669
2671
  {
2670
2672
  relations: pendingRelations.slice(0, 25).map((r) => ({ fromEntryId: r.fromEntryId, toEntryId: r.toEntryId, type: r.type })),
@@ -2674,9 +2676,9 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
2674
2676
  entryWarnings.push(`Auto-linking partially failed: ${err instanceof Error ? err.message : "unknown error"}`);
2675
2677
  return null;
2676
2678
  }) : Promise.resolve(null);
2677
- const cardinalityPromise = resolvedCK ? mcpQuery("chain.checkCardinalityWarning", { canonicalKey: resolvedCK }).catch(() => null) : Promise.resolve(null);
2679
+ const cardinalityPromise = resolvedCK ? kernelQuery("chain.checkCardinalityWarning", { canonicalKey: resolvedCK }).catch(() => null) : Promise.resolve(null);
2678
2680
  const contradictionPromise = runContradictionCheck(name, description);
2679
- const coachingPromise = mcpMutation("quality.evaluateHeuristicAndSchedule", {
2681
+ const coachingPromise = kernelMutation("quality.evaluateHeuristicAndSchedule", {
2680
2682
  entryId: finalEntryId,
2681
2683
  context: "capture"
2682
2684
  }).catch(() => null);
@@ -2761,7 +2763,7 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
2761
2763
  const shouldAutoCommit = shouldAutoCommitCapture(autoCommit, wsCtx.governanceMode);
2762
2764
  if (shouldAutoCommit && finalEntryId && conflictCandidates.length === 0) {
2763
2765
  try {
2764
- const conflictResults = await mcpQuery("chain.searchEntries", { query: name });
2766
+ const conflictResults = await kernelQuery("chain.searchEntries", { query: name });
2765
2767
  conflictCandidates = (conflictResults ?? []).filter((r) => r.entryId && r.entryId !== finalEntryId && r._id !== internalId).slice(0, 3).map((r) => ({ entryId: r.entryId, name: r.name, collection: r.collectionSlug ?? "unknown" }));
2766
2768
  } catch {
2767
2769
  }
@@ -2777,7 +2779,7 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
2777
2779
  if (blockingConflicts.length > 0) {
2778
2780
  commitError = `blocked by semantic contradiction preflight: ${blockingConflicts[0]?.chainEntryId} ${blockingConflicts[0]?.explanation ?? ""}`.trim();
2779
2781
  } else {
2780
- const commitResult = await mcpMutation("chain.commitEntry", {
2782
+ const commitResult = await kernelMutation("chain.commitEntry", {
2781
2783
  entryId: finalEntryId,
2782
2784
  author: agentId ? `agent:${agentId}` : void 0,
2783
2785
  sessionId: agentId ?? void 0
@@ -3002,7 +3004,7 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
3002
3004
  }
3003
3005
  }
3004
3006
  try {
3005
- const readiness = await mcpQuery("chain.workspaceReadiness");
3007
+ const readiness = await kernelQuery("chain.workspaceReadiness");
3006
3008
  if (readiness && readiness.gaps && readiness.gaps.length > 0) {
3007
3009
  const topGaps = readiness.gaps.slice(0, 2);
3008
3010
  lines.push("");
@@ -3242,7 +3244,7 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
3242
3244
  let batchDecomposeWarning;
3243
3245
  if (shouldDecomposeBatch) {
3244
3246
  try {
3245
- const decomposed = await mcpCall(
3247
+ const decomposed = await kernelCall(
3246
3248
  "chain.decomposeContent",
3247
3249
  {
3248
3250
  collectionSlug: resolvedSlug,
@@ -3266,7 +3268,7 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
3266
3268
  }
3267
3269
  canonicalizeSelects(data, col.fields ?? [], batchIsBet);
3268
3270
  try {
3269
- const result = await mcpMutation("chain.createEntry", {
3271
+ const result = await kernelMutation("chain.createEntry", {
3270
3272
  collectionSlug: resolvedSlug,
3271
3273
  entryId: entry.entryId ?? void 0,
3272
3274
  name: entry.name,
@@ -3293,7 +3295,7 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
3293
3295
  const searchQuery = extractSearchTerms(entry.name, entry.description);
3294
3296
  if (searchQuery) {
3295
3297
  try {
3296
- const searchResults = await mcpQuery("chain.searchEntries", { query: searchQuery });
3298
+ const searchResults = await kernelQuery("chain.searchEntries", { query: searchQuery });
3297
3299
  const candidates = (searchResults ?? []).filter((r) => r.entryId !== finalEntryId).map((r) => {
3298
3300
  const conf = computeLinkConfidence(r, entry.name, entry.description, resolvedSlug, collIdToSlug.get(r.collectionId) ?? "unknown");
3299
3301
  return { ...r, collSlug: collIdToSlug.get(r.collectionId) ?? "unknown", confidence: conf.score };
@@ -3308,7 +3310,7 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
3308
3310
  batchAutoLinks.push({ fromEntryId: finalEntryId, toEntryId: c.entryId, type: relationType });
3309
3311
  }
3310
3312
  if (batchAutoLinks.length > 0) {
3311
- const batchRes = await mcpMutation("chain.createEntryRelations", {
3313
+ const batchRes = await kernelMutation("chain.createEntryRelations", {
3312
3314
  relations: batchAutoLinks,
3313
3315
  sessionId: agentId ?? void 0
3314
3316
  });
@@ -3326,7 +3328,7 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
3326
3328
  if (blockingConflicts.length > 0) {
3327
3329
  commitError = `blocked by semantic contradiction preflight: ${blockingConflicts[0]?.chainEntryId} ${blockingConflicts[0]?.explanation ?? ""}`.trim();
3328
3330
  } else {
3329
- const commitResult = await mcpMutation("chain.commitEntry", {
3331
+ const commitResult = await kernelMutation("chain.commitEntry", {
3330
3332
  entryId: finalEntryId,
3331
3333
  author: agentId ? `agent:${agentId}` : void 0,
3332
3334
  sessionId: agentId ?? void 0
@@ -3669,8 +3671,8 @@ async function runContradictionCheck(name, description) {
3669
3671
  if (keyTerms.length === 0) return warnings;
3670
3672
  const searchQuery = keyTerms.slice(0, 5).join(" ");
3671
3673
  const [govResults, archResults] = await Promise.all([
3672
- mcpQuery("chain.searchEntries", { query: searchQuery, collectionSlug: "business-rules" }),
3673
- mcpQuery("chain.searchEntries", { query: searchQuery, collectionSlug: "architecture" })
3674
+ kernelQuery("chain.searchEntries", { query: searchQuery, collectionSlug: "business-rules" }),
3675
+ kernelQuery("chain.searchEntries", { query: searchQuery, collectionSlug: "architecture" })
3674
3676
  ]);
3675
3677
  const allGov = [...govResults ?? [], ...archResults ?? []].slice(0, 5);
3676
3678
  for (const entry of allGov) {
@@ -3679,7 +3681,7 @@ async function runContradictionCheck(name, description) {
3679
3681
  if (matched.length < 3) continue;
3680
3682
  let governsCount = 0;
3681
3683
  try {
3682
- const relations = await mcpQuery("chain.listEntryRelations", {
3684
+ const relations = await kernelQuery("chain.listEntryRelations", {
3683
3685
  entryId: entry.entryId
3684
3686
  });
3685
3687
  governsCount = (relations ?? []).filter((r) => r.type === "governs").length;
@@ -3699,7 +3701,7 @@ async function runContradictionCheck(name, description) {
3699
3701
  var BLOCKING_CONTRADICTION_THRESHOLD = 0.75;
3700
3702
  async function runSemanticConflictPreflight(name, description, collectionHint) {
3701
3703
  try {
3702
- const conflicts = await mcpQuery("chain.detectSemanticConflicts", {
3704
+ const conflicts = await kernelQuery("chain.detectSemanticConflicts", {
3703
3705
  name,
3704
3706
  description,
3705
3707
  ...collectionHint ? { collectionHint } : {}
@@ -3792,7 +3794,7 @@ function isBlockingContradiction(conflict) {
3792
3794
  }
3793
3795
  async function runConflictPreflight(name, description, collectionHint) {
3794
3796
  try {
3795
- const conflicts = await mcpQuery("chain.detectSemanticConflicts", {
3797
+ const conflicts = await kernelQuery("chain.detectSemanticConflicts", {
3796
3798
  name,
3797
3799
  description,
3798
3800
  ...collectionHint ? { collectionHint } : {}
@@ -3803,7 +3805,8 @@ async function runConflictPreflight(name, description, collectionHint) {
3803
3805
  blockingContradictions: conflicts.filter(isBlockingContradiction),
3804
3806
  advisoryWarnings: []
3805
3807
  };
3806
- } catch {
3808
+ } catch (err) {
3809
+ console.error("[conflict-preflight] Semantic conflict detection unavailable, falling back to heuristic:", err instanceof Error ? err.message : String(err));
3807
3810
  const advisoryWarnings = await runContradictionCheck(name, description);
3808
3811
  return {
3809
3812
  source: "heuristic",
@@ -3879,16 +3882,6 @@ function registerKnowledgeTools(server) {
3879
3882
  },
3880
3883
  withEnvelope(async ({ entryId, name, status: rawStatus, workflowStatus: rawWorkflowStatus, data, order, canonicalKey, autoPublish, changeNote, sourceRef, sourceExcerpt }) => {
3881
3884
  requireWriteAccess();
3882
- const PROMOTED_FIELDS = ["status", "workflowStatus", "name", "order", "canonicalKey"];
3883
- const topLevelByField = { status: rawStatus, workflowStatus: rawWorkflowStatus, name, order, canonicalKey };
3884
- const confusedFields = [];
3885
- if (data) {
3886
- for (const field of PROMOTED_FIELDS) {
3887
- if (field in data && topLevelByField[field] === void 0) {
3888
- confusedFields.push(field);
3889
- }
3890
- }
3891
- }
3892
3885
  const fieldsProvided = [];
3893
3886
  if (name !== void 0) fieldsProvided.push("name");
3894
3887
  if (rawStatus !== void 0) fieldsProvided.push("status");
@@ -3906,7 +3899,7 @@ function registerKnowledgeTools(server) {
3906
3899
  status = void 0;
3907
3900
  deprecationWarning = `\u26A0\uFE0F Deprecation: \`status: '${rawStatus}'\` \u2014 use \`workflowStatus: '${rawStatus}'\` instead. Support ends ~2026-09-03.`;
3908
3901
  }
3909
- const updateResult = await mcpMutation("chain.updateEntry", {
3902
+ const updateResult = await kernelMutation("chain.updateEntry", {
3910
3903
  entryId,
3911
3904
  name,
3912
3905
  status,
@@ -3923,7 +3916,7 @@ function registerKnowledgeTools(server) {
3923
3916
  const id = updateResult.id;
3924
3917
  await recordSessionActivity({ entryModified: id });
3925
3918
  const wsCtx = await getWorkspaceContext();
3926
- const updated = await mcpQuery("chain.getEntry", { entryId });
3919
+ const updated = await kernelQuery("chain.getEntry", { entryId });
3927
3920
  const entryStatus = updated?.status ?? "draft";
3928
3921
  const versionMode = entryStatus === "active" ? "published" : `saved as ${entryStatus}`;
3929
3922
  const responseLines = [
@@ -3944,12 +3937,6 @@ function registerKnowledgeTools(server) {
3944
3937
  responseLines.push("");
3945
3938
  responseLines.push(deprecationWarning);
3946
3939
  }
3947
- if (confusedFields.length > 0) {
3948
- responseLines.push("");
3949
- for (const field of confusedFields) {
3950
- responseLines.push(`\u26A0\uFE0F \`data.${field}\` detected \u2014 did you mean the top-level \`${field}\` parameter?`);
3951
- }
3952
- }
3953
3940
  if (updateResult.normalizationWarnings.length > 0) {
3954
3941
  responseLines.push("");
3955
3942
  responseLines.push("\u26A0\uFE0F **Normalization warnings:**");
@@ -3975,7 +3962,6 @@ function registerKnowledgeTools(server) {
3975
3962
  entryId: id,
3976
3963
  versionMode,
3977
3964
  fieldsProvided,
3978
- confusedFields,
3979
3965
  // BET-192: normalization breakdown in structuredContent — symmetric with capture tool
3980
3966
  ...updateResult.normalization && (Object.keys(updateResult.normalization.remapped).length > 0 || updateResult.normalization.rejected.length > 0) && {
3981
3967
  normalization: {
@@ -4003,7 +3989,7 @@ function registerKnowledgeTools(server) {
4003
3989
  annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false }
4004
3990
  },
4005
3991
  withEnvelope(async ({ entryId }) => {
4006
- const history = await mcpQuery("chain.listEntryHistory", { entryId });
3992
+ const history = await kernelQuery("chain.listEntryHistory", { entryId });
4007
3993
  if (history.length === 0) {
4008
3994
  return successResult(
4009
3995
  `No history found for ${entryId}.`,
@@ -4037,7 +4023,7 @@ ${formatted}` }],
4037
4023
  },
4038
4024
  withEnvelope(async ({ entryId, preview }) => {
4039
4025
  requireWriteAccess();
4040
- const entry = await mcpQuery("chain.getEntry", { entryId });
4026
+ const entry = await kernelQuery("chain.getEntry", { entryId });
4041
4027
  if (!entry) {
4042
4028
  return notFoundResult(entryId, `Entry '${entryId}' not found. Try search to find the right ID.`);
4043
4029
  }
@@ -4087,7 +4073,7 @@ ${formatted}` }],
4087
4073
  }
4088
4074
  let coachingResult = null;
4089
4075
  try {
4090
- coachingResult = await mcpMutation("quality.evaluateHeuristicAndSchedule", {
4076
+ coachingResult = await kernelMutation("quality.evaluateHeuristicAndSchedule", {
4091
4077
  entryId,
4092
4078
  context: "commit"
4093
4079
  });
@@ -4095,7 +4081,7 @@ ${formatted}` }],
4095
4081
  }
4096
4082
  let result;
4097
4083
  try {
4098
- result = await mcpMutation("chain.commitEntry", {
4084
+ result = await kernelMutation("chain.commitEntry", {
4099
4085
  entryId,
4100
4086
  author: getAgentSessionId() ? `agent:${getAgentSessionId()}` : void 0,
4101
4087
  sessionId: getAgentSessionId() ?? void 0,
@@ -4234,7 +4220,7 @@ No DB writes \u2014 call without \`preview:true\` to commit for real.` }],
4234
4220
  try {
4235
4221
  const collSlug = entry.collectionSlug ?? entry.collection?.slug;
4236
4222
  if (collSlug) {
4237
- captureContract = await mcpQuery(
4223
+ captureContract = await kernelQuery(
4238
4224
  "chain.getCaptureContract",
4239
4225
  { collectionSlug: collSlug }
4240
4226
  ) ?? void 0;
@@ -4398,7 +4384,7 @@ function registerEntriesTools(server) {
4398
4384
  );
4399
4385
  }
4400
4386
  async function handleGet(entryId) {
4401
- const entry = await mcpQuery("chain.getEntry", { entryId });
4387
+ const entry = await kernelQuery("chain.getEntry", { entryId });
4402
4388
  if (!entry) {
4403
4389
  return notFoundResult(entryId, `Entry '${entryId}' not found. Try search to find the right ID.`);
4404
4390
  }
@@ -4492,7 +4478,7 @@ async function handleGet(entryId) {
4492
4478
  };
4493
4479
  }
4494
4480
  async function handleBatch(entryIds) {
4495
- const results = await mcpQuery("chain.batchGetEntries", { entryIds });
4481
+ const results = await kernelQuery("chain.batchGetEntries", { entryIds });
4496
4482
  const lines = [`## Batch Result`, "", `# Batch Get (${results.length} requested)`, ""];
4497
4483
  for (let i = 0; i < results.length; i++) {
4498
4484
  const r = results[i];
@@ -4583,12 +4569,12 @@ async function handleBatch(entryIds) {
4583
4569
  async function handleList(collection, status, tag, label) {
4584
4570
  let entries;
4585
4571
  if (label) {
4586
- entries = await mcpQuery("chain.listEntriesByLabel", { labelSlug: label });
4572
+ entries = await kernelQuery("chain.listEntriesByLabel", { labelSlug: label });
4587
4573
  if (status) {
4588
4574
  entries = entries.filter((e) => e.status === status);
4589
4575
  }
4590
4576
  } else {
4591
- entries = await mcpQuery("chain.listEntries", {
4577
+ entries = await kernelQuery("chain.listEntries", {
4592
4578
  collectionSlug: collection,
4593
4579
  status,
4594
4580
  tag
@@ -4632,7 +4618,7 @@ ${formatted}` }],
4632
4618
  }
4633
4619
  async function handleMove(entryId, toCollection) {
4634
4620
  try {
4635
- const result = await mcpMutation("chain.moveToCollection", { entryId, toCollectionSlug: toCollection });
4621
+ const result = await kernelMutation("chain.moveToCollection", { entryId, toCollectionSlug: toCollection });
4636
4622
  const lines = [
4637
4623
  `## Move Result`,
4638
4624
  "",
@@ -4673,8 +4659,8 @@ async function handleSearch(server, query, collection, status) {
4673
4659
  logger: "product-os"
4674
4660
  });
4675
4661
  const [results, collections] = await Promise.all([
4676
- mcpQuery("chain.searchEntries", { query, collectionSlug: collection, status }),
4677
- mcpQuery("chain.listCollections")
4662
+ kernelQuery("chain.searchEntries", { query, collectionSlug: collection, status }),
4663
+ kernelQuery("chain.listCollections")
4678
4664
  ]);
4679
4665
  if (results.length === 0) {
4680
4666
  const recorded = recordGap({ query, tool: "entries", action: "search", gapType: "search_zero", collectionScope: collection });
@@ -4815,7 +4801,7 @@ function registerGraphTools(server) {
4815
4801
  );
4816
4802
  }
4817
4803
  async function handleFind(entryId, direction) {
4818
- const relations = await mcpQuery("chain.listEntryRelations", { entryId });
4804
+ const relations = await kernelQuery("chain.listEntryRelations", { entryId });
4819
4805
  if (relations.length === 0) {
4820
4806
  return {
4821
4807
  content: [{ type: "text", text: `No relations found for \`${entryId}\`. Use relations action=create to create connections.` }],
@@ -4829,7 +4815,7 @@ async function handleFind(entryId, direction) {
4829
4815
  )
4830
4816
  };
4831
4817
  }
4832
- const sourceEntry = await mcpQuery("chain.getEntry", { entryId });
4818
+ const sourceEntry = await kernelQuery("chain.getEntry", { entryId });
4833
4819
  if (!sourceEntry) {
4834
4820
  return notFoundResult(entryId, `Entry '${entryId}' not found. Try entries action=search to find the right ID.`);
4835
4821
  }
@@ -4844,12 +4830,12 @@ async function handleFind(entryId, direction) {
4844
4830
  }
4845
4831
  const otherEntries = /* @__PURE__ */ new Map();
4846
4832
  for (const id of otherIds) {
4847
- const entry = await mcpQuery("chain.getEntry", { id });
4833
+ const entry = await kernelQuery("chain.getEntry", { id });
4848
4834
  if (entry) {
4849
4835
  otherEntries.set(entry._id, { entryId: entry.entryId, name: entry.name, collectionId: entry.collectionId });
4850
4836
  }
4851
4837
  }
4852
- const collections = await mcpQuery("chain.listCollections");
4838
+ const collections = await kernelQuery("chain.listCollections");
4853
4839
  const collMap = /* @__PURE__ */ new Map();
4854
4840
  for (const c of collections) collMap.set(c._id, c.slug);
4855
4841
  const lines = [`## Find Result`, "", `# Relations for ${entryId}: ${sourceEntry.name}`, ""];
@@ -4913,7 +4899,7 @@ async function handleFind(entryId, direction) {
4913
4899
  };
4914
4900
  }
4915
4901
  async function handleSuggest(entryId, limit, depth) {
4916
- const result = await mcpQuery("chain.graphSuggestLinks", {
4902
+ const result = await kernelQuery("chain.graphSuggestLinks", {
4917
4903
  entryId,
4918
4904
  maxHops: depth,
4919
4905
  limit
@@ -5067,7 +5053,7 @@ function registerRelationsTools(server) {
5067
5053
  async function handleCreate(from, to, type, score, preview) {
5068
5054
  requireWriteAccess();
5069
5055
  const agentSessionId = getAgentSessionId();
5070
- const result = await mcpMutation("chain.createEntryRelation", {
5056
+ const result = await kernelMutation("chain.createEntryRelation", {
5071
5057
  fromEntryId: from,
5072
5058
  toEntryId: to,
5073
5059
  type,
@@ -5157,7 +5143,7 @@ async function handleBatchCreate(relations) {
5157
5143
  const batchRels = relations.filter((r) => r.type !== "governs");
5158
5144
  if (batchRels.length > 0) {
5159
5145
  try {
5160
- const batchResult = await mcpMutation("chain.createEntryRelations", {
5146
+ const batchResult = await kernelMutation("chain.createEntryRelations", {
5161
5147
  relations: batchRels.map((r) => ({ fromEntryId: r.from, toEntryId: r.to, type: r.type })),
5162
5148
  sessionId: agentSessionId ?? void 0
5163
5149
  });
@@ -5174,7 +5160,7 @@ async function handleBatchCreate(relations) {
5174
5160
  }
5175
5161
  for (const rel of governsRels) {
5176
5162
  try {
5177
- const result = await mcpMutation("chain.createEntryRelation", {
5163
+ const result = await kernelMutation("chain.createEntryRelation", {
5178
5164
  fromEntryId: rel.from,
5179
5165
  toEntryId: rel.to,
5180
5166
  type: rel.type,
@@ -5229,15 +5215,15 @@ async function handleBatchCreate(relations) {
5229
5215
  }
5230
5216
  async function handleDismiss(from, to, type, score) {
5231
5217
  requireWriteAccess();
5232
- const fromEntry = await mcpQuery("chain.getEntry", { entryId: from });
5218
+ const fromEntry = await kernelQuery("chain.getEntry", { entryId: from });
5233
5219
  if (!fromEntry) {
5234
5220
  return notFoundResult(from);
5235
5221
  }
5236
- const toEntry = await mcpQuery("chain.getEntry", { entryId: to });
5222
+ const toEntry = await kernelQuery("chain.getEntry", { entryId: to });
5237
5223
  if (!toEntry) {
5238
5224
  return notFoundResult(to);
5239
5225
  }
5240
- await mcpMutation("chain.dismissSuggestion", {
5226
+ await kernelMutation("chain.dismissSuggestion", {
5241
5227
  fromEntryId: fromEntry._id,
5242
5228
  suggestedEntryId: toEntry._id,
5243
5229
  recommendedType: type,
@@ -5251,7 +5237,7 @@ async function handleDismiss(from, to, type, score) {
5251
5237
  }
5252
5238
  async function handleDelete(from, to, type) {
5253
5239
  requireWriteAccess();
5254
- await mcpMutation("chain.removeEntryRelation", {
5240
+ await kernelMutation("chain.removeEntryRelation", {
5255
5241
  fromEntryId: from,
5256
5242
  toEntryId: to,
5257
5243
  type
@@ -5385,7 +5371,7 @@ async function handleGather(server, entryId, task, mode, maxHops, maxResults, st
5385
5371
  data: `Graph traversal for ${entryId} (depth: ${maxHops})...`,
5386
5372
  logger: "product-brain"
5387
5373
  });
5388
- const result2 = await mcpQuery("chain.graphGatherContext", {
5374
+ const result2 = await kernelQuery("chain.graphGatherContext", {
5389
5375
  entryId,
5390
5376
  maxHops
5391
5377
  });
@@ -5471,11 +5457,11 @@ Use \`graph action=suggest\` to discover potential connections.`
5471
5457
  data: `Loading context for task: "${task.substring(0, 80)}..." [strategy: ${strategyLabel}]`,
5472
5458
  logger: "product-brain"
5473
5459
  });
5474
- const result2 = strategy === "hybrid" ? await mcpQuery("chain.resolveTaskStartupHybrid", {
5460
+ const result2 = strategy === "hybrid" ? await kernelQuery("chain.resolveTaskStartupHybrid", {
5475
5461
  task,
5476
5462
  maxHops,
5477
5463
  maxResults
5478
- }) : await mcpQuery("chain.resolveTaskStartup", {
5464
+ }) : await kernelQuery("chain.resolveTaskStartup", {
5479
5465
  task,
5480
5466
  maxHops,
5481
5467
  maxResults
@@ -5643,7 +5629,7 @@ _This helps future sessions start with better constraints and context._`
5643
5629
  data: `Gathering context for ${entryId} (depth: ${maxHops})...`,
5644
5630
  logger: "product-brain"
5645
5631
  });
5646
- const result = await mcpQuery("chain.gatherContext", { entryId, maxHops });
5632
+ const result = await kernelQuery("chain.gatherContext", { entryId, maxHops });
5647
5633
  if (!result?.root) {
5648
5634
  return notFoundResult(entryId, `Entry '${entryId}' not found. Try search to find the right ID.`);
5649
5635
  }
@@ -5718,7 +5704,7 @@ async function handleJourneyGather(server, mapEntryId, maxHops, maxResults) {
5718
5704
  data: `Loading journey context for map ${mapEntryId}...`,
5719
5705
  logger: "product-brain"
5720
5706
  });
5721
- const result = await mcpQuery("chain.journeyAwareGatherContext", {
5707
+ const result = await kernelQuery("chain.journeyAwareGatherContext", {
5722
5708
  mapEntryId,
5723
5709
  maxHops,
5724
5710
  maxResults
@@ -5798,7 +5784,7 @@ Add journey steps via MCP: \`map-slot action=add mapEntryId="${mapEntryId}" slot
5798
5784
  };
5799
5785
  }
5800
5786
  async function handleNeighborhood(entryId) {
5801
- const result = await mcpQuery("chain.getEntryNeighborhood", { entryId, now: Date.now() });
5787
+ const result = await kernelQuery("chain.getEntryNeighborhood", { entryId, now: Date.now() });
5802
5788
  const lines = [`# Neighborhood: ${entryId}`, ""];
5803
5789
  if (result.blockingChain.length > 0) {
5804
5790
  lines.push(`## Blocking Chain (${result.blockingChain.length})`);
@@ -5865,7 +5851,7 @@ async function handleBuild(server, entryId, maxHops) {
5865
5851
  data: `Assembling build context for ${entryId}...`,
5866
5852
  logger: "product-brain"
5867
5853
  });
5868
- const result = await mcpQuery("chain.assembleBuildContext", {
5854
+ const result = await kernelQuery("chain.assembleBuildContext", {
5869
5855
  entryId,
5870
5856
  maxHops
5871
5857
  });
@@ -5934,7 +5920,7 @@ async function handleBuild(server, entryId, maxHops) {
5934
5920
  };
5935
5921
  }
5936
5922
  async function handleCrossCut(relationType) {
5937
- const result = await mcpQuery("chain.structuralAggregation", {
5923
+ const result = await kernelQuery("chain.structuralAggregation", {
5938
5924
  relationType
5939
5925
  });
5940
5926
  const groupKeys = Object.keys(result.groups);
@@ -5979,7 +5965,7 @@ No relations of type '${relationType}' found in this workspace.`
5979
5965
  }
5980
5966
  async function handleChainWalk(entryId, direction, maxHops, relationType) {
5981
5967
  const clampedHops = Math.max(1, Math.min(4, maxHops));
5982
- const result = await mcpQuery("chain.deepChainWalk", {
5968
+ const result = await kernelQuery("chain.deepChainWalk", {
5983
5969
  entryId,
5984
5970
  direction,
5985
5971
  maxHops: clampedHops,
@@ -6051,7 +6037,7 @@ async function handleChanges(since) {
6051
6037
  if (isNaN(sinceMs)) {
6052
6038
  return validationResult(`Invalid 'since' timestamp: '${since}'. Use ISO 8601 format (e.g. '2026-03-24T00:00:00Z').`);
6053
6039
  }
6054
- const result = await mcpQuery("chain.changeDetection", { since: sinceMs });
6040
+ const result = await kernelQuery("chain.changeDetection", { since: sinceMs });
6055
6041
  const totalEntries = result.entries.length;
6056
6042
  const totalRelations = result.relations.length;
6057
6043
  if (totalEntries === 0 && totalRelations === 0) {
@@ -6109,10 +6095,10 @@ No entries modified or relations created since this timestamp.`
6109
6095
  };
6110
6096
  }
6111
6097
  async function handleIncremental(skill) {
6112
- const result = await mcpQuery("chain.incrementalChanges", { skill });
6098
+ const result = await kernelQuery("chain.incrementalChanges", { skill });
6113
6099
  const totalEntries = result.newEntries.length;
6114
6100
  const surfacedIds = result.newEntries.map((e) => e.entryId).filter((id) => id !== null);
6115
- mcpMutation("chain.recordBriefRun", {
6101
+ kernelMutation("chain.recordBriefRun", {
6116
6102
  skill,
6117
6103
  entriesSurfaced: surfacedIds,
6118
6104
  timestamp: Date.now()
@@ -6176,7 +6162,7 @@ No new entries since last brief run (${formatTimeAgo(result.previousRunTimestamp
6176
6162
  async function handleBrief(briefType, sinceMs) {
6177
6163
  const args = { type: briefType };
6178
6164
  if (sinceMs !== void 0) args.since = sinceMs;
6179
- const result = await mcpQuery("chain.compoundQuery", args);
6165
+ const result = await kernelQuery("chain.compoundQuery", args);
6180
6166
  if (briefType === "steering") {
6181
6167
  return formatSteeringBrief(result);
6182
6168
  }
@@ -6434,7 +6420,7 @@ function registerCollectionsTools(server) {
6434
6420
  trackWriteTool(tool);
6435
6421
  }
6436
6422
  async function handleDescribe(slug) {
6437
- const col = await mcpQuery("chain.getCollection", { slug });
6423
+ const col = await kernelQuery("chain.getCollection", { slug });
6438
6424
  if (!col) {
6439
6425
  return failureResult(
6440
6426
  `Collection '${slug}' not found.`,
@@ -6527,7 +6513,7 @@ ${refList}`);
6527
6513
  };
6528
6514
  }
6529
6515
  async function handleList2() {
6530
- const collections = await mcpQuery("chain.listCollections");
6516
+ const collections = await kernelQuery("chain.listCollections");
6531
6517
  if (collections.length === 0) {
6532
6518
  return successResult(
6533
6519
  "No collections found in this workspace.",
@@ -6570,7 +6556,7 @@ ${formatted}` }],
6570
6556
  async function handleCreate2(slug, name, description, purpose, icon, navGroup, fields, meta = {}) {
6571
6557
  requireWriteAccess();
6572
6558
  try {
6573
- await mcpMutation("chain.createCollection", {
6559
+ await kernelMutation("chain.createCollection", {
6574
6560
  slug,
6575
6561
  name,
6576
6562
  description,
@@ -6618,12 +6604,22 @@ You can now capture entries: \`capture collection="${slug}" name="..." descripti
6618
6604
  [{ tool: "collections", description: "Update collection", parameters: { action: "update", slug } }]
6619
6605
  );
6620
6606
  }
6607
+ const code = error.code ?? error.data?.code;
6608
+ if (code === "COLLECTION_PREFIX_TAKEN" || msg.includes("already used by collection")) {
6609
+ return failureResult(
6610
+ msg,
6611
+ "DUPLICATE",
6612
+ msg,
6613
+ "Choose a different prefix by passing the idPrefix parameter, or let the system derive one from a different slug.",
6614
+ [{ tool: "collections", description: "List collections to see taken prefixes", parameters: { action: "list" } }]
6615
+ );
6616
+ }
6621
6617
  throw error;
6622
6618
  }
6623
6619
  }
6624
6620
  async function handleUpdate(slug, name, description, purpose, icon, navGroup, fields, meta = {}) {
6625
6621
  requireWriteAccess();
6626
- await mcpMutation("chain.updateCollection", {
6622
+ await kernelMutation("chain.updateCollection", {
6627
6623
  slug,
6628
6624
  ...name !== void 0 && { name },
6629
6625
  ...description !== void 0 && { description },
@@ -6656,7 +6652,7 @@ Use \`collections action=list\` to verify the result.`
6656
6652
  };
6657
6653
  }
6658
6654
  async function handleAudit() {
6659
- const data = await mcpQuery("chain.auditCollections");
6655
+ const data = await kernelQuery("chain.auditCollections");
6660
6656
  const lines = [];
6661
6657
  lines.push(`# Collection Audit Report`);
6662
6658
  lines.push(`
@@ -6694,7 +6690,7 @@ All collections are healthy.`);
6694
6690
  };
6695
6691
  }
6696
6692
  async function handleExport() {
6697
- const definitions = await mcpQuery("chain.exportDefinitions");
6693
+ const definitions = await kernelQuery("chain.exportDefinitions");
6698
6694
  return {
6699
6695
  content: [{ type: "text", text: JSON.stringify(definitions, null, 2) }],
6700
6696
  structuredContent: success(
@@ -6728,7 +6724,7 @@ function registerLabelTools(server) {
6728
6724
  },
6729
6725
  withEnvelope(async ({ action, slug, name, color, description, parentSlug, isGroup, order, entryId }) => {
6730
6726
  if (action === "list") {
6731
- const labels = await mcpQuery("chain.listLabels");
6727
+ const labels = await kernelQuery("chain.listLabels");
6732
6728
  if (labels.length === 0) {
6733
6729
  return successResult(
6734
6730
  "No labels defined in this workspace yet.",
@@ -6774,7 +6770,7 @@ function registerLabelTools(server) {
6774
6770
  }
6775
6771
  let parentId;
6776
6772
  if (parentSlug) {
6777
- const labels = await mcpQuery("chain.listLabels");
6773
+ const labels = await kernelQuery("chain.listLabels");
6778
6774
  const parent = labels.find((l) => l.slug === parentSlug);
6779
6775
  if (!parent) {
6780
6776
  return failureResult(
@@ -6787,7 +6783,7 @@ function registerLabelTools(server) {
6787
6783
  }
6788
6784
  parentId = parent._id;
6789
6785
  }
6790
- await mcpMutation("chain.createLabel", { slug, name, color, description, parentId, isGroup, order });
6786
+ await kernelMutation("chain.createLabel", { slug, name, color, description, parentId, isGroup, order });
6791
6787
  return successResult(
6792
6788
  `Label '${name}' (${slug}) created.`,
6793
6789
  `Created label '${name}' (${slug}).`,
@@ -6796,7 +6792,7 @@ function registerLabelTools(server) {
6796
6792
  );
6797
6793
  }
6798
6794
  if (action === "update") {
6799
- await mcpMutation("chain.updateLabel", { slug, name, color, description, isGroup, order });
6795
+ await kernelMutation("chain.updateLabel", { slug, name, color, description, isGroup, order });
6800
6796
  return successResult(
6801
6797
  `Label '${slug}' updated.`,
6802
6798
  `Updated label '${slug}'.`,
@@ -6805,7 +6801,7 @@ function registerLabelTools(server) {
6805
6801
  );
6806
6802
  }
6807
6803
  if (action === "delete") {
6808
- await mcpMutation("chain.deleteLabel", { slug });
6804
+ await kernelMutation("chain.deleteLabel", { slug });
6809
6805
  return successResult(
6810
6806
  `Label '${slug}' removed from all entries and deleted.`,
6811
6807
  `Deleted label '${slug}'.`,
@@ -6817,10 +6813,10 @@ function registerLabelTools(server) {
6817
6813
  return validationResult("An entryId is required for apply/remove actions.");
6818
6814
  }
6819
6815
  if (action === "apply") {
6820
- await mcpMutation("chain.applyLabel", { entryId, labelSlug: slug });
6816
+ await kernelMutation("chain.applyLabel", { entryId, labelSlug: slug });
6821
6817
  return successResult(`Label '${slug}' applied to ${entryId}.`, `Applied label '${slug}' to ${entryId}.`, { slug, entryId });
6822
6818
  }
6823
- await mcpMutation("chain.removeLabel", { entryId, labelSlug: slug });
6819
+ await kernelMutation("chain.removeLabel", { entryId, labelSlug: slug });
6824
6820
  return successResult(`Label '${slug}' removed from ${entryId}.`, `Removed label '${slug}' from ${entryId}.`, { slug, entryId });
6825
6821
  }
6826
6822
  return validationResult("Unknown action.");
@@ -7426,7 +7422,7 @@ function isValidTopGap(g) {
7426
7422
  }
7427
7423
  async function fetchSessionCoherenceSnapshot(sessionId) {
7428
7424
  try {
7429
- const session = await mcpCall("agent.getSession", {
7425
+ const session = await kernelCall("agent.getSession", {
7430
7426
  sessionId
7431
7427
  });
7432
7428
  const raw = session?.coherenceSnapshot;
@@ -7445,7 +7441,7 @@ async function suggestLinksForEntries(entries) {
7445
7441
  const results = await mapWithConcurrency(
7446
7442
  entries,
7447
7443
  async (entry) => {
7448
- const result = await mcpQuery("chain.graphSuggestLinks", {
7444
+ const result = await kernelQuery("chain.graphSuggestLinks", {
7449
7445
  entryId: entry.entryId,
7450
7446
  limit: 3
7451
7447
  });
@@ -7475,7 +7471,7 @@ async function runWrapupReview() {
7475
7471
  if (getApiKeyScope() === "read") {
7476
7472
  return { text: "Read-only session \u2014 nothing to review.", data: null, suggestions: [], failureCode: "READONLY_SCOPE" };
7477
7473
  }
7478
- const kernelEnvelope = await mcpCallEnvelope("agent.getSessionWrapup", { sessionId });
7474
+ const kernelEnvelope = await kernelCallEnvelope("agent.getSessionWrapup", { sessionId });
7479
7475
  const data = kernelEnvelope.data;
7480
7476
  if (data.wrapupCompletedAt) {
7481
7477
  return { text: "Wrapup already completed this session.", data, suggestions: [], failureCode: "ALREADY_COMPLETED" };
@@ -7641,7 +7637,7 @@ async function runWrapupCommitAll(data, cachedSuggestions) {
7641
7637
  let proposalsCreated = 0;
7642
7638
  for (const draft of data.drafts) {
7643
7639
  try {
7644
- const result = await mcpMutation("chain.commitEntry", {
7640
+ const result = await kernelMutation("chain.commitEntry", {
7645
7641
  entryId: draft.entryId,
7646
7642
  author: `agent:${sessionId}`,
7647
7643
  sessionId
@@ -7678,7 +7674,7 @@ async function runWrapupCommitAll(data, cachedSuggestions) {
7678
7674
  const batchRels = toApply.filter((s) => s.type !== "governs");
7679
7675
  if (batchRels.length > 0) {
7680
7676
  try {
7681
- const batchResult = await mcpMutation("chain.createEntryRelations", {
7677
+ const batchResult = await kernelMutation("chain.createEntryRelations", {
7682
7678
  relations: batchRels.map((s) => ({
7683
7679
  fromEntryId: s.fromEntryId,
7684
7680
  toEntryId: s.toEntryId,
@@ -7707,7 +7703,7 @@ async function runWrapupCommitAll(data, cachedSuggestions) {
7707
7703
  }
7708
7704
  for (const s of governsRels) {
7709
7705
  try {
7710
- const result = await mcpMutation("chain.createEntryRelation", {
7706
+ const result = await kernelMutation("chain.createEntryRelation", {
7711
7707
  fromEntryId: s.fromEntryId,
7712
7708
  toEntryId: s.toEntryId,
7713
7709
  type: s.type,
@@ -7724,7 +7720,7 @@ async function runWrapupCommitAll(data, cachedSuggestions) {
7724
7720
  }
7725
7721
  const committed = results.filter((r) => r.ok && !r.proposed).length;
7726
7722
  const failed = results.filter((r) => !r.ok);
7727
- await mcpCall("agent.recordWrapup", {
7723
+ await kernelCall("agent.recordWrapup", {
7728
7724
  sessionId,
7729
7725
  draftsReviewed: data.drafts.length,
7730
7726
  draftsCommitted: committed,
@@ -7786,7 +7782,7 @@ function registerWrapupTools(server) {
7786
7782
  );
7787
7783
  }
7788
7784
  const useCachedReview = lastReviewSessionId === sessionId;
7789
- const data2 = useCachedReview && lastReviewData ? lastReviewData : (await mcpCallEnvelope("agent.getSessionWrapup", { sessionId })).data;
7785
+ const data2 = useCachedReview && lastReviewData ? lastReviewData : (await kernelCallEnvelope("agent.getSessionWrapup", { sessionId })).data;
7790
7786
  if (data2.drafts.length === 0) {
7791
7787
  return failureResult("No uncommitted drafts to commit.", "NOT_FOUND", "No uncommitted drafts to commit.", "Nothing to commit.");
7792
7788
  }
@@ -7929,7 +7925,7 @@ async function handleClose() {
7929
7925
  [{ tool: "session", description: "Start a session", parameters: { action: "start" } }]
7930
7926
  );
7931
7927
  }
7932
- const session = await mcpCall("agent.getSession", {
7928
+ const session = await kernelCall("agent.getSession", {
7933
7929
  sessionId
7934
7930
  });
7935
7931
  let wrapupNudge = "";
@@ -8009,7 +8005,7 @@ async function handleStatus() {
8009
8005
  [{ tool: "session", description: "Start a session", parameters: { action: "start" } }]
8010
8006
  );
8011
8007
  }
8012
- const session = await mcpCall("agent.getSession", {
8008
+ const session = await kernelCall("agent.getSession", {
8013
8009
  sessionId
8014
8010
  });
8015
8011
  if (!session) {
@@ -8115,7 +8111,7 @@ async function handleCheck(entryId) {
8115
8111
  );
8116
8112
  if (needsRelations) {
8117
8113
  try {
8118
- const suggestions = await mcpQuery("chain.graphSuggestLinks", {
8114
+ const suggestions = await kernelQuery("chain.graphSuggestLinks", {
8119
8115
  entryId,
8120
8116
  maxHops: 2,
8121
8117
  limit: 3
@@ -8131,7 +8127,7 @@ ${linkHints}`;
8131
8127
  }
8132
8128
  }
8133
8129
  try {
8134
- const verdict = await mcpQuery("quality.getLatestVerdictForEntry", { entryId });
8130
+ const verdict = await kernelQuery("quality.getLatestVerdictForEntry", { entryId });
8135
8131
  if (verdict && verdict.criteria && verdict.criteria.length > 0) {
8136
8132
  result.text += "\n\n" + formatRubricVerdictSection(verdict);
8137
8133
  try {
@@ -8176,7 +8172,7 @@ ${linkHints}`;
8176
8172
  async function handleReEvaluate(entryId, context) {
8177
8173
  requireWriteAccess();
8178
8174
  const ws = await getWorkspaceContext();
8179
- const result = await mcpMutation("quality.reEvaluateEntry", {
8175
+ const result = await kernelMutation("quality.reEvaluateEntry", {
8180
8176
  entryId,
8181
8177
  context
8182
8178
  });
@@ -9307,7 +9303,7 @@ Use workflows action=list to see workflow names and round structure.`
9307
9303
  }
9308
9304
  let run = null;
9309
9305
  try {
9310
- run = await mcpQuery("chainwork.getLatestWorkflowRun", {
9306
+ run = await kernelQuery("chainwork.getLatestWorkflowRun", {
9311
9307
  agentSessionId,
9312
9308
  workflowId: wf.id
9313
9309
  });
@@ -9372,7 +9368,7 @@ Use workflows action=list to see workflow names and round structure.`
9372
9368
  async function handleGetRun(runId, workflowId) {
9373
9369
  let run;
9374
9370
  if (runId) {
9375
- run = await mcpQuery("chainwork.getWorkflowRun", {
9371
+ run = await kernelQuery("chainwork.getWorkflowRun", {
9376
9372
  runId
9377
9373
  });
9378
9374
  } else {
@@ -9383,7 +9379,7 @@ async function handleGetRun(runId, workflowId) {
9383
9379
  "Active session required for workflow run inspection by workflowId."
9384
9380
  );
9385
9381
  }
9386
- run = await mcpQuery("chainwork.getLatestWorkflowRun", {
9382
+ run = await kernelQuery("chainwork.getLatestWorkflowRun", {
9387
9383
  agentSessionId,
9388
9384
  workflowId
9389
9385
  });
@@ -9546,7 +9542,7 @@ This checkpoint was NOT saved. The conversation context is preserved \u2014 cont
9546
9542
  );
9547
9543
  }
9548
9544
  const resolvedSummaryCapture = summaryCapture;
9549
- const existingRun = await mcpQuery(
9545
+ const existingRun = await kernelQuery(
9550
9546
  "chainwork.getLatestWorkflowRun",
9551
9547
  {
9552
9548
  agentSessionId,
@@ -9568,7 +9564,7 @@ This checkpoint was NOT saved. The conversation context is preserved \u2014 cont
9568
9564
  resolvedCollectionSlug = resolved.collection;
9569
9565
  }
9570
9566
  }
9571
- const result = await mcpMutation("chainwork.finalizeWorkflowRun", {
9567
+ const result = await kernelMutation("chainwork.finalizeWorkflowRun", {
9572
9568
  agentSessionId,
9573
9569
  workflowId: wf.id,
9574
9570
  workflowName: wf.name,
@@ -9666,7 +9662,7 @@ This checkpoint was NOT saved. The conversation context is preserved \u2014 cont
9666
9662
  try {
9667
9663
  const descriptor = getWorkflowDescriptor(workflowId);
9668
9664
  const template = descriptor ? getWorkflowTemplateMetadata(descriptor) : { slug: wf.id, name: wf.name };
9669
- const checkpointResult = await mcpMutation("chainwork.recordWorkflowCheckpoint", {
9665
+ const checkpointResult = await kernelMutation("chainwork.recordWorkflowCheckpoint", {
9670
9666
  agentSessionId,
9671
9667
  workflowId: wf.id,
9672
9668
  workflowName: wf.name,
@@ -9754,7 +9750,7 @@ This checkpoint was NOT saved. The conversation context is preserved \u2014 cont
9754
9750
  async function handleFacilitatedFinalization(wf, descriptor, roundId, normalizedOutput, agentSessionId, summaryEntryId, lines, runId) {
9755
9751
  const template = descriptor ? getWorkflowTemplateMetadata(descriptor) : { slug: wf.id, name: wf.name };
9756
9752
  try {
9757
- const checkpointResult = await mcpMutation("chainwork.recordWorkflowCheckpoint", {
9753
+ const checkpointResult = await kernelMutation("chainwork.recordWorkflowCheckpoint", {
9758
9754
  agentSessionId,
9759
9755
  workflowId: wf.id,
9760
9756
  workflowName: wf.name,
@@ -9872,14 +9868,14 @@ function buildStudioUrl(workspaceSlug, entryId) {
9872
9868
  }
9873
9869
  async function loadBetEntry(entryId) {
9874
9870
  try {
9875
- return await mcpQuery("chain.getEntry", { entryId });
9871
+ return await kernelQuery("chain.getEntry", { entryId });
9876
9872
  } catch {
9877
9873
  return null;
9878
9874
  }
9879
9875
  }
9880
9876
  async function loadConstellationState(betEntryId, betInternalId) {
9881
9877
  try {
9882
- const relations = await mcpQuery("chain.listEntryRelations", {
9878
+ const relations = await kernelQuery("chain.listEntryRelations", {
9883
9879
  entryId: betEntryId
9884
9880
  });
9885
9881
  const internalId = betInternalId ?? (await loadBetEntry(betEntryId))?._id;
@@ -9904,7 +9900,7 @@ var RELATION_TO_COLLECTION = {
9904
9900
  };
9905
9901
  async function loadSessionDrafts(betEntryId, betInternalId) {
9906
9902
  try {
9907
- const relations = await mcpQuery("chain.listEntryRelations", {
9903
+ const relations = await kernelQuery("chain.listEntryRelations", {
9908
9904
  entryId: betEntryId
9909
9905
  });
9910
9906
  const internalId = betInternalId ?? (await loadBetEntry(betEntryId))?._id;
@@ -9914,7 +9910,7 @@ async function loadSessionDrafts(betEntryId, betInternalId) {
9914
9910
  const drafts = [];
9915
9911
  for (const rel of incoming.slice(0, 15)) {
9916
9912
  try {
9917
- const entry = await mcpQuery(
9913
+ const entry = await kernelQuery(
9918
9914
  "chain.getEntry",
9919
9915
  { id: rel.fromId }
9920
9916
  );
@@ -10045,7 +10041,7 @@ async function handleCommitConstellation(args) {
10045
10041
  }
10046
10042
  const betData = betEntry.data ?? {};
10047
10043
  const operationId = args.operationId ?? `${betId}:${getAgentSessionId() ?? "sessionless"}:${betEntry.status}:${betEntry.currentVersion ?? 0}`;
10048
- const { blockers: commitBlockerItems, totalRelations } = await mcpQuery("chain.validateCommitConstellation", { betEntryId: betId });
10044
+ const { blockers: commitBlockerItems, totalRelations } = await kernelQuery("chain.validateCommitConstellation", { betEntryId: betId });
10049
10045
  if (commitBlockerItems.length > 0) {
10050
10046
  return {
10051
10047
  content: [{
@@ -10116,11 +10112,13 @@ async function handleCommitConstellation(args) {
10116
10112
  let kernelEnvelope;
10117
10113
  let result;
10118
10114
  try {
10119
- kernelEnvelope = await mcpCallEnvelope("chain.batchCommitConstellation", {
10115
+ kernelEnvelope = await kernelCallEnvelope("chain.batchCommitConstellation", {
10120
10116
  betEntryId: betId,
10121
10117
  author,
10122
10118
  sessionId,
10123
- operationId
10119
+ operationId,
10120
+ conflicts: preflight.conflicts
10121
+ // pass for kernel-side enforcement (TEN-1405)
10124
10122
  });
10125
10123
  result = kernelEnvelope.data;
10126
10124
  } catch (err) {
@@ -10152,7 +10150,7 @@ No constellation entries were committed.`
10152
10150
  };
10153
10151
  for (const entryId of result.committedIds) {
10154
10152
  try {
10155
- const committedEntry = await mcpQuery("chain.getEntry", { entryId });
10153
+ const committedEntry = await kernelQuery("chain.getEntry", { entryId });
10156
10154
  const docId = committedEntry?._id;
10157
10155
  if (typeof docId === "string" && docId.length > 0) {
10158
10156
  await recordSessionActivity({ entryModified: docId });
@@ -10387,7 +10385,7 @@ function registerVerifyTools(server) {
10387
10385
  data: `Verifying "${collection}" against ${schema.size} schema tables at ${projectRoot}`,
10388
10386
  logger: "product-os"
10389
10387
  });
10390
- const scopedEntries = await mcpQuery("chain.listEntries", { collectionSlug: collection });
10388
+ const scopedEntries = await kernelQuery("chain.listEntries", { collectionSlug: collection });
10391
10389
  if (scopedEntries.length === 0) {
10392
10390
  return failureResult(
10393
10391
  `No entries found in '${collection}'. Nothing to verify.`,
@@ -10404,7 +10402,7 @@ function registerVerifyTools(server) {
10404
10402
  });
10405
10403
  let allEntryIds;
10406
10404
  try {
10407
- const allEntries = await mcpQuery("chain.listEntries", {});
10405
+ const allEntries = await kernelQuery("chain.listEntries", {});
10408
10406
  allEntryIds = new Set(allEntries.map((e) => e.entryId).filter(Boolean));
10409
10407
  } catch {
10410
10408
  allEntryIds = new Set(scopedEntries.map((e) => e.entryId).filter(Boolean));
@@ -10483,7 +10481,7 @@ function registerVerifyTools(server) {
10483
10481
  const updated = (entry.data?.codeMapping ?? []).map(
10484
10482
  (cm) => cm.status === "aligned" && driftedFields.has(cm.field) ? { ...cm, status: "drifted" } : cm
10485
10483
  );
10486
- const updateResult = await mcpMutation("chain.updateEntry", {
10484
+ const updateResult = await kernelMutation("chain.updateEntry", {
10487
10485
  entryId: entry.entryId,
10488
10486
  data: { codeMapping: updated }
10489
10487
  });
@@ -10561,7 +10559,7 @@ function registerVerifyTools(server) {
10561
10559
  annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false }
10562
10560
  },
10563
10561
  withEnvelope(async ({ entryId }) => {
10564
- const result = await mcpMutation("chain.verifyEntry", { entryId });
10562
+ const result = await kernelMutation("chain.verifyEntry", { entryId });
10565
10563
  return success(`Entry ${entryId} verified.`, result);
10566
10564
  })
10567
10565
  );
@@ -10721,7 +10719,7 @@ function buildPlannedWork(allEntries) {
10721
10719
  }
10722
10720
  async function queryPlannedWork() {
10723
10721
  try {
10724
- const allEntries = await mcpQuery("chain.listEntries", {});
10722
+ const allEntries = await kernelQuery("chain.listEntries", {});
10725
10723
  if (!allEntries) return { uncommittedDrafts: [], inProgressEntries: [], openTensions: [] };
10726
10724
  return buildPlannedWork(allEntries);
10727
10725
  } catch {
@@ -11258,7 +11256,7 @@ function formatGapOneLiner(gap) {
11258
11256
  async function tryMarkOriented(agentSessionId, coherenceSnapshot) {
11259
11257
  if (!agentSessionId) return { oriented: false, orientationStatus: "no_session" };
11260
11258
  try {
11261
- await mcpCall("agent.markOriented", {
11259
+ await kernelCall("agent.markOriented", {
11262
11260
  sessionId: agentSessionId,
11263
11261
  ...coherenceSnapshot ? { coherenceSnapshot } : {}
11264
11262
  });
@@ -11269,7 +11267,7 @@ async function tryMarkOriented(agentSessionId, coherenceSnapshot) {
11269
11267
  return { oriented: false, orientationStatus: "failed" };
11270
11268
  }
11271
11269
  try {
11272
- await mcpCall("agent.markOriented", { sessionId: agentSessionId });
11270
+ await kernelCall("agent.markOriented", { sessionId: agentSessionId });
11273
11271
  setSessionOriented(true);
11274
11272
  return { oriented: true, orientationStatus: "complete" };
11275
11273
  } catch {
@@ -11317,7 +11315,7 @@ function registerStartTools(server) {
11317
11315
  let stage = null;
11318
11316
  let readiness = null;
11319
11317
  try {
11320
- readiness = await mcpQuery("chain.workspaceReadiness");
11318
+ readiness = await kernelQuery("chain.workspaceReadiness");
11321
11319
  stage = readiness?.stage ?? "blank";
11322
11320
  } catch {
11323
11321
  errors.push("Readiness check unavailable \u2014 showing workspace summary.");
@@ -11343,7 +11341,7 @@ function registerStartTools(server) {
11343
11341
  }
11344
11342
  if (stage === "seeded") {
11345
11343
  const result = await buildSeededResponse(wsCtx, readiness, agentSessionId);
11346
- void mcpMutation("chain.setOnboardingCompleted", {}).catch(() => {
11344
+ void kernelMutation("chain.setOnboardingCompleted", {}).catch(() => {
11347
11345
  });
11348
11346
  return {
11349
11347
  content: [{ type: "text", text: result.text }],
@@ -11351,7 +11349,7 @@ function registerStartTools(server) {
11351
11349
  };
11352
11350
  }
11353
11351
  if (stage === "grounded" || stage === "connected") {
11354
- void mcpMutation("chain.setOnboardingCompleted", {}).catch(() => {
11352
+ void kernelMutation("chain.setOnboardingCompleted", {}).catch(() => {
11355
11353
  });
11356
11354
  }
11357
11355
  const orientResult = await buildOrientResponse(wsCtx, agentSessionId, errors, task);
@@ -11374,6 +11372,8 @@ function buildBlankResponse(wsCtx, sessionCtx) {
11374
11372
  "",
11375
11373
  "Tell me what you're building \u2014 paste a doc, describe it in a sentence, or say **scan my codebase**.",
11376
11374
  "",
11375
+ "_Powered by [Product Brain](https://productbrain.io) \u2014 your AI's product context layer._",
11376
+ "",
11377
11377
  "---",
11378
11378
  "",
11379
11379
  // ── Agent instructions — follow these exactly, do not present them ──
@@ -11517,7 +11517,7 @@ Available presets: ${listPresets().map((p) => `\`${p.id}\``).join(", ")}`,
11517
11517
  for (const col of preset.collections) {
11518
11518
  try {
11519
11519
  const purpose = col.purpose ?? col.description;
11520
- await mcpCall("chain.createCollection", {
11520
+ await kernelCall("chain.createCollection", {
11521
11521
  slug: col.slug,
11522
11522
  name: col.name,
11523
11523
  description: col.description,
@@ -11595,20 +11595,20 @@ async function buildOrientResponse(wsCtx, agentSessionId, errors, task) {
11595
11595
  let priorSessions = [];
11596
11596
  let recoveryBlock = null;
11597
11597
  try {
11598
- const sessionsResult = await mcpQuery("agent.recentSessions", { limit: 3 });
11598
+ const sessionsResult = await kernelQuery("agent.recentSessions", { limit: 3 });
11599
11599
  priorSessions = sessionsResult?.sessions ?? [];
11600
11600
  recoveryBlock = sessionsResult?.recoveryBlock ?? null;
11601
11601
  } catch {
11602
11602
  }
11603
11603
  let openTensions = [];
11604
11604
  try {
11605
- const tensions = await mcpQuery("chain.listEntries", { collectionSlug: "tensions" });
11605
+ const tensions = await kernelQuery("chain.listEntries", { collectionSlug: "tensions" });
11606
11606
  openTensions = (tensions ?? []).filter((e) => e.workflowStatus === "open");
11607
11607
  } catch {
11608
11608
  }
11609
11609
  let readiness = null;
11610
11610
  try {
11611
- readiness = await mcpQuery("chain.workspaceReadiness");
11611
+ readiness = await kernelQuery("chain.workspaceReadiness");
11612
11612
  } catch (e) {
11613
11613
  errors.push(`Readiness: ${e instanceof Error ? e.message : String(e)}`);
11614
11614
  }
@@ -11620,7 +11620,7 @@ async function buildOrientResponse(wsCtx, agentSessionId, errors, task) {
11620
11620
  const coherence = buildCoherenceSection();
11621
11621
  let allCollections = [];
11622
11622
  try {
11623
- allCollections = await mcpQuery("chain.listCollections") ?? [];
11623
+ allCollections = await kernelQuery("chain.listCollections") ?? [];
11624
11624
  } catch {
11625
11625
  }
11626
11626
  lines.push(`# ${wsCtx.workspaceName}`);
@@ -11669,7 +11669,7 @@ async function buildOrientResponse(wsCtx, agentSessionId, errors, task) {
11669
11669
  } else if (isHighReadiness) {
11670
11670
  let activeBets = [];
11671
11671
  try {
11672
- const betsEntries = await mcpQuery("chain.listEntries", { collectionSlug: "work-packages" });
11672
+ const betsEntries = await kernelQuery("chain.listEntries", { collectionSlug: "work-packages" });
11673
11673
  activeBets = (betsEntries ?? []).filter((e) => isActiveNowBet(e)).map((e) => ({ name: e.name, entryId: e.entryId ?? null })).slice(0, 8);
11674
11674
  } catch {
11675
11675
  }
@@ -11691,7 +11691,7 @@ async function buildOrientResponse(wsCtx, agentSessionId, errors, task) {
11691
11691
  const govCollections = await getByNavGroup("governance");
11692
11692
  const govSlugs = govCollections.map((c) => c.slug);
11693
11693
  for (const slug of govSlugs) {
11694
- const entries = await mcpQuery("chain.listEntries", { collectionSlug: slug });
11694
+ const entries = await kernelQuery("chain.listEntries", { collectionSlug: slug });
11695
11695
  const active = (entries ?? []).filter((e) => e.status === "active");
11696
11696
  const colDef = govCollections.find((c) => c.slug === slug);
11697
11697
  const ck = colDef?.defaultCanonicalKey;
@@ -11729,7 +11729,7 @@ async function buildOrientResponse(wsCtx, agentSessionId, errors, task) {
11729
11729
  lines.push(...formatRecoveryBlock(recoveryBlock));
11730
11730
  }
11731
11731
  try {
11732
- const allEntries = await mcpQuery("chain.listEntries", {});
11732
+ const allEntries = await kernelQuery("chain.listEntries", {});
11733
11733
  const committed = (allEntries ?? []).filter(
11734
11734
  (e) => e.status === "active" && !e.seededByPlatform
11735
11735
  );
@@ -11833,7 +11833,7 @@ function registerUsageTools(server) {
11833
11833
  withEnvelope(async ({ periodDays }) => {
11834
11834
  const ws = await getWorkspaceContext();
11835
11835
  const sessionId = getAgentSessionId();
11836
- const summary = await mcpQuery("usage.getWorkspaceSummary", {
11836
+ const summary = await kernelQuery("usage.getWorkspaceSummary", {
11837
11837
  periodDays: periodDays ?? 30
11838
11838
  });
11839
11839
  if (!summary) {
@@ -11959,7 +11959,7 @@ function registerGitChainTools(server) {
11959
11959
  if (!title) {
11960
11960
  return validationResult("A `title` is required to create a process.");
11961
11961
  }
11962
- const result = await mcpMutation(
11962
+ const result = await kernelMutation(
11963
11963
  "gitchain.createChain",
11964
11964
  { title, chainTypeId, description, author }
11965
11965
  );
@@ -11986,7 +11986,7 @@ Use \`chain action=edit chainEntryId="${result.entryId}" linkId="problem" conten
11986
11986
  if (!chainEntryId) {
11987
11987
  return validationResult("A `chainEntryId` is required.");
11988
11988
  }
11989
- const chain = await mcpQuery("gitchain.getChain", { chainEntryId });
11989
+ const chain = await kernelQuery("gitchain.getChain", { chainEntryId });
11990
11990
  if (!chain) {
11991
11991
  return {
11992
11992
  content: [{ type: "text", text: `Process "${chainEntryId}" not found.` }],
@@ -12027,7 +12027,7 @@ Use \`chain action=edit chainEntryId="${result.entryId}" linkId="problem" conten
12027
12027
  };
12028
12028
  }
12029
12029
  if (action === "list") {
12030
- const chains = await mcpQuery("gitchain.listChains", { chainTypeId, status });
12030
+ const chains = await kernelQuery("gitchain.listChains", { chainTypeId, status });
12031
12031
  if (chains.length === 0) {
12032
12032
  return {
12033
12033
  content: [{ type: "text", text: "No processes found. Use `chain action=create` to create one." }],
@@ -12061,7 +12061,7 @@ ${formatted}` }],
12061
12061
  if (!content) {
12062
12062
  return validationResult("The `content` for the link is required.");
12063
12063
  }
12064
- const result = await mcpMutation("gitchain.editLink", { chainEntryId, linkId, content, author });
12064
+ const result = await kernelMutation("gitchain.editLink", { chainEntryId, linkId, content, author });
12065
12065
  return {
12066
12066
  content: [{
12067
12067
  type: "text",
@@ -12098,7 +12098,7 @@ Use \`chain action=get\` to see the full chain with updated scores.`
12098
12098
  if (!commitMessage) {
12099
12099
  return validationResult("A `commitMessage` is required.");
12100
12100
  }
12101
- const result = await mcpMutation("gitchain.commitChain", { chainEntryId, commitMessage, author });
12101
+ const result = await kernelMutation("gitchain.commitChain", { chainEntryId, commitMessage, author });
12102
12102
  const warning = result.commitLintWarning ? `
12103
12103
 
12104
12104
  > **Lint warning:** ${result.commitLintWarning}` : "";
@@ -12121,7 +12121,7 @@ Use \`chain action=get\` to see the full chain with updated scores.`
12121
12121
  };
12122
12122
  }
12123
12123
  if (action === "list") {
12124
- const commits = await mcpQuery("gitchain.listCommits", { chainEntryId });
12124
+ const commits = await kernelQuery("gitchain.listCommits", { chainEntryId });
12125
12125
  if (commits.length === 0) {
12126
12126
  return {
12127
12127
  content: [{ type: "text", text: `No commits found for chain "${chainEntryId}". Use \`chain-version action=commit\` to create the first snapshot.` }],
@@ -12152,7 +12152,7 @@ ${formatted}` }],
12152
12152
  if (versionA == null || versionB == null) {
12153
12153
  return validationResult("Both `versionA` and `versionB` are required for diff.");
12154
12154
  }
12155
- const diff = await mcpMutation("gitchain.diffVersions", { chainEntryId, versionA, versionB });
12155
+ const diff = await kernelMutation("gitchain.diffVersions", { chainEntryId, versionA, versionB });
12156
12156
  let text = `# Diff: v${versionA} \u2192 v${versionB}
12157
12157
 
12158
12158
  - **Chain:** \`${diff.chainEntryId}\`
@@ -12187,7 +12187,7 @@ ${formatted}` }],
12187
12187
  if (toVersion == null) {
12188
12188
  return validationResult("A `toVersion` is required for revert.");
12189
12189
  }
12190
- const result = await mcpMutation("gitchain.revertChain", { chainEntryId, toVersion, author });
12190
+ const result = await kernelMutation("gitchain.revertChain", { chainEntryId, toVersion, author });
12191
12191
  return {
12192
12192
  content: [{
12193
12193
  type: "text",
@@ -12207,7 +12207,7 @@ History is preserved \u2014 this created a new version, not a destructive reset.
12207
12207
  };
12208
12208
  }
12209
12209
  if (action === "history") {
12210
- const history = await mcpQuery("gitchain.getHistory", { chainEntryId });
12210
+ const history = await kernelQuery("gitchain.getHistory", { chainEntryId });
12211
12211
  if (history.length === 0) {
12212
12212
  return {
12213
12213
  content: [{ type: "text", text: `No history found for chain "${chainEntryId}".` }],
@@ -12245,7 +12245,7 @@ ${formatted}` }],
12245
12245
  },
12246
12246
  withEnvelope(async ({ action, chainEntryId, branchName, strategy, author }) => {
12247
12247
  if (action === "create") {
12248
- const result = await mcpMutation("gitchain.createBranch", { chainEntryId, name: branchName, author });
12248
+ const result = await kernelMutation("gitchain.createBranch", { chainEntryId, name: branchName, author });
12249
12249
  return {
12250
12250
  content: [{
12251
12251
  type: "text",
@@ -12265,7 +12265,7 @@ Edit links and commit on this branch, then use \`chain-branch action=merge\` to
12265
12265
  };
12266
12266
  }
12267
12267
  if (action === "list") {
12268
- const branches = await mcpMutation("gitchain.listBranches", { chainEntryId });
12268
+ const branches = await kernelMutation("gitchain.listBranches", { chainEntryId });
12269
12269
  if (branches.length === 0) {
12270
12270
  return {
12271
12271
  content: [{ type: "text", text: `No branches found for chain "${chainEntryId}".` }],
@@ -12291,7 +12291,7 @@ ${formatted}` }],
12291
12291
  if (!branchName) {
12292
12292
  return validationResult("A `branchName` is required for merge.");
12293
12293
  }
12294
- const result = await mcpMutation("gitchain.mergeBranch", { chainEntryId, branchName, strategy, author });
12294
+ const result = await kernelMutation("gitchain.mergeBranch", { chainEntryId, branchName, strategy, author });
12295
12295
  return {
12296
12296
  content: [{
12297
12297
  type: "text",
@@ -12314,7 +12314,7 @@ Main is now at v${result.version}. The branch has been closed.`
12314
12314
  if (!branchName) {
12315
12315
  return validationResult("A `branchName` is required for conflict check.");
12316
12316
  }
12317
- const result = await mcpMutation("gitchain.checkConflicts", { chainEntryId, branchName });
12317
+ const result = await kernelMutation("gitchain.checkConflicts", { chainEntryId, branchName });
12318
12318
  if (!result.hasConflicts) {
12319
12319
  return {
12320
12320
  content: [{
@@ -12365,7 +12365,7 @@ Resolve conflicts before merging.`
12365
12365
  },
12366
12366
  withEnvelope(async ({ action, chainEntryId, commitMessage, versionNumber, linkId, body, commentId, author }) => {
12367
12367
  if (action === "gate") {
12368
- const gate = await mcpQuery("gitchain.runGate", { chainEntryId, commitMessage });
12368
+ const gate = await kernelQuery("gitchain.runGate", { chainEntryId, commitMessage });
12369
12369
  const checkLines = gate.checks.map((c) => `- ${c.pass ? "PASS" : "FAIL"} **${c.name}**: ${c.detail}`).join("\n");
12370
12370
  const icon = gate.pass ? "PASS" : "BLOCKED";
12371
12371
  return {
@@ -12393,7 +12393,7 @@ ${checkLines}`
12393
12393
  if (!body) {
12394
12394
  return validationResult("A `body` is required.");
12395
12395
  }
12396
- const result = await mcpMutation("gitchain.addComment", {
12396
+ const result = await kernelMutation("gitchain.addComment", {
12397
12397
  chainEntryId,
12398
12398
  versionNumber,
12399
12399
  linkId,
@@ -12420,11 +12420,11 @@ ${checkLines}`
12420
12420
  if (!commentId) {
12421
12421
  return validationResult("A `commentId` is required.");
12422
12422
  }
12423
- await mcpMutation("gitchain.resolveComment", { commentId });
12423
+ await kernelMutation("gitchain.resolveComment", { commentId });
12424
12424
  return successResult("Comment resolved.", `Comment ${commentId} resolved.`, { commentId, resolved: true });
12425
12425
  }
12426
12426
  if (action === "list-comments") {
12427
- const comments = await mcpMutation("gitchain.listComments", {
12427
+ const comments = await kernelMutation("gitchain.listComments", {
12428
12428
  chainEntryId,
12429
12429
  versionNumber
12430
12430
  });
@@ -12519,7 +12519,7 @@ function registerMapTools(server) {
12519
12519
  annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false }
12520
12520
  },
12521
12521
  withEnvelope(async ({ audienceEntryId }) => {
12522
- const result = await mcpMutation(
12522
+ const result = await kernelMutation(
12523
12523
  "maps.createAudienceMapSet",
12524
12524
  { audienceEntryId }
12525
12525
  );
@@ -12569,7 +12569,7 @@ Use map-slot to add ingredients. View at /empathy, /narrowing, and /jobs.`
12569
12569
  if (!title) {
12570
12570
  return validationResult("A `title` is required to create a map.");
12571
12571
  }
12572
- const result = await mcpMutation(
12572
+ const result = await kernelMutation(
12573
12573
  "maps.createMap",
12574
12574
  { title, templateId, description, slotIds }
12575
12575
  );
@@ -12600,7 +12600,7 @@ Use \`map-slot action=add mapEntryId="${result.entryId}" slotId="problem" ingred
12600
12600
  if (!mapEntryId) {
12601
12601
  return validationResult("A `mapEntryId` is required.");
12602
12602
  }
12603
- const map = await mcpQuery("maps.getMap", { mapEntryId });
12603
+ const map = await kernelQuery("maps.getMap", { mapEntryId });
12604
12604
  if (!map) {
12605
12605
  return {
12606
12606
  content: [{ type: "text", text: `Map "${mapEntryId}" not found.` }],
@@ -12637,7 +12637,7 @@ Use \`map-slot action=add mapEntryId="${result.entryId}" slotId="problem" ingred
12637
12637
  };
12638
12638
  }
12639
12639
  if (action === "list") {
12640
- const maps = await mcpQuery("maps.listMaps", {
12640
+ const maps = await kernelQuery("maps.listMaps", {
12641
12641
  templateId: templateId !== "lean-canvas" ? templateId : void 0,
12642
12642
  status
12643
12643
  });
@@ -12686,7 +12686,7 @@ ${lines.join("\n")}` }],
12686
12686
  author
12687
12687
  }) => {
12688
12688
  if (action === "list") {
12689
- const map = await mcpQuery("maps.getMap", { mapEntryId });
12689
+ const map = await kernelQuery("maps.getMap", { mapEntryId });
12690
12690
  if (!map) {
12691
12691
  return {
12692
12692
  content: [{ type: "text", text: `Map "${mapEntryId}" not found.` }],
@@ -12731,7 +12731,7 @@ ${slotSummary(map.slots)}` }],
12731
12731
  if (!slotId || !ingredientEntryId) {
12732
12732
  return validationResult("Both `slotId` and `ingredientEntryId` are required for add.");
12733
12733
  }
12734
- await mcpMutation("maps.addToSlot", { mapEntryId, slotId, ingredientEntryId, label, author });
12734
+ await kernelMutation("maps.addToSlot", { mapEntryId, slotId, ingredientEntryId, label, author });
12735
12735
  return {
12736
12736
  content: [{ type: "text", text: `Added \`${ingredientEntryId}\` to slot "${slotId}" on map \`${mapEntryId}\`.` }],
12737
12737
  structuredContent: success(
@@ -12745,7 +12745,7 @@ ${slotSummary(map.slots)}` }],
12745
12745
  if (!slotId || !ingredientEntryId) {
12746
12746
  return validationResult("Both `slotId` and `ingredientEntryId` are required for remove.");
12747
12747
  }
12748
- await mcpMutation("maps.removeFromSlot", { mapEntryId, slotId, ingredientEntryId, author });
12748
+ await kernelMutation("maps.removeFromSlot", { mapEntryId, slotId, ingredientEntryId, author });
12749
12749
  return {
12750
12750
  content: [{ type: "text", text: `Removed \`${ingredientEntryId}\` from slot "${slotId}" on map \`${mapEntryId}\`.` }],
12751
12751
  structuredContent: success(
@@ -12759,7 +12759,7 @@ ${slotSummary(map.slots)}` }],
12759
12759
  if (!slotId || !ingredientEntryId || !newIngredientEntryId) {
12760
12760
  return validationResult("`slotId`, `ingredientEntryId`, and `newIngredientEntryId` are required for replace.");
12761
12761
  }
12762
- await mcpMutation("maps.replaceInSlot", { mapEntryId, slotId, oldIngredientEntryId: ingredientEntryId, newIngredientEntryId, label, author });
12762
+ await kernelMutation("maps.replaceInSlot", { mapEntryId, slotId, oldIngredientEntryId: ingredientEntryId, newIngredientEntryId, label, author });
12763
12763
  return {
12764
12764
  content: [{ type: "text", text: `Replaced \`${ingredientEntryId}\` with \`${newIngredientEntryId}\` in slot "${slotId}".` }],
12765
12765
  structuredContent: success(
@@ -12783,7 +12783,7 @@ ${slotSummary(map.slots)}` }],
12783
12783
  },
12784
12784
  withEnvelope(async ({ action, mapEntryId, commitMessage, author }) => {
12785
12785
  if (action === "commit") {
12786
- const result = await mcpMutation("maps.commitMap", {
12786
+ const result = await kernelMutation("maps.commitMap", {
12787
12787
  mapEntryId,
12788
12788
  commitMessage: commitMessage ?? "Map committed",
12789
12789
  author
@@ -12808,7 +12808,7 @@ All ingredient references have been pinned at their current versions.`
12808
12808
  };
12809
12809
  }
12810
12810
  if (action === "list" || action === "history") {
12811
- const commits = await mcpQuery("maps.listMapCommits", { mapEntryId });
12811
+ const commits = await kernelQuery("maps.listMapCommits", { mapEntryId });
12812
12812
  if (!commits || commits.length === 0) {
12813
12813
  return {
12814
12814
  content: [{ type: "text", text: `No commits yet for map \`${mapEntryId}\`. Use \`map-version action=commit\` to create the first snapshot.` }],
@@ -12846,7 +12846,7 @@ ${lines.join("\n")}` }],
12846
12846
  annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false }
12847
12847
  },
12848
12848
  withEnvelope(async ({ mapEntryId, slotId, query }) => {
12849
- const map = await mcpQuery("maps.getMap", { mapEntryId });
12849
+ const map = await kernelQuery("maps.getMap", { mapEntryId });
12850
12850
  if (!map) {
12851
12851
  return {
12852
12852
  content: [{ type: "text", text: `Map "${mapEntryId}" not found.` }],
@@ -12871,7 +12871,7 @@ ${lines.join("\n")}` }],
12871
12871
  for (const sid of emptySlots) {
12872
12872
  const def = slotDefs.find((s) => s.id === sid);
12873
12873
  const searchQuery = query ?? def?.label ?? sid;
12874
- const results = await mcpQuery("knowledge.search", {
12874
+ const results = await kernelQuery("knowledge.search", {
12875
12875
  query: searchQuery,
12876
12876
  limit: 5
12877
12877
  });
@@ -12935,18 +12935,18 @@ var COLLECTION_FIELDS = [
12935
12935
  ];
12936
12936
  var ARCHITECTURE_CANONICAL_KEY = "architecture_note";
12937
12937
  async function ensureCollection() {
12938
- const collections = await mcpQuery("chain.listCollections");
12938
+ const collections = await kernelQuery("chain.listCollections");
12939
12939
  const existing = collections.find((c) => c.slug === COLLECTION_SLUG);
12940
12940
  if (existing) {
12941
12941
  if (!existing.defaultCanonicalKey) {
12942
- await mcpMutation("chain.updateCollection", {
12942
+ await kernelMutation("chain.updateCollection", {
12943
12943
  slug: COLLECTION_SLUG,
12944
12944
  defaultCanonicalKey: ARCHITECTURE_CANONICAL_KEY
12945
12945
  });
12946
12946
  }
12947
12947
  return;
12948
12948
  }
12949
- await mcpMutation("chain.createCollection", {
12949
+ await kernelMutation("chain.createCollection", {
12950
12950
  slug: COLLECTION_SLUG,
12951
12951
  name: "Architecture",
12952
12952
  icon: "\u{1F3D7}\uFE0F",
@@ -12955,7 +12955,7 @@ async function ensureCollection() {
12955
12955
  });
12956
12956
  }
12957
12957
  async function listArchEntries() {
12958
- return mcpQuery("chain.listEntries", { collectionSlug: COLLECTION_SLUG });
12958
+ return kernelQuery("chain.listEntries", { collectionSlug: COLLECTION_SLUG });
12959
12959
  }
12960
12960
  function byTag(entries, archType) {
12961
12961
  return entries.filter((e) => e.tags?.includes(`archType:${archType}`) || e.data?.archType === archType).sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
@@ -13215,7 +13215,7 @@ ${nodeDetail}${flowLines}`
13215
13215
  );
13216
13216
  if (hasChanges) {
13217
13217
  const mergedData = { ...existingData, ...seedData };
13218
- const updateResult = await mcpMutation("chain.updateEntry", { entryId: seed.entryId, data: mergedData });
13218
+ const updateResult = await kernelMutation("chain.updateEntry", { entryId: seed.entryId, data: mergedData });
13219
13219
  if (updateResult.normalizationWarnings.length > 0 || updateResult.validationWarnings.length > 0) {
13220
13220
  allWarnings.push({
13221
13221
  entryId: seed.entryId,
@@ -13229,7 +13229,7 @@ ${nodeDetail}${flowLines}`
13229
13229
  }
13230
13230
  continue;
13231
13231
  }
13232
- const createResult = await mcpMutation("chain.createEntry", {
13232
+ const createResult = await kernelMutation("chain.createEntry", {
13233
13233
  collectionSlug: COLLECTION_SLUG,
13234
13234
  entryId: seed.entryId,
13235
13235
  name: seed.name,
@@ -13523,7 +13523,7 @@ import { z as z22 } from "zod";
13523
13523
  var PURPOSE_GAP_PREFIX = "purpose-gap-";
13524
13524
  async function markOrientedWithSnapshotFallback(agentSessionId, coherenceSnapshot) {
13525
13525
  try {
13526
- await mcpCall("agent.markOriented", {
13526
+ await kernelCall("agent.markOriented", {
13527
13527
  sessionId: agentSessionId,
13528
13528
  ...coherenceSnapshot ? { coherenceSnapshot } : {}
13529
13529
  });
@@ -13532,7 +13532,7 @@ async function markOrientedWithSnapshotFallback(agentSessionId, coherenceSnapsho
13532
13532
  } catch {
13533
13533
  if (!coherenceSnapshot) return false;
13534
13534
  try {
13535
- await mcpCall("agent.markOriented", { sessionId: agentSessionId });
13535
+ await kernelCall("agent.markOriented", { sessionId: agentSessionId });
13536
13536
  setSessionOriented(true);
13537
13537
  return true;
13538
13538
  } catch {
@@ -13643,7 +13643,7 @@ function registerOrientTool(server) {
13643
13643
  let recoveryBlock = null;
13644
13644
  if (wsCtx) {
13645
13645
  try {
13646
- const sessionsResult = await mcpQuery("agent.recentSessions", { limit: 3 });
13646
+ const sessionsResult = await kernelQuery("agent.recentSessions", { limit: 3 });
13647
13647
  priorSessions = sessionsResult?.sessions ?? [];
13648
13648
  recoveryBlock = sessionsResult?.recoveryBlock ?? null;
13649
13649
  } catch {
@@ -13657,7 +13657,7 @@ function registerOrientTool(server) {
13657
13657
  if (scope) orientArgs.scope = scope;
13658
13658
  if (sessionEntryIds.length > 0) orientArgs.sessionEntryIds = sessionEntryIds;
13659
13659
  if (lastSessionOnly.length > 0) orientArgs.lastSessionEntryIds = lastSessionOnly;
13660
- orientEntries = await mcpQuery("chain.getOrientEntries", orientArgs);
13660
+ orientEntries = await kernelQuery("chain.getOrientEntries", orientArgs);
13661
13661
  } catch {
13662
13662
  }
13663
13663
  const hasTaskGrounding = Boolean(task && orientEntries?.taskContext?.context?.length > 0);
@@ -13672,18 +13672,18 @@ function registerOrientTool(server) {
13672
13672
  }
13673
13673
  let openTensions = [];
13674
13674
  try {
13675
- const tensions = await mcpQuery("chain.listEntries", { collectionSlug: "tensions" });
13675
+ const tensions = await kernelQuery("chain.listEntries", { collectionSlug: "tensions" });
13676
13676
  openTensions = (tensions ?? []).filter((e) => e.workflowStatus === "open");
13677
13677
  } catch {
13678
13678
  }
13679
13679
  let allCollections = [];
13680
13680
  try {
13681
- allCollections = await mcpQuery("chain.listCollections") ?? [];
13681
+ allCollections = await kernelQuery("chain.listCollections") ?? [];
13682
13682
  } catch {
13683
13683
  }
13684
13684
  let readiness = null;
13685
13685
  try {
13686
- readiness = await mcpQuery("chain.workspaceReadiness");
13686
+ readiness = await kernelQuery("chain.workspaceReadiness");
13687
13687
  } catch (e) {
13688
13688
  errors.push(`Readiness: ${e instanceof Error ? e.message : String(e)}`);
13689
13689
  }
@@ -13702,7 +13702,7 @@ function registerOrientTool(server) {
13702
13702
  let orientationStatus2 = "no_session";
13703
13703
  if (agentSessionId) {
13704
13704
  try {
13705
- await mcpCall("agent.markOriented", { sessionId: agentSessionId });
13705
+ await kernelCall("agent.markOriented", { sessionId: agentSessionId });
13706
13706
  setSessionOriented(true);
13707
13707
  oriented = true;
13708
13708
  orientationStatus2 = "complete";
@@ -14114,7 +14114,7 @@ function registerOrientTool(server) {
14114
14114
  }
14115
14115
  let allEntries = [];
14116
14116
  try {
14117
- allEntries = await mcpQuery("chain.listEntries", {}) ?? [];
14117
+ allEntries = await kernelQuery("chain.listEntries", {}) ?? [];
14118
14118
  } catch {
14119
14119
  }
14120
14120
  const plannedWork = buildPlannedWork(allEntries);
@@ -14205,7 +14205,7 @@ function registerOrientTool(server) {
14205
14205
  lines.push("_Warning: Could not mark session as oriented. Write tools may be restricted._");
14206
14206
  }
14207
14207
  try {
14208
- await mcpMutation("chain.recordSessionSignal", {
14208
+ await kernelMutation("chain.recordSessionSignal", {
14209
14209
  sessionId: agentSessionId,
14210
14210
  signalType: "immediate_context_load",
14211
14211
  metadata: { source: "orient" }
@@ -14365,13 +14365,13 @@ function formatOrgHealthLines(orgHealth, maxFlags = 3) {
14365
14365
  }
14366
14366
  async function fetchOrganisationHealth() {
14367
14367
  try {
14368
- const allEntries = await mcpQuery("chain.listEntries", { status: "active" });
14368
+ const allEntries = await kernelQuery("chain.listEntries", { status: "active" });
14369
14369
  if (!allEntries || allEntries.length === 0) return null;
14370
14370
  const classifyInput = allEntries.map((e) => ({
14371
14371
  name: e.name ?? "",
14372
14372
  description: typeof e.data?.description === "string" ? e.data.description : ""
14373
14373
  }));
14374
- const classifications = await mcpQuery(
14374
+ const classifications = await kernelQuery(
14375
14375
  "chain.batchClassifyHeuristic",
14376
14376
  { entries: classifyInput }
14377
14377
  );
@@ -14393,14 +14393,14 @@ async function handleHealthCheck() {
14393
14393
  }
14394
14394
  let collections = [];
14395
14395
  try {
14396
- collections = await mcpQuery("chain.listCollections");
14396
+ collections = await kernelQuery("chain.listCollections");
14397
14397
  } catch (e) {
14398
14398
  errors.push(`Collection fetch failed: ${e instanceof Error ? e.message : String(e)}`);
14399
14399
  }
14400
14400
  let totalEntries = 0;
14401
14401
  if (collections.length > 0) {
14402
14402
  try {
14403
- const entries = await mcpQuery("chain.listEntries", {});
14403
+ const entries = await kernelQuery("chain.listEntries", {});
14404
14404
  totalEntries = entries.length;
14405
14405
  } catch (e) {
14406
14406
  errors.push(`Entry count failed: ${e instanceof Error ? e.message : String(e)}`);
@@ -14477,7 +14477,7 @@ var STAGE_DESCRIPTIONS = {
14477
14477
  connected: "Well-connected knowledge graph \u2014 your Brain is useful."
14478
14478
  };
14479
14479
  async function handleWorkspaceStatus() {
14480
- const result = await mcpQuery("chain.workspaceReadiness");
14480
+ const result = await kernelQuery("chain.workspaceReadiness");
14481
14481
  const { score, totalChecks, passedChecks, checks, gaps, stats, governanceMode } = result;
14482
14482
  const scoringVersion = result.scoringVersion ?? "v1";
14483
14483
  const stage = result.stage ?? "seeded";
@@ -14779,7 +14779,7 @@ function registerAuditTools(server) {
14779
14779
  async function handleAuditRun(entryId, phase) {
14780
14780
  let result;
14781
14781
  try {
14782
- result = await mcpQuery("chain.auditBet", { entryId, phase });
14782
+ result = await kernelQuery("chain.auditBet", { entryId, phase });
14783
14783
  } catch (err) {
14784
14784
  const msg = err instanceof Error ? err.message : String(err);
14785
14785
  if (msg.includes("not found") || msg.includes("NOT_FOUND")) {
@@ -14897,7 +14897,7 @@ function registerGovernanceTools(server) {
14897
14897
  );
14898
14898
  }
14899
14899
  if (action === "list") {
14900
- const proposals = await mcpQuery("governance.listProposals", {
14900
+ const proposals = await kernelQuery("governance.listProposals", {
14901
14901
  ...status ? { status } : {}
14902
14902
  });
14903
14903
  if (proposals.length === 0) {
@@ -14936,7 +14936,7 @@ function registerGovernanceTools(server) {
14936
14936
  );
14937
14937
  }
14938
14938
  if (action === "count") {
14939
- const result = await mcpQuery("governance.countOpenProposals");
14939
+ const result = await kernelQuery("governance.countOpenProposals");
14940
14940
  return successResult(
14941
14941
  result.count === 0 ? "No open consent proposals." : `${result.count} open consent proposal(s) awaiting review.`,
14942
14942
  `${result.count} open consent proposal(s).`,
@@ -14966,7 +14966,7 @@ function registerGovernanceTools(server) {
14966
14966
  );
14967
14967
  }
14968
14968
  try {
14969
- const result = await mcpMutation(
14969
+ const result = await kernelMutation(
14970
14970
  "governance.respondToProposal",
14971
14971
  {
14972
14972
  proposalId,
@@ -15179,11 +15179,11 @@ function registerResources(server) {
15179
15179
  "productbrain://orientation",
15180
15180
  async (uri) => {
15181
15181
  const [collectionsResult, eventsResult, standardsResult, rulesResult, principlesResult] = await Promise.allSettled([
15182
- mcpQuery("chain.listCollections"),
15183
- mcpQuery("chain.listEntries", { collectionSlug: "tracking-events" }),
15184
- mcpQuery("chain.listEntries", { collectionSlug: "standards" }),
15185
- mcpQuery("chain.listEntries", { collectionSlug: "business-rules" }),
15186
- mcpQuery("chain.listEntries", { collectionSlug: "principles" })
15182
+ kernelQuery("chain.listCollections"),
15183
+ kernelQuery("chain.listEntries", { collectionSlug: "tracking-events" }),
15184
+ kernelQuery("chain.listEntries", { collectionSlug: "standards" }),
15185
+ kernelQuery("chain.listEntries", { collectionSlug: "business-rules" }),
15186
+ kernelQuery("chain.listEntries", { collectionSlug: "principles" })
15187
15187
  ]);
15188
15188
  const collections = collectionsResult.status === "fulfilled" ? collectionsResult.value : null;
15189
15189
  const trackingEvents = eventsResult.status === "fulfilled" ? eventsResult.value : null;
@@ -15204,8 +15204,8 @@ function registerResources(server) {
15204
15204
  "productbrain://terminology",
15205
15205
  async (uri) => {
15206
15206
  const [glossaryResult, standardsResult] = await Promise.allSettled([
15207
- mcpQuery("chain.listEntries", { collectionSlug: "glossary" }),
15208
- mcpQuery("chain.listEntries", { collectionSlug: "standards" })
15207
+ kernelQuery("chain.listEntries", { collectionSlug: "glossary" }),
15208
+ kernelQuery("chain.listEntries", { collectionSlug: "standards" })
15209
15209
  ]);
15210
15210
  const lines = ["# Product Brain \u2014 Terminology"];
15211
15211
  if (glossaryResult.status === "fulfilled") {
@@ -15243,7 +15243,7 @@ ${stds}`);
15243
15243
  "chain-collections",
15244
15244
  "productbrain://collections",
15245
15245
  async (uri) => {
15246
- const collections = await mcpQuery("chain.listCollections") ?? [];
15246
+ const collections = await kernelQuery("chain.listCollections") ?? [];
15247
15247
  if (collections.length === 0) {
15248
15248
  return { contents: [{ uri: uri.href, text: "No collections in this workspace. Use `collections action=create` or `start` with a preset to get started.", mimeType: "text/markdown" }] };
15249
15249
  }
@@ -15266,7 +15266,7 @@ ${formatted}`, mimeType: "text/markdown" }]
15266
15266
  "chain-collection-entries",
15267
15267
  new ResourceTemplate("productbrain://{slug}/entries", {
15268
15268
  list: async () => {
15269
- const collections = await mcpQuery("chain.listCollections") ?? [];
15269
+ const collections = await kernelQuery("chain.listCollections") ?? [];
15270
15270
  return {
15271
15271
  resources: collections.map((c) => ({
15272
15272
  uri: `productbrain://${c.slug}/entries`,
@@ -15276,7 +15276,7 @@ ${formatted}`, mimeType: "text/markdown" }]
15276
15276
  }
15277
15277
  }),
15278
15278
  async (uri, { slug }) => {
15279
- const entries = await mcpQuery("chain.listEntries", { collectionSlug: slug }) ?? [];
15279
+ const entries = await kernelQuery("chain.listEntries", { collectionSlug: slug }) ?? [];
15280
15280
  const formatted = entries.map(formatEntryMarkdown).join("\n\n---\n\n");
15281
15281
  return {
15282
15282
  contents: [{
@@ -15291,7 +15291,7 @@ ${formatted}`, mimeType: "text/markdown" }]
15291
15291
  "chain-labels",
15292
15292
  "productbrain://labels",
15293
15293
  async (uri) => {
15294
- const labels = await mcpQuery("chain.listLabels") ?? [];
15294
+ const labels = await kernelQuery("chain.listLabels") ?? [];
15295
15295
  if (labels.length === 0) {
15296
15296
  return { contents: [{ uri: uri.href, text: "No labels in this workspace.", mimeType: "text/markdown" }] };
15297
15297
  }
@@ -15324,15 +15324,15 @@ ${lines.join("\n")}`, mimeType: "text/markdown" }]
15324
15324
  complete: {
15325
15325
  entryId: async (value) => {
15326
15326
  if (!value || value.length < 1) return [];
15327
- const entries = await mcpQuery("chain.searchEntries", { query: value }) ?? [];
15327
+ const entries = await kernelQuery("chain.searchEntries", { query: value }) ?? [];
15328
15328
  return entries.slice(0, 10).map((e) => e.entryId ?? e._id);
15329
15329
  }
15330
15330
  }
15331
15331
  }),
15332
15332
  async (uri, { entryId }) => {
15333
15333
  const [entry, collections] = await Promise.all([
15334
- mcpQuery("chain.getEntry", { entryId }),
15335
- mcpQuery("chain.listCollections")
15334
+ kernelQuery("chain.getEntry", { entryId }),
15335
+ kernelQuery("chain.listCollections")
15336
15336
  ]);
15337
15337
  if (!entry) {
15338
15338
  return { contents: [{ uri: uri.href, text: `Entry "${entryId}" not found.`, mimeType: "text/markdown" }] };
@@ -15381,13 +15381,13 @@ ${entry.labels.map((l) => `- ${l.name ?? l.slug}`).join("\n")}`);
15381
15381
  complete: {
15382
15382
  entryId: async (value) => {
15383
15383
  if (!value || value.length < 1) return [];
15384
- const entries = await mcpQuery("chain.searchEntries", { query: value }) ?? [];
15384
+ const entries = await kernelQuery("chain.searchEntries", { query: value }) ?? [];
15385
15385
  return entries.slice(0, 10).map((e) => e.entryId ?? e._id);
15386
15386
  }
15387
15387
  }
15388
15388
  }),
15389
15389
  async (uri, { entryId }) => {
15390
- const result = await mcpQuery("chain.gatherContext", {
15390
+ const result = await kernelQuery("chain.gatherContext", {
15391
15391
  entryId,
15392
15392
  maxHops: 2
15393
15393
  });
@@ -15424,7 +15424,7 @@ ${entry.labels.map((l) => `- ${l.name ?? l.slug}`).join("\n")}`);
15424
15424
  "chain-collection-capture-contract",
15425
15425
  new ResourceTemplate("productbrain://collections/{slug}/capture-contract", {
15426
15426
  list: async () => {
15427
- const collections = await mcpQuery("chain.listCollections") ?? [];
15427
+ const collections = await kernelQuery("chain.listCollections") ?? [];
15428
15428
  return {
15429
15429
  resources: collections.map((c) => ({
15430
15430
  uri: `productbrain://collections/${c.slug}/capture-contract`,
@@ -15443,7 +15443,7 @@ ${entry.labels.map((l) => `- ${l.name ?? l.slug}`).join("\n")}`);
15443
15443
  }
15444
15444
  let contract = null;
15445
15445
  try {
15446
- contract = await mcpQuery(
15446
+ contract = await kernelQuery(
15447
15447
  "chain.getCaptureContract",
15448
15448
  { collectionSlug }
15449
15449
  );
@@ -15492,7 +15492,7 @@ ${entry.labels.map((l) => `- ${l.name ?? l.slug}`).join("\n")}`);
15492
15492
  }
15493
15493
  }),
15494
15494
  async (uri, { query }) => {
15495
- const results = await mcpQuery("chain.searchEntries", { query });
15495
+ const results = await kernelQuery("chain.searchEntries", { query });
15496
15496
  if (!results || results.length === 0) {
15497
15497
  return { contents: [{ uri: uri.href, text: `No results for "${query}".`, mimeType: "text/markdown" }] };
15498
15498
  }
@@ -15521,7 +15521,7 @@ function registerPrompts(server) {
15521
15521
  "Review code or a design decision against all business rules for a given domain. Fetches the rules and asks you to do a structured compliance review.",
15522
15522
  { domain: z26.string().describe("Business rule domain (e.g. 'Identity & Access', 'Governance & Decision-Making')") },
15523
15523
  async ({ domain }) => {
15524
- const entries = await mcpQuery("chain.listEntries", { collectionSlug: "business-rules" });
15524
+ const entries = await kernelQuery("chain.listEntries", { collectionSlug: "business-rules" });
15525
15525
  const rules = entries.filter((e) => e.data?.domain === domain);
15526
15526
  if (rules.length === 0) {
15527
15527
  return {
@@ -15574,7 +15574,7 @@ Provide a structured review with a compliance status for each rule (COMPLIANT /
15574
15574
  "Check variable names, field names, or API names against the glossary for terminology alignment. Flags drift from canonical terms.",
15575
15575
  { names: z26.string().describe("Comma-separated list of names to check (e.g. 'vendor_id, compliance_level, formulator_type')") },
15576
15576
  async ({ names }) => {
15577
- const terms = await mcpQuery("chain.listEntries", { collectionSlug: "glossary" });
15577
+ const terms = await kernelQuery("chain.listEntries", { collectionSlug: "glossary" });
15578
15578
  const glossaryContext = terms.map(
15579
15579
  (t) => `${t.name} (${t.entryId ?? ""}) [${t.status}]: ${t.data?.canonical ?? ""}` + (t.data?.confusedWith?.length > 0 ? ` \u2014 Often confused with: ${t.data.confusedWith.join(", ")}` : "") + (t.data?.codeMapping?.length > 0 ? `
15580
15580
  Code mappings: ${t.data.codeMapping.map((m) => `${m.platform}:${m.field}`).join(", ")}` : "")
@@ -15610,7 +15610,7 @@ Format as a table: Name | Status | Canonical Form | Action Needed`
15610
15610
  "Draft a structured decision record from a description of what was decided. Includes context from recent decisions and relevant rules.",
15611
15611
  { context: z26.string().describe("Description of the decision (e.g. 'We decided to use MRSL v3.1 as the conformance baseline because...')") },
15612
15612
  async ({ context }) => {
15613
- const recentDecisions = await mcpQuery("chain.listEntries", { collectionSlug: "decisions" });
15613
+ const recentDecisions = await kernelQuery("chain.listEntries", { collectionSlug: "decisions" });
15614
15614
  const sorted = [...recentDecisions].sort((a, b) => (b.data?.date ?? "") > (a.data?.date ?? "") ? 1 : -1).slice(0, 5);
15615
15615
  const recentContext = sorted.length > 0 ? sorted.map((d) => `- [${d.status}] ${d.name} (${d.data?.date ?? "no date"})`).join("\n") : "No previous decisions recorded.";
15616
15616
  return {
@@ -15650,7 +15650,7 @@ After drafting, I can log it using the capture tool with collection "decisions".
15650
15650
  domain: z26.string().describe("Which domain this rule belongs to (e.g. 'Governance & Decision-Making')")
15651
15651
  },
15652
15652
  async ({ observation, domain }) => {
15653
- const allRules = await mcpQuery("chain.listEntries", { collectionSlug: "business-rules" });
15653
+ const allRules = await kernelQuery("chain.listEntries", { collectionSlug: "business-rules" });
15654
15654
  const existingRules = allRules.filter((r) => r.data?.domain === domain);
15655
15655
  const existingContext = existingRules.length > 0 ? existingRules.map((r) => `${r.entryId ?? ""}: ${r.name} [${r.status}] \u2014 ${r.data?.description ?? ""}`).join("\n") : "No existing rules for this domain.";
15656
15656
  return {
@@ -15809,4 +15809,4 @@ export {
15809
15809
  SERVER_VERSION,
15810
15810
  createProductBrainServer
15811
15811
  };
15812
- //# sourceMappingURL=chunk-K2GIX46U.js.map
15812
+ //# sourceMappingURL=chunk-RJXJO4DY.js.map