@productbrain/mcp 0.0.1-beta.11500 → 0.0.1-beta.11515

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.
@@ -35,11 +35,11 @@ import {
35
35
  runWithToolContext,
36
36
  setSessionOriented,
37
37
  startAgentSession
38
- } from "./chunk-3STAPRQ3.js";
38
+ } from "./chunk-PTRT75UR.js";
39
39
 
40
40
  // src/server.ts
41
41
  import { McpServer as McpServer2 } from "@modelcontextprotocol/sdk/server/mcp.js";
42
- import { z as z36 } from "zod/v3";
42
+ import { z as z35 } from "zod/v3";
43
43
 
44
44
  // src/lib/mcpGatewayClientMessages.ts
45
45
  function agentSessionNotActiveMessage(status2) {
@@ -175,7 +175,7 @@ function thinWrapper(handler) {
175
175
  return {
176
176
  content: [{
177
177
  type: "text",
178
- text: classified.fn ? `[${classified.code}/${classified.fn}] ${classified.message}` : `[${classified.code}] ${classified.message}`
178
+ text: `[${classified.code}] ${classified.message}`
179
179
  }],
180
180
  structuredContent: envelope,
181
181
  isError: true
@@ -498,15 +498,14 @@ var TOOL_NAME_MIGRATIONS = /* @__PURE__ */ new Map([
498
498
  // (WP-687 S2 retired the map tool and its 4 migration rows below.)
499
499
  // Multi-action retired tools map to the FULL action menu (pipe / wildcard
500
500
  // form), never a single default action: the coach only matches the retired
501
- // NAME, so historical text like `facilitate action=commit-constellation`
502
- // would otherwise be annotated with the wrong action (e.g. → resume) and
503
- // send the agent down the wrong path (PR #362 review finding).
501
+ // NAME, so historical text like `facilitate action=resume` maps to the
502
+ // matching action (PR #362 review finding).
504
503
  ["update-entry", 'entries action="update"'],
505
504
  ["get-history", 'context action="history"'],
506
- ["commit-entry", 'entries action="commit"'],
505
+ ["commit-entry", 'entries action="accept"'],
507
506
  ["move-entry", 'entries action="move"'],
508
- ["session-wrapup", 'session action="wrapup-review|wrapup-commit" (review \u2192 wrapup-review, commit-all \u2192 wrapup-commit)'],
509
- ["facilitate", 'session action="resume|commit-constellation" (same action names)'],
507
+ ["session-wrapup", 'session action="wrapup-review", then entries action="accept" per draft'],
508
+ ["facilitate", 'session action="resume", then entries action="accept" per entry'],
510
509
  ["graph", 'context action="find" (same action name)'],
511
510
  ["documents", 'context action="last-verified-brief"'],
512
511
  ["labels", 'collections action="label-*" (list/create/update/delete/apply/remove \u2192 label-<same>)'],
@@ -1055,7 +1054,7 @@ function registerSmartCaptureTools(server) {
1055
1054
  "capture",
1056
1055
  {
1057
1056
  title: "Capture",
1058
- description: "The tool for creating a single knowledge entry. Creates an entry and returns a quality scorecard \u2014 all in one call. Provide a name and description; `collection` is optional \u2014 the kernel classifies when omitted and files a low-confidence pick as a draft with one line saying so. An agent capturing several atoms from one text calls this once per atom.\n\n**Explicit data:** When you know the schema, pass `data: { field: value }` to set fields directly. A value in `data` is kept as sent; `description` is the entry's text and fills the collection's prose field only when `data` leaves it empty (the same rule as `pb capture`); when `data` carries the prose field, `description` and `context` are used for classification and judging only and are not stored. Governance entries also require a top-level `why`.\n\n**Compound capture:** Pass `links` to create relations in the same call; a capture writes no other relations. A capture lands as a `draft` to accept with `entries action=commit`; a question is born open. The reply names possible duplicates; only an exact name in the collection is refused.",
1057
+ description: "The tool for creating a single knowledge entry. Creates an entry and returns a quality scorecard \u2014 all in one call. Provide a name and description; `collection` is optional \u2014 the kernel classifies when omitted and files a low-confidence pick as a draft with one line saying so. An agent capturing several atoms from one text calls this once per atom.\n\n**Explicit data:** When you know the schema, pass `data: { field: value }` to set fields directly. A value in `data` is kept as sent; `description` is the entry's text and fills the collection's prose field only when `data` leaves it empty (the same rule as `pb capture`); when `data` carries the prose field, `description` and `context` are used for classification and judging only and are not stored. Governance entries also require a top-level `why`.\n\n**Compound capture:** Pass `links` to create relations in the same call; a capture writes no other relations. A capture lands as a `draft` to accept with `entries action=accept`; a question is born open. The reply names possible duplicates; only an exact name in the collection is refused.",
1059
1058
  inputSchema: captureCompoundSchema,
1060
1059
  annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false }
1061
1060
  },
@@ -1278,7 +1277,7 @@ Use \`context action=get\` to inspect the existing entry, or \`entries action=up
1278
1277
  } else if (spineFloor) {
1279
1278
  const { relationType: relationType2, parentKind, exempt, linkWritten } = spineFloor, id = finalEntryId, to = `<${parentKind.toUpperCase().replace(/_/g, "-")}-ID>`;
1280
1279
  lines.push("", "## Saved as draft", `**${name}** ${exempt ? SPINE_FLOOR_EXEMPT_SENTENCE : `kept as a draft. ${rungLine(parentKind)}`}`);
1281
- lines.push(exempt || linkWritten ? `Next: \`entries action=commit entryId="${id}"\`.` : `Next: \`relations action=create from="${id}" type="${relationType2}" to="${to}"\`.`);
1280
+ lines.push(exempt || linkWritten ? `Next: \`entries action=accept entryId="${id}"\`.` : `Next: \`relations action=create from="${id}" type="${relationType2}" to="${to}"\`.`);
1282
1281
  }
1283
1282
  if (groundingCaveat) lines.push("", groundingCaveat);
1284
1283
  const named = groundingReport.duplicates.slice(0, 3).map((d) => `${d.entryId} "${d.name}"`).join(", ");
@@ -1325,7 +1324,7 @@ Use \`context action=get\` to inspect the existing entry, or \`entries action=up
1325
1324
  next.push({ tool: "context", description: "See its connections", parameters: { action: "find", entryId: finalEntryId } });
1326
1325
  } else {
1327
1326
  next.push({ tool: "context", description: "Review the draft alternative", parameters: { action: "get", entryId: finalEntryId } });
1328
- next.push(spineFloor && !spineFloor.exempt && !spineFloor.linkWritten ? { tool: "relations", description: "Write the spine link it owes", parameters: { action: "create", from: finalEntryId, type: spineFloor.relationType } } : { tool: "entries", description: "Accept onto Chain", parameters: { action: "commit", entryId: finalEntryId } });
1327
+ next.push(spineFloor && !spineFloor.exempt && !spineFloor.linkWritten ? { tool: "relations", description: "Write the spine link it owes", parameters: { action: "create", from: finalEntryId, type: spineFloor.relationType } } : { tool: "entries", description: "Accept onto Chain", parameters: { action: "accept", entryId: finalEntryId } });
1329
1328
  }
1330
1329
  const qualityPhrase = verdictQualityPhrase(verdictResult);
1331
1330
  const summary = finalStatus === "committed" ? `Captured and accepted ${finalEntryId} (${name}) onto ${landedCollection}. ${qualityPhrase}` : `Captured ${finalEntryId} (${name}) as draft in ${landedCollection}. ${qualityPhrase}`;
@@ -1599,11 +1598,11 @@ var updateEntrySchema = z7.object({
1599
1598
  name: z7.string().optional().describe("New display name"),
1600
1599
  // Chain-ID-leak guard (check:chain-id-leaks): the retired legacy-shim ticket number stays in
1601
1600
  // the code comment above, never in this user-visible describe() string. T8 (TASK-393, WP-779): narrowed to generated ENTRY_STATUS_WRITE_WORDS.
1602
- status: z7.enum(ENTRY_STATUS_WRITE_WORDS).optional().describe(`Lifecycle status: ${ENTRY_STATUS_WRITE_WORDS.join(" | ")}. 'accepted' is set via 'commit', never 'update'; 'active'/'deprecated' are legacy words and are refused here. Use \`workflowStatus\` for collection-specific workflow values \u2014 those are no longer accepted via \`status\`.`),
1601
+ status: z7.enum(ENTRY_STATUS_WRITE_WORDS).optional().describe(`Lifecycle status: ${ENTRY_STATUS_WRITE_WORDS.join(" | ")}. 'accepted' is set via 'accept', never 'update'; 'active'/'deprecated' are legacy words and are refused here. Use \`workflowStatus\` for collection-specific workflow values \u2014 those are no longer accepted via \`status\`.`),
1603
1602
  workflowStatus: z7.string().optional().describe("Collection workflow state. Valid values are collection-specific and server-owned \u2014 discover them via `collections action=describe` for the target collection. The server rejects invalid values and returns the valid set in the error."),
1604
1603
  data: z7.record(z7.unknown()).optional().describe("Fields to update (merged with existing data)"),
1605
1604
  order: z7.number().optional().describe("New sort order"),
1606
- canonicalKey: z7.string().optional().describe("Semantic type (e.g. 'decision', 'tension'). Only changeable on draft/uncommitted entries."),
1605
+ canonicalKey: z7.string().optional().describe("Semantic type (e.g. 'decision', 'tension'). Only changeable on draft entries."),
1607
1606
  autoPublish: z7.boolean().optional().default(false).describe("Accepted for backward compatibility but IGNORED \u2014 draft vs. published is decided by the entry's own accepted/active status, never by this flag. Removal tracked as a follow-up."),
1608
1607
  // DEC-1716
1609
1608
  changeReason: z7.string().optional().describe("Change reason: required when this update changes a promise field (or the name of a collection that declares one) of an accepted entry \u2014 why what the entry promises is changing. Recorded on the history event and the version. Not the same as changeNote."),
@@ -1716,7 +1715,7 @@ ${mcp}`, "QUALITY_HELD", mcp.split("\n")[0] ?? mcp, mcp.split("\n")[1] ?? mcp, v
1716
1715
  const next = [
1717
1716
  { tool: "context", description: "View updated entry", parameters: { action: "get", entryId } },
1718
1717
  // DEC-1894: reads live on context
1719
- { tool: toolName, description: "Accept onto Chain", parameters: { action: "commit", entryId } }
1718
+ { tool: toolName, description: "Accept onto Chain", parameters: { action: "accept", entryId } }
1720
1719
  ];
1721
1720
  return {
1722
1721
  content: [{ type: "text", text: responseLines.join("\n") }],
@@ -1791,7 +1790,7 @@ async function handleCommitEntry({ entryId, preview, steeringOverrideReason, qua
1791
1790
  ...conflictEvidence.length > 0 ? { conflicts: conflictEvidence } : {}
1792
1791
  });
1793
1792
  if (result2?.status === "coherency_refused" && result2?.refusal) {
1794
- return coherencyRefusedResult(`${toolName} action=commit`, entryId, result2.refusal);
1793
+ return coherencyRefusedResult(`${toolName} action=accept`, entryId, result2.refusal);
1795
1794
  }
1796
1795
  if (result2?.preview) {
1797
1796
  const wouldBlock = result2.wouldBlock === true;
@@ -1808,7 +1807,7 @@ async function handleCommitEntry({ entryId, preview, steeringOverrideReason, qua
1808
1807
  ...wouldBlock && result2.blockingReason ? { blockingReason: result2.blockingReason } : {},
1809
1808
  ...previewContradictionAdvisory ? { contradictionAdvisory: previewContradictionAdvisory } : {}
1810
1809
  },
1811
- [{ tool: toolName, description: "Accept for real", parameters: { action: "commit", entryId } }]
1810
+ [{ tool: toolName, description: "Accept for real", parameters: { action: "accept", entryId } }]
1812
1811
  );
1813
1812
  if (result2.contract) {
1814
1813
  previewEnvelope.contract = result2.contract;
@@ -1820,7 +1819,7 @@ async function handleCommitEntry({ entryId, preview, steeringOverrideReason, qua
1820
1819
  **Would be blocked** by the coherency/grounding gate.` : "";
1821
1820
  const advisoryNote = previewContradictionAdvisory ? `
1822
1821
 
1823
- \u26A0 Contradiction advisory (would be attached on real commit): ${previewContradictionAdvisory.reason}
1822
+ \u26A0 Contradiction advisory (would be attached on a real accept): ${previewContradictionAdvisory.reason}
1824
1823
  ${previewContradictionAdvisory.conflictDetails.map((c) => `- \`${c.chainEntryId}\` ${c.chainEntryName}: ${c.explanation}`).join("\n")}` : "";
1825
1824
  return {
1826
1825
  content: [{ type: "text", text: `# Preview: would ${wouldBlock ? "BLOCK accept" : "accept"} ${entryId}
@@ -1838,14 +1837,14 @@ No DB writes \u2014 call without \`preview:true\` to accept for real.` }],
1838
1837
  const lines = [
1839
1838
  `# Accepted: ${entryId}`,
1840
1839
  ...judged ? [judged] : [],
1841
- `**${entry.name}** promoted to SSOT on the Chain.`,
1840
+ `**${entry.name}** accepted onto the Chain.`,
1842
1841
  `**Workspace:** ${wsCtx.workspaceSlug} (${wsCtx.workspaceId})`
1843
1842
  ];
1844
1843
  const autoVerified = result2?.autoVerified;
1845
1844
  if (autoVerified?.strength) {
1846
1845
  const who = autoVerified.verifiedBy ? ` (${autoVerified.verifiedBy})` : "";
1847
1846
  lines.push("");
1848
- lines.push(`_Auto-verified as part of promote \u2014 ${autoVerified.strength}${who}._`);
1847
+ lines.push(`_Auto-verified as part of this accept \u2014 ${autoVerified.strength}${who}._`);
1849
1848
  }
1850
1849
  if (advisoryWarnings.length > 0) {
1851
1850
  lines.push("");
@@ -1876,7 +1875,7 @@ No DB writes \u2014 call without \`preview:true\` to accept for real.` }],
1876
1875
  const contradictionAdvisory = result2?.contradictionAdvisory;
1877
1876
  if (contradictionAdvisory) {
1878
1877
  lines.push("");
1879
- lines.push(`\u26A0 Contradiction advisory (entry committed): ${contradictionAdvisory.reason}`);
1878
+ lines.push(`\u26A0 Contradiction advisory (entry accepted): ${contradictionAdvisory.reason}`);
1880
1879
  for (const c of contradictionAdvisory.conflictDetails) {
1881
1880
  lines.push(`- \`${c.chainEntryId}\` ${c.chainEntryName}: ${c.explanation}`);
1882
1881
  }
@@ -1884,7 +1883,7 @@ No DB writes \u2014 call without \`preview:true\` to accept for real.` }],
1884
1883
  const publishAdvisories = Array.isArray(result2?.publishAdvisories) ? result2.publishAdvisories.filter((a) => typeof a === "string") : void 0;
1885
1884
  if (publishAdvisories && publishAdvisories.length > 0) {
1886
1885
  lines.push("");
1887
- lines.push("\u26A0 Direction advisory (entry committed):");
1886
+ lines.push("\u26A0 Direction advisory (entry accepted):");
1888
1887
  for (const advisory of publishAdvisories) {
1889
1888
  lines.push(`- ${advisory}`);
1890
1889
  }
@@ -2443,7 +2442,7 @@ function platformSearchLines(platform) {
2443
2442
  import { z as z11 } from "zod/v3";
2444
2443
  var ENTRIES_ACTIONS = [
2445
2444
  "update",
2446
- "commit",
2445
+ "accept",
2447
2446
  "move",
2448
2447
  "verify",
2449
2448
  "still-true"
@@ -2453,18 +2452,19 @@ var coherencyAcknowledgementFlatSchema = z11.object({
2453
2452
  entryId: z11.string().max(200).optional().describe("Authorizing entry being linked/accepted (required for 'linked' and 'accepted-fix')."),
2454
2453
  reason: z11.string().max(2e3).optional().describe("Divergence rationale (required for 'diverged', \u226512 chars).")
2455
2454
  });
2456
- var ENTRIES_READS_MOVED = {
2457
- preflight: "entries only writes. Check a collection's requirements with the read-only context tool: context action=preflight collection=..."
2455
+ var ENTRIES_MOVED = {
2456
+ preflight: "entries only writes. Check a collection's requirements with the read-only context tool: context action=preflight collection=...",
2457
+ commit: "commit was renamed accept. Next: entries action=accept entryId=..."
2458
2458
  };
2459
2459
  var entriesSchema = z11.object({
2460
- action: actionEnum(ENTRIES_ACTIONS, ENTRIES_READS_MOVED).describe(
2461
- "'update': change fields on an existing entry (draft by default). 'commit': accept a draft entry onto the Chain. 'move': relocate an entry to a different collection (pass `canonicalKey` too for an atomic move+retype). 'verify': mark an entry as verified (lightweight \u2014 no codebase scan; see `quality action=verify-chain` for that). 'still-true': confirm accuracy (the holder of the owning role, else the nearest seated Team Lead) \u2014 distinct from 'verify'; no content, version, or updatedAt change."
2460
+ action: actionEnum(ENTRIES_ACTIONS, ENTRIES_MOVED).describe(
2461
+ "'update': change fields on an existing entry (draft by default). 'accept': accept a draft entry onto the Chain. 'move': relocate an entry to a different collection (pass `canonicalKey` too for an atomic move+retype). 'verify': mark an entry as verified (lightweight \u2014 no codebase scan; see `quality action=verify-chain` for that). 'still-true': confirm accuracy (the holder of the owning role, else the nearest seated Team Lead) \u2014 distinct from 'verify'; no content, version, or updatedAt change."
2462
2462
  ),
2463
2463
  entryId: z11.string().max(200).optional().describe(
2464
- "Entry ID, e.g. '<PREFIX>-<n>'. Required for: update, commit, move, verify, still-true."
2464
+ "Entry ID, e.g. '<PREFIX>-<n>'. Required for: update, accept, move, verify, still-true."
2465
2465
  ),
2466
2466
  status: z11.string().max(200).optional().describe(
2467
- "For 'update': draft|archived ONLY \u2014 'accepted' is set via 'commit', never 'update'; 'active'/'deprecated' are legacy read-only words, refused on write. Workflow values use `workflowStatus` instead."
2467
+ "For 'update': draft|archived ONLY \u2014 'accepted' is set via 'accept', never 'update'; 'active'/'deprecated' are legacy read-only words, refused on write. Workflow values use `workflowStatus` instead."
2468
2468
  ),
2469
2469
  name: z11.string().max(ENTRY_NAME_MAX_CHARS).optional().describe("For 'update': new display name."),
2470
2470
  workflowStatus: z11.string().max(200).optional().describe(
@@ -2473,7 +2473,7 @@ var entriesSchema = z11.object({
2473
2473
  data: z11.record(z11.unknown()).optional().describe("For 'update': fields to update (merged with existing data)."),
2474
2474
  order: z11.number().optional().describe("For 'update': new sort order."),
2475
2475
  canonicalKey: z11.string().max(200).optional().describe(
2476
- "For 'update': semantic type (e.g. 'decision', 'tension'); only changeable on draft/uncommitted entries. For 'move': optional atomic move+retype target."
2476
+ "For 'update': semantic type (e.g. 'decision', 'tension'); only changeable on draft entries. For 'move': optional atomic move+retype target."
2477
2477
  ),
2478
2478
  // DEC-1716: draft vs. published is decided by the entry's own accepted/active status, never this flag.
2479
2479
  autoPublish: z11.boolean().optional().default(false).describe(
@@ -2492,21 +2492,21 @@ var entriesSchema = z11.object({
2492
2492
  "For 'update': verbatim excerpt from the source backing this entry's claims. Write-once."
2493
2493
  ),
2494
2494
  steeringOverrideReason: z11.string().max(2e3).optional().describe(
2495
- "For 'update'/'commit': typed override (\u226512 chars) that clears a steering coherency block."
2495
+ "For 'update'/'accept': typed override (\u226512 chars) that clears a steering coherency block."
2496
2496
  ),
2497
2497
  qualityOverrideReason: z11.string().max(2e3).optional().describe(
2498
- "For 'update'/'commit': why (\u226512 chars) to keep a spine text its quality checklist failed; recorded as an override with who wrote it."
2498
+ "For 'update'/'accept': why (\u226512 chars) to keep a spine text its quality checklist failed; recorded as an override with who wrote it."
2499
2499
  ),
2500
2500
  coherencyAcknowledgement: coherencyAcknowledgementFlatSchema.optional().describe(
2501
- "For 'update'/'commit': explicit response to a coherency challenge (standard/strict workspace modes)."
2501
+ "For 'update'/'accept': explicit response to a coherency challenge (standard/strict workspace modes)."
2502
2502
  ),
2503
2503
  preview: z11.boolean().optional().describe(
2504
- "For 'commit': if true, validates the accept without writing \u2014 returns what would happen."
2504
+ "For 'accept': if true, validates the accept without writing \u2014 returns what would happen."
2505
2505
  ),
2506
2506
  toCollection: z11.string().max(200).optional().describe("For 'move': target collection slug, e.g. 'decisions', 'architecture'.")
2507
2507
  });
2508
2508
  var entriesUpdateVariant = updateEntrySchema.extend({ action: z11.literal("update") });
2509
- var entriesCommitVariant = commitEntrySchema.extend({ action: z11.literal("commit") });
2509
+ var entriesAcceptVariant = commitEntrySchema.extend({ action: z11.literal("accept") });
2510
2510
  var entriesMoveVariant = z11.object({
2511
2511
  action: z11.literal("move"),
2512
2512
  entryId: z11.string().max(200),
@@ -2518,14 +2518,14 @@ var entriesVerifyVariant = verifyEntrySchema.extend({ action: z11.literal("verif
2518
2518
  var entriesStillTrueVariant = stillTrueEntrySchema.extend({ action: z11.literal("still-true") });
2519
2519
  var entriesActionUnion = z11.discriminatedUnion("action", [
2520
2520
  entriesUpdateVariant,
2521
- entriesCommitVariant,
2521
+ entriesAcceptVariant,
2522
2522
  entriesMoveVariant,
2523
2523
  entriesVerifyVariant,
2524
2524
  entriesStillTrueVariant
2525
2525
  ]);
2526
2526
  var ENTRIES_ACTION_SPECS = {
2527
2527
  update: { params: ["entryId", "name", "status", "workflowStatus", "data", "order", "canonicalKey", "autoPublish", "changeNote", "changeReason", "sourceRef", "sourceExcerpt", "steeringOverrideReason", "qualityOverrideReason", "coherencyAcknowledgement"], description: "entryId is required; every other field is optional." },
2528
- commit: { params: ["entryId", "preview", "steeringOverrideReason", "qualityOverrideReason", "coherencyAcknowledgement"], description: "entryId is required." },
2528
+ accept: { params: ["entryId", "preview", "steeringOverrideReason", "qualityOverrideReason", "coherencyAcknowledgement"], description: "entryId is required." },
2529
2529
  move: { params: ["entryId", "toCollection", "canonicalKey"], description: "entryId and toCollection are required; canonicalKey is optional (atomic move+retype)." },
2530
2530
  verify: { params: ["entryId"], description: "entryId is required." },
2531
2531
  "still-true": { params: ["entryId"], description: "entryId is required. Allowed for the holder of the owning role; if that role is empty, the nearest seated Team Lead up the team tree." }
@@ -2673,10 +2673,10 @@ var entriesBatchOutputSchema = z12.object({
2673
2673
  });
2674
2674
  function registerEntriesTools(server) {
2675
2675
  const entriesHandlers = {
2676
- // update/commit reuse knowledge.ts's extracted handlers — "entries" routes
2676
+ // update/accept reuse knowledge.ts's extracted handlers — "entries" routes
2677
2677
  // `next` at itself (toolName="entries") instead of the legacy tool names.
2678
2678
  update: (data) => handleUpdateEntry(data, "entries"),
2679
- commit: (data) => handleCommitEntry(data, "entries"),
2679
+ accept: (data) => handleCommitEntry(data, "entries"),
2680
2680
  move: (data) => handleMoveEntry(data.entryId, data.toCollection, data.canonicalKey),
2681
2681
  verify: (data) => handleVerifyEntry(data),
2682
2682
  "still-true": (data) => handleStillTrueEntry(data)
@@ -2685,7 +2685,7 @@ function registerEntriesTools(server) {
2685
2685
  "entries",
2686
2686
  {
2687
2687
  title: "Entries",
2688
- description: 'Write entries on the Chain: the entry lifecycle after capture. Reads live on `context`.\n\n- **update**: Change fields on an existing entry (publishes whenever the entry is not draft \u2014 includes archived, not just accepted/active; autoPublish is accepted but ignored).\n- **commit**: Accept a draft entry onto the Chain (SSOT). Runs the contradiction preflight first.\n- **move**: Relocate an entry to a different collection; pass canonicalKey too for an atomic move+retype.\n- **verify**: Mark verified (lightweight, no scan \u2014 see `quality action=verify-chain`).\n- **still-true**: confirm accuracy (the holder of the owning role; if that role is empty, the nearest seated Team Lead up the team tree).\n\nRead entries with the read-only `context` tool: `context action=get entryId="..."`, `context action=search query="..."`, `context action=preflight`.',
2688
+ description: 'Write entries on the Chain: the entry lifecycle after capture. Reads live on `context`.\n\n- **update**: Change fields on an existing entry (publishes whenever the entry is not draft \u2014 includes archived, not just accepted/active; autoPublish is accepted but ignored).\n- **accept**: Accept a draft entry onto the Chain. Runs the contradiction preflight first.\n- **move**: Relocate an entry to a different collection; pass canonicalKey too for an atomic move+retype.\n- **verify**: Mark verified (lightweight, no scan \u2014 see `quality action=verify-chain`).\n- **still-true**: confirm accuracy (the holder of the owning role; if that role is empty, the nearest seated Team Lead up the team tree).\n\nRead entries with the read-only `context` tool: `context action=get entryId="..."`, `context action=search query="..."`, `context action=preflight`.',
2689
2689
  inputSchema: entriesSchema,
2690
2690
  // DEC-1894 / DEC-74: every look-up lives on the read-only `context` tool, so this
2691
2691
  // annotation tells hosts the truth about the writes left here.
@@ -4338,7 +4338,7 @@ var CONTEXT_ACTIONS = [...LOOKUP_ACTIONS, "gather", "build", "neighborhood", "ch
4338
4338
  var contextSchema = z20.object({
4339
4339
  // provenance: neighborhood BET-142; changes/chain/cross-cut/incremental/brief BET-239 (E4, E6)
4340
4340
  action: z20.enum(CONTEXT_ACTIONS).describe(
4341
- LOOKUP_ACTION_DESCRIBE + "'gather': assemble knowledge context (entry graph, task auto-load, journey mode, or graph mode). 'build': structured build spec for an entry. 'neighborhood': typed graph neighborhood for an entry \u2014 blocking chain, dependencies, parent context, tensions, staleness. 'changes': entries modified and relations created since a timestamp. Requires 'since' parameter. 'chain': directed traversal along one relation type to depth 4. Requires entryId. Optional: direction, relationType, maxHops (1-4). 'cross-cut': structural aggregation \u2014 all relations of a given type grouped by source collection. Requires 'relationType' parameter. 'incremental': delta since last brief run for a skill. Requires 'skill' parameter. Returns only entries changed since the skill's last brief. 'brief': compound intelligence query. Requires 'briefType' parameter: 'steering' (changes + structure + delta + readiness), 'confidence' (changes + active bets \u2014 use the pb CLI's `tensions list` for tensions), or 'delta' (changes + relations since timestamp). Optional 'since' for delta type. 'last-verified-brief': fetch the most recent verified brief snapshot for a (templateId, scopeKey) pair (absorbs documents action=get-last-verified-brief). Requires templateId and scopeKey."
4341
+ LOOKUP_ACTION_DESCRIBE + "'gather': assemble knowledge context (entry graph, task auto-load, journey mode, or graph mode). 'build': structured build spec for an entry. 'neighborhood': typed graph neighborhood for an entry \u2014 blocking chain, dependencies, parent context, tensions, staleness. 'changes': entries modified and relations created since a timestamp. Requires 'since' parameter. 'chain': directed traversal along one relation type to depth 4. Requires entryId. Optional: direction, relationType, maxHops (1-4). 'cross-cut': structural aggregation \u2014 all relations of a given type grouped by source collection. Requires 'relationType' parameter. 'incremental': delta since last brief run for a skill. Requires 'skill' parameter. Returns only entries changed since the skill's last brief. 'brief': compound intelligence query. Requires 'briefType' parameter: 'steering' (changes + structure + delta + readiness), 'confidence' (changes + active bets \u2014 use the pb CLI's `tensions list` for tensions), or 'delta' (changes + relations since timestamp). Optional 'since' for delta type. 'last-verified-brief': fetch the most recent verified brief snapshot for a (templateId, scopeKey) pair. Requires templateId and scopeKey."
4342
4342
  ),
4343
4343
  entryId: z20.string().max(200).optional().describe("For 'get'/'history'/'find'/'outcome'/'readings'/'build'/'neighborhood'/'chain': entry ID. For 'gather': optional (entry-graph mode)."),
4344
4344
  ...lookupParams,
@@ -6749,11 +6749,11 @@ function buildOrientBriefingLines(view) {
6749
6749
  if (!view) return [];
6750
6750
  return formatBriefingLines({ facts: view.briefing ?? void 0, ruleLists: view.ruleLists ?? void 0, surface: "mcp" });
6751
6751
  }
6752
- async function fetchAndRenderOpenerDirection(kernelQuery3, errors, session) {
6752
+ async function fetchAndRenderOpenerDirection(kernelQuery2, errors, session) {
6753
6753
  let view = null;
6754
6754
  let fetchFailed = false;
6755
6755
  try {
6756
- view = await kernelQuery3("chain.getOrientView", {
6756
+ view = await kernelQuery2("chain.getOrientView", {
6757
6757
  tier: "standard",
6758
6758
  invocationPath: session?.invocationPath ?? "session-start",
6759
6759
  // Stamps this call onto the current session/conversation/task (same as every other
@@ -6768,9 +6768,9 @@ async function fetchAndRenderOpenerDirection(kernelQuery3, errors, session) {
6768
6768
  }
6769
6769
  return { lines: [...buildOrientBriefingLines(view), ...buildRitualsSurfaceLines(view, { fetchFailed: fetchFailed || view?.fetchFailed === true })], view };
6770
6770
  }
6771
- async function buildAlreadyOrientedResult(kernelQuery3, agentSessionId, taskGroundingWarningLines2) {
6771
+ async function buildAlreadyOrientedResult(kernelQuery2, agentSessionId, taskGroundingWarningLines2) {
6772
6772
  const errors = [];
6773
- const { lines, view } = await fetchAndRenderOpenerDirection(kernelQuery3, errors, { agentSessionId, invocationPath: "manual-orient" });
6773
+ const { lines, view } = await fetchAndRenderOpenerDirection(kernelQuery2, errors, { agentSessionId, invocationPath: "manual-orient" });
6774
6774
  return {
6775
6775
  content: [{
6776
6776
  type: "text",
@@ -7896,7 +7896,7 @@ var SHAPE_WORKFLOW_DESCRIPTOR = {
7896
7896
  id: "shape",
7897
7897
  skill: "shaping",
7898
7898
  name: "Shape a Bet",
7899
- shortDescription: "Integration-aware shaping: maps the system before designing, traces five paths per element, surfaces governance conflicts at design time. Scoring is in the shaping skill; uses capture and session action=commit-constellation for Chain capture.",
7899
+ shortDescription: "Integration-aware shaping: maps the system before designing, traces five paths per element, surfaces governance conflicts at design time. Scoring is in the shaping skill; uses capture and entries action=accept for Chain capture.",
7900
7900
  template: {
7901
7901
  slug: "shape-a-bet",
7902
7902
  name: "Shape a Bet"
@@ -7905,7 +7905,7 @@ var SHAPE_WORKFLOW_DESCRIPTOR = {
7905
7905
  facilitatorPreamble: `You are now in **Shaping Mode**. The shaping skill owns the facilitation loop end-to-end \u2014 read it for scoring rubrics, investigation patterns, and the capture flow.
7906
7906
 
7907
7907
  Use \`capture\` to create constellation entries (elements, risks, decisions, glossary terms) linked to the work package.
7908
- Use \`session action=commit-constellation\` to accept the work package and all linked entries when the shape is complete \u2014 sequentially, best-effort per entry; check failedIds and conflictIds.
7908
+ Use \`entries action=accept\` on the work package, then on each linked entry, when the shape is complete.
7909
7909
  Use \`workflows action=checkpoint\` after each round to persist progress to the durable run.`,
7910
7910
  rounds: [
7911
7911
  {
@@ -8016,7 +8016,7 @@ Use \`workflows action=checkpoint\` after each round to persist progress to the
8016
8016
  label: "Capture & Accept",
8017
8017
  type: "close",
8018
8018
  instruction: "Capture the pitch to the Chain. Accept draft entries. Connect the constellation.",
8019
- facilitatorGuidance: "List all draft entries created during shaping (elements, risks, decisions, glossary terms). Ask the user to confirm: 'Ready to accept these onto the Chain?' Call `session action=commit-constellation` to accept the work package and all linked entries \u2014 sequentially, best-effort per entry; check failedIds and conflictIds. Then link the work package to the entries it relates to via `relations action=batch-create`. Thank the user. State: what was shaped, how many constellation entries captured, what the implementer inherits.",
8019
+ facilitatorGuidance: "List all draft entries created during shaping (elements, risks, decisions, glossary terms). Ask the user to confirm: 'Ready to accept these onto the Chain?' Call `entries action=accept` on the work package, then on each linked entry. Then link the work package to the entries it relates to via `relations action=batch-create`. Thank the user. State: what was shaped, how many constellation entries captured, what the implementer inherits.",
8020
8020
  outputSchema: {
8021
8021
  field: "capture",
8022
8022
  description: "Final capture summary \u2014 entries accepted, relations created",
@@ -8275,7 +8275,7 @@ var PROCESS_CHANGE_WORKFLOW_DESCRIPTOR = {
8275
8275
  - \`context action=search\` \u2014 find related entries
8276
8276
  - \`capture\` \u2014 manual fallback only if workflow finalization cannot safely route the entry
8277
8277
  - \`relations action=create\` or \`relations action=batch-create\` \u2014 link to related entries
8278
- - \`entries action=commit\` \u2014 promote to SSOT (only on user confirmation)
8278
+ - \`entries action=accept\` \u2014 accept onto the Chain (only on user confirmation)
8279
8279
  - \`workflows action=checkpoint\` \u2014 save progress if needed
8280
8280
 
8281
8281
  ## Communication Style
@@ -8333,7 +8333,7 @@ var PROCESS_CHANGE_WORKFLOW_DESCRIPTOR = {
8333
8333
  label: "Capture & Close",
8334
8334
  type: "close",
8335
8335
  instruction: "Capture to the Chain. Link to related entries. Confirm with the user.",
8336
- facilitatorGuidance: "Finalize through workflows action=checkpoint with isFinal=true, passing a summaryName when you have a clean title. The workflow substrate will create the primary record as a draft and attach it to the durable run. After finalization, link the entry to the 2-3 entries it relates to with relations action=create. Show the user what was captured: entry ID, collection it landed in, relations created. Ask if they want to accept now or leave as draft. If they confirm, use entries action=commit. If there are stale entries to reconfirm, mention them. Thank the user briefly and exit \u2014 don't linger.",
8336
+ facilitatorGuidance: "Finalize through workflows action=checkpoint with isFinal=true, passing a summaryName when you have a clean title. The workflow substrate will create the primary record as a draft and attach it to the durable run. After finalization, link the entry to the 2-3 entries it relates to with relations action=create. Show the user what was captured: entry ID, collection it landed in, relations created. Ask if they want to accept now or leave as draft. If they confirm, use entries action=accept. If there are stale entries to reconfirm, mention them. Thank the user briefly and exit \u2014 don't linger.",
8337
8337
  outputSchema: {
8338
8338
  field: "capture",
8339
8339
  description: "Entry captured, relations created, accept status",
@@ -8962,7 +8962,7 @@ This checkpoint was NOT saved. The conversation context is preserved \u2014 cont
8962
8962
  `Collection: \`${result2.summary.collection ?? (resolvedSummaryCapture.routing.mode === "fixed" ? resolvedSummaryCapture.routing.collection : "classifier-routed")}\``,
8963
8963
  `Name: ${result2.summary.name}`,
8964
8964
  "",
8965
- `The summary is captured as a draft. Use \`entries action=commit entryId="${result2.summary.entryId}"\` to promote it to the Chain.`,
8965
+ `The summary is captured as a draft. Use \`entries action=accept entryId="${result2.summary.entryId}"\` to accept it onto the Chain.`,
8966
8966
  `Use \`relations action=create\` to link it to the entries it relates to.`
8967
8967
  );
8968
8968
  return {
@@ -8981,8 +8981,8 @@ This checkpoint was NOT saved. The conversation context is preserved \u2014 cont
8981
8981
  [
8982
8982
  {
8983
8983
  tool: "entries",
8984
- description: "Promote draft to Chain",
8985
- parameters: { action: "commit", entryId: result2.summary.entryId }
8984
+ description: "Accept draft onto the Chain",
8985
+ parameters: { action: "accept", entryId: result2.summary.entryId }
8986
8986
  },
8987
8987
  {
8988
8988
  tool: "context",
@@ -9582,10 +9582,7 @@ async function handleReEvaluate(entryId, context) {
9582
9582
  }
9583
9583
 
9584
9584
  // src/tools/session.ts
9585
- import { z as z28 } from "zod/v3";
9586
-
9587
- // src/tools/wrapup.ts
9588
- import { z as z26 } from "zod/v3";
9585
+ import { z as z27 } from "zod/v3";
9589
9586
 
9590
9587
  // src/lib/compose-wrapup-view.ts
9591
9588
  function toComposed(e) {
@@ -9660,14 +9657,14 @@ async function runWrapupReview() {
9660
9657
  }
9661
9658
  const lines = [];
9662
9659
  lines.push(
9663
- `**Session activity:** ${data.summary.created} created, ${data.summary.modified} modified, ${data.summary.uncommitted} uncommitted drafts.`
9660
+ `**Session activity:** ${data.summary.created} created, ${data.summary.modified} modified, ${data.summary.uncommitted} draft${data.summary.uncommitted === 1 ? "" : "s"} not yet accepted.`
9664
9661
  );
9665
9662
  if (overflowUnscanned > 0) {
9666
9663
  lines.push(`_...and ${overflowUnscanned} more entr${overflowUnscanned === 1 ? "y" : "ies"} this session could not be enumerated (past the scan cap)._`);
9667
9664
  }
9668
9665
  lines.push("");
9669
9666
  if (data.drafts.length > 0) {
9670
- lines.push("### Uncommitted Drafts", "");
9667
+ lines.push("### Drafts", "");
9671
9668
  lines.push("| Entry | Collection | Quality | Connections | Coaching |");
9672
9669
  lines.push("|-------|------------|---------|-------------|----------|");
9673
9670
  for (const draft of data.drafts) {
@@ -9681,7 +9678,7 @@ async function runWrapupReview() {
9681
9678
  lines.push("");
9682
9679
  }
9683
9680
  if (data.committed.length > 0) {
9684
- lines.push(`### Already Committed (${data.committed.length})`, "");
9681
+ lines.push(`### Already Accepted (${data.committed.length})`, "");
9685
9682
  for (const entry of data.committed) {
9686
9683
  const conns = data.connectionCounts[entry.entryId] ?? 0;
9687
9684
  lines.push(`- \`${entry.entryId}\` [${entry.collection}] ${entry.name} (${conns} connections)`);
@@ -9694,7 +9691,7 @@ async function runWrapupReview() {
9694
9691
  lines.push(`### Beyond Review Cap (${overflowDrafts.length + overflowCommitted.length})`, "");
9695
9692
  lines.push("_Past the per-session enrichment cap \u2014 listed by id and name only._", "");
9696
9693
  for (const e of overflowCommitted) {
9697
- lines.push(`- \`${e.entryId}\` \u2014 ${e.name} (committed)`);
9694
+ lines.push(`- \`${e.entryId}\` \u2014 ${e.name} (accepted)`);
9698
9695
  }
9699
9696
  for (const e of overflowDrafts) {
9700
9697
  lines.push(`- \`${e.entryId}\` \u2014 ${e.name} (draft)`);
@@ -9773,14 +9770,14 @@ async function runWrapupReview() {
9773
9770
  if (allDraftEntries.length > 0) {
9774
9771
  const draftIds = allDraftEntries.map((d) => `\`${d.entryId}\``).join(", ");
9775
9772
  lines.push("### Actions", "");
9776
- lines.push(`Uncommitted: ${draftIds}`);
9777
- lines.push("- **Accept all:** call `session action=wrapup-commit`");
9773
+ lines.push(`Drafts: ${draftIds}`);
9774
+ lines.push("- **Accept:** call `entries action=accept entryId=...` for each one you mean to keep.");
9778
9775
  lines.push("- **Skip:** call `session action=close` \u2014 drafts remain for next session's orient recovery.");
9779
9776
  }
9780
9777
  if (overflowUnscanned > 0) {
9781
9778
  lines.push("");
9782
9779
  lines.push(
9783
- `> _${overflowUnscanned} draft(s) beyond the scan cap can't be auto-committed here \u2014 commit them individually via \`entries action=commit\`, or close via \`session action=close\`._`
9780
+ `> _${overflowUnscanned} draft(s) beyond the scan cap are not listed here \u2014 accept each with \`entries action=accept\`, or close via \`session action=close\`._`
9784
9781
  );
9785
9782
  }
9786
9783
  if (data.captureAudit) {
@@ -9804,127 +9801,9 @@ async function runWrapupReview() {
9804
9801
  kernelMeta: kernelEnvelope._meta
9805
9802
  };
9806
9803
  }
9807
- async function runWrapupCommitAll(data) {
9808
- requireWriteAccess();
9809
- const sessionId = getAgentSessionId();
9810
- if (!sessionId) {
9811
- return { text: "No active session.", committed: 0, failed: 0, overflowUnscanned: 0 };
9812
- }
9813
- const results = [];
9814
- const allDrafts = [...data.drafts, ...data.overflowDrafts ?? []];
9815
- const overflowUnscanned = data.overflowUnscanned ?? 0;
9816
- for (const draft of allDrafts) {
9817
- try {
9818
- const result2 = await kernelMutation("chain.commitEntry", {
9819
- entryId: draft.entryId,
9820
- author: `agent:${sessionId}`,
9821
- sessionId
9822
- });
9823
- if (result2 && "status" in result2 && result2.status === "coherency_refused") {
9824
- const refusal = "refusal" in result2 ? result2.refusal : void 0;
9825
- results.push({
9826
- entryId: draft.entryId,
9827
- ok: false,
9828
- error: `coherency gate refused this accept \u2014 ${refusal?.reason ?? "refused by the coherency gate"}`
9829
- });
9830
- continue;
9831
- }
9832
- await recordSessionActivity({ entryModified: draft.docId });
9833
- results.push({ entryId: draft.entryId, ok: true });
9834
- } catch (err) {
9835
- const msg = err instanceof Error ? err.message : String(err);
9836
- results.push({ entryId: draft.entryId, ok: false, error: msg });
9837
- }
9838
- }
9839
- const committed = results.filter((r) => r.ok).length;
9840
- const failed = results.filter((r) => !r.ok);
9841
- const cleanDrain = failed.length === 0 && overflowUnscanned === 0;
9842
- if (cleanDrain) {
9843
- await kernelCall("agent.recordWrapup", {
9844
- sessionId,
9845
- draftsReviewed: allDrafts.length,
9846
- draftsCommitted: committed,
9847
- linksCreated: 0
9848
- });
9849
- }
9850
- const lines = [
9851
- "## Wrapup Complete",
9852
- "",
9853
- `**${committed}** drafts accepted.`
9854
- ];
9855
- if (failed.length > 0) {
9856
- lines.push("");
9857
- lines.push("### Failed to accept");
9858
- for (const f of failed) {
9859
- lines.push(`- \`${f.entryId}\`: ${f.error}`);
9860
- }
9861
- lines.push("_These remain as drafts for next session._");
9862
- }
9863
- return {
9864
- text: lines.join("\n"),
9865
- committed,
9866
- failed: failed.length,
9867
- overflowUnscanned
9868
- };
9869
- }
9870
- var wrapupSchema = z26.object({
9871
- action: z26.enum(["review", "commit-all"]).optional().describe(
9872
- "Action to perform. 'review' (default) shows the wrapup summary. 'commit-all' accepts all uncommitted drafts; it writes no relations."
9873
- )
9874
- });
9875
9804
  function createWrapupHandler() {
9876
- let lastReviewData = null;
9877
- let lastReviewSessionId = null;
9878
- return async ({ action }) => {
9879
- if (action === "commit-all") {
9880
- const sessionId = getAgentSessionId();
9881
- if (!sessionId) {
9882
- return failureResult(
9883
- "No active agent session.",
9884
- "SESSION_REQUIRED",
9885
- "No active agent session.",
9886
- "Start a session first.",
9887
- [{ tool: "session", description: "Start a session", parameters: { action: "start" } }]
9888
- );
9889
- }
9890
- const useCachedReview = lastReviewSessionId === sessionId;
9891
- let data2;
9892
- if (useCachedReview && lastReviewData) {
9893
- data2 = lastReviewData;
9894
- } else {
9895
- const { workspaceId } = await getWorkspaceContext();
9896
- data2 = (await kernelCallEnvelope("agentKnowledge.wrapupEnvelope", {
9897
- workspaceId,
9898
- sessionId,
9899
- action: "review"
9900
- })).data;
9901
- }
9902
- if (data2.drafts.length === 0 && (data2.overflowDrafts ?? []).length === 0) {
9903
- return failureResult("No uncommitted drafts to accept.", "NOT_FOUND", "No uncommitted drafts to accept.", "Nothing to accept.");
9904
- }
9905
- const result2 = await runWrapupCommitAll(data2);
9906
- lastReviewData = null;
9907
- lastReviewSessionId = null;
9908
- const commitNext = result2.overflowUnscanned > 0 ? [
9909
- {
9910
- tool: "session",
9911
- description: `${result2.overflowUnscanned} draft(s) beyond the scan cap can't be auto-committed here \u2014 commit them individually via \`entries action=commit\`, or close via \`session action=close\`.`,
9912
- parameters: { action: "close" }
9913
- }
9914
- ] : result2.failed > 0 ? [{ tool: "session", description: "Re-review remaining drafts before closing", parameters: { action: "wrapup-review" } }] : [{ tool: "session", description: "Close the session now that drafts are committed", parameters: { action: "close" } }];
9915
- return successResult(
9916
- result2.text,
9917
- `Wrapup processed: ${result2.committed} accepted.`,
9918
- {
9919
- committed: result2.committed,
9920
- failed: result2.failed
9921
- },
9922
- commitNext
9923
- );
9924
- }
9805
+ return async () => {
9925
9806
  const { text, data, failureCode, gapCount, coherenceVerdict, persistentGaps, kernelSummary, kernelNext, kernelMeta } = await runWrapupReview();
9926
- lastReviewData = data;
9927
- lastReviewSessionId = getAgentSessionId();
9928
9807
  const composed = data ? composeWrapupView(data) : null;
9929
9808
  const fullText = composed && (composed.drafts.length > 0 || composed.committed.length > 0 || composed.discarded.length > 0) ? `## Session Wrapup
9930
9809
 
@@ -9932,14 +9811,14 @@ ${text}` : text;
9932
9811
  if (failureCode) {
9933
9812
  return failureResult(fullText, failureCode, text);
9934
9813
  }
9935
- const localNext = composed && !composed.canClose ? [{ tool: "session", description: "Accept all drafts", parameters: { action: "wrapup-commit" } }] : void 0;
9814
+ const localNext = composed && !composed.canClose ? composed.drafts.slice(0, 1).map((d) => ({ tool: "entries", description: "Accept this draft", parameters: { action: "accept", entryId: d.entryId } })) : void 0;
9936
9815
  const next = kernelNext || localNext;
9937
9816
  const gapsSummary = gapCount ? `, ${gapCount} knowledge gaps detected` : "";
9938
9817
  const coherenceSummary = coherenceVerdict ? `, coherence: ${coherenceVerdict}` : "";
9939
9818
  const persistentSummary = persistentGaps?.length ? `, ${persistentGaps.length} persistent coherence gaps` : "";
9940
9819
  const draftsCount = composed?.drafts.length ?? data.drafts.length;
9941
9820
  const committedCount = composed?.committed.length ?? data.committed.length;
9942
- const summaryText = `Session review: ${draftsCount} uncommitted, ${committedCount} committed${gapsSummary}${coherenceSummary}${persistentSummary}.`;
9821
+ const summaryText = `Session review: ${draftsCount} draft${draftsCount === 1 ? "" : "s"}, ${committedCount} accepted${gapsSummary}${coherenceSummary}${persistentSummary}.`;
9943
9822
  return {
9944
9823
  content: [{ type: "text", text: fullText }],
9945
9824
  structuredContent: {
@@ -9961,33 +9840,10 @@ ${text}` : text;
9961
9840
  }
9962
9841
 
9963
9842
  // src/tools/facilitate.ts
9964
- import { z as z27 } from "zod/v3";
9965
- var FACILITATE_ACTIONS = ["resume", "commit-constellation"];
9966
- var coherencyAcknowledgementSchema = z27.object({
9967
- response: z27.string().max(200).describe("Acknowledgement response per offender: 'linked' | 'accepted-fix' | 'diverged'."),
9968
- entryId: z27.string().max(200).optional().describe("Entry the acknowledgement links to (e.g. the strategic spine entry)."),
9969
- reason: z27.string().max(2e3).optional().describe("Free-text justification, required for a 'diverged' response."),
9970
- subjectEntryId: z27.string().max(200).optional().describe("The refused entry this acknowledgement answers.")
9971
- });
9972
- var facilitateSchema = z27.object({
9973
- action: z27.enum(FACILITATE_ACTIONS).describe(
9974
- "'resume': load session state from an existing bet entry. 'commit-constellation': atomically accept a bet and all its linked draft entries in one call. Requires betEntryId."
9975
- ),
9976
- betEntryId: z27.string().max(200).optional().describe("Bet entry ID. Required for both actions."),
9977
- operationId: z27.string().max(200).optional().describe("Optional idempotency key for commit-constellation retries."),
9978
- // WP-465 slice ⑤: coherency retry controls for a COHERENCY_REFUSED constellation hold.
9979
- // Forwarded verbatim to agentKnowledge.facilitateEnvelope (validation lives at the gate).
9980
- coherencyAcknowledgements: z27.array(coherencyAcknowledgementSchema).max(20).optional().describe(
9981
- "Per-offender acknowledgements to retry a constellation held under standard/strict coherency mode. Each: {subjectEntryId, response: 'linked' | 'accepted-fix' | 'diverged', entryId?, reason?}."
9982
- ),
9983
- steeringOverrideReason: z27.string().max(2e3).optional().describe(
9984
- "Typed override reason (>= 12 chars) to push a constellation past a coherency hold instead of acknowledging."
9985
- )
9843
+ import { z as z26 } from "zod/v3";
9844
+ var facilitateSchema = z26.object({
9845
+ betEntryId: z26.string().max(200).optional().describe("Work package entry ID. Required.")
9986
9846
  });
9987
- function conflictSuffix(c) {
9988
- const seat = c.routeTarget ? `; seat team ${c.routeTarget.teamEntryId} role ${c.routeTarget.roleEntryId}` : "";
9989
- return ` [${c.code}${seat}]`;
9990
- }
9991
9847
  function buildCortexUrl(workspaceSlug, entryId) {
9992
9848
  return `${appUrl()}/w/${workspaceSlug}/chain?entry=${encodeURIComponent(entryId)}&railTab=context`;
9993
9849
  }
@@ -10036,195 +9892,6 @@ async function handleResume(args) {
10036
9892
  }
10037
9893
  };
10038
9894
  }
10039
- async function handleCommitConstellation(args) {
10040
- requireWriteAccess();
10041
- const betId = args.betEntryId;
10042
- if (!betId) {
10043
- return validationResult("`betEntryId` is required for commit-constellation action.");
10044
- }
10045
- const { workspaceId } = await getWorkspaceContext();
10046
- const sessionId = getAgentSessionId();
10047
- const operationId = args.operationId ?? `${betId}:${sessionId ?? "sessionless"}:${Date.now()}`;
10048
- let betName = betId;
10049
- let betDesc = "";
10050
- let betCollectionHint;
10051
- try {
10052
- const betEnvelope = await kernelCallEnvelope("chain.getEntry", { entryId: betId });
10053
- const entry = betEnvelope.data;
10054
- if (entry) {
10055
- betName = entry.name ?? betId;
10056
- const d = entry.data ?? {};
10057
- const links = d["links"];
10058
- betDesc = d.problem ?? links?.problem ?? d.description ?? "";
10059
- betCollectionHint = entry.collectionSlug ?? entry.collection?.slug ?? entry.collection?.name;
10060
- }
10061
- } catch {
10062
- }
10063
- const preflight = await runConflictPreflight(betName, betDesc, betCollectionHint);
10064
- if (preflight.conflicts.length > 0) {
10065
- await recordSessionActivity({ contradictionWarning: true });
10066
- }
10067
- const conflictEvidence = preflight.conflicts.map((c) => ({
10068
- chainEntryId: c.chainEntryId,
10069
- chainEntryName: c.chainEntryName,
10070
- ...c.chainEntryDescription ? { chainEntryDescription: c.chainEntryDescription } : {},
10071
- type: c.type,
10072
- confidence: c.confidence,
10073
- explanation: c.explanation
10074
- }));
10075
- let envelope;
10076
- try {
10077
- envelope = await kernelCallEnvelope("agentKnowledge.facilitateEnvelope", {
10078
- workspaceId,
10079
- action: "commit-constellation",
10080
- betEntryId: betId,
10081
- operationId,
10082
- sessionId: sessionId ?? void 0,
10083
- author: sessionId ? `agent:${sessionId}` : "kernel:facilitate",
10084
- // WP-465 slice ⑤ (TEN-2439, §3.7): relay the coherency retry controls so a
10085
- // COHERENCY_REFUSED constellation hold is actually retryable through MCP.
10086
- ...args.coherencyAcknowledgements ? { coherencyAcknowledgements: args.coherencyAcknowledgements } : {},
10087
- ...args.steeringOverrideReason ? { steeringOverrideReason: args.steeringOverrideReason } : {},
10088
- ...conflictEvidence.length > 0 ? { conflicts: conflictEvidence } : {}
10089
- });
10090
- } catch (err) {
10091
- const msg = err instanceof Error ? err.message : String(err);
10092
- const code = err?.code;
10093
- const diagnostics = err?.diagnostics;
10094
- if (code === "COHERENCY_REFUSED") {
10095
- const coherencyRefusals = Array.isArray(diagnostics?.coherencyRefusals) ? diagnostics.coherencyRefusals : [];
10096
- const offenderLines = coherencyRefusals.map((r) => `- \`${r.entryId}\` ${r.name}: ${String(r.refusal?.reason ?? "coherency challenge unsatisfied")}`).join("\n");
10097
- const count = coherencyRefusals.length;
10098
- return {
10099
- content: [{
10100
- type: "text",
10101
- text: [
10102
- `# Constellation held by the coherency gate`,
10103
- "",
10104
- `\`${betId}\` was not accepted \u2014 ${count} entr${count === 1 ? "y" : "ies"} refused. Nothing was committed; drafts persist.`,
10105
- ...offenderLines ? ["", offenderLines] : []
10106
- ].join("\n")
10107
- }],
10108
- structuredContent: failure(
10109
- "COHERENCY_REFUSED",
10110
- `Constellation held: ${count} entr${count === 1 ? "y" : "ies"} refused by the coherency gate \u2014 nothing was committed, drafts persist.`,
10111
- "Respond per offender and retry commit-constellation: link the entry to the strategic spine, pass coherencyAcknowledgements [{subjectEntryId, response: 'linked' | 'accepted-fix' | 'diverged', entryId?, reason?}], or supply a typed steeringOverrideReason (at least 12 characters).",
10112
- [{ tool: "session", description: "Retry with coherency acknowledgements", parameters: { action: "commit-constellation", betEntryId: betId } }],
10113
- { coherencyRefusals }
10114
- )
10115
- };
10116
- }
10117
- if (code === "CONSTELLATION_COMMIT_REFUSED") {
10118
- const conflictIds = Array.isArray(diagnostics?.conflictIds) ? diagnostics.conflictIds : [];
10119
- const offenderLines = conflictIds.map((c) => `- \`${c.entryId}\` ${c.name}: ${c.reason}${conflictSuffix(c)}`).join("\n");
10120
- return {
10121
- content: [{
10122
- type: "text",
10123
- text: [
10124
- `# Constellation commit refused`,
10125
- "",
10126
- `\`${betId}\` was not accepted \u2014 the root itself was refused, so nothing was committed.`,
10127
- ...offenderLines ? ["", offenderLines] : []
10128
- ].join("\n")
10129
- }],
10130
- structuredContent: failure(
10131
- "CONSTELLATION_COMMIT_REFUSED",
10132
- msg,
10133
- "Resolve the authority conflict (route through the accountable role or Team Lead) and retry commit-constellation.",
10134
- [{ tool: "session", description: "Retry once authority is resolved", parameters: { action: "commit-constellation", betEntryId: betId } }],
10135
- { conflictIds }
10136
- )
10137
- };
10138
- }
10139
- if (code === "CONTRADICTION_BLOCKED") {
10140
- return {
10141
- content: [{
10142
- type: "text",
10143
- text: `# Constellation accept blocked
10144
-
10145
- \`${betId}\` was not accepted: ${msg}
10146
-
10147
- No constellation entries were accepted.`
10148
- }],
10149
- structuredContent: failure(
10150
- "CONTRADICTION_BLOCKED",
10151
- msg,
10152
- "Resolve the contradiction before retrying commit-constellation."
10153
- )
10154
- };
10155
- }
10156
- return {
10157
- content: [{
10158
- type: "text",
10159
- text: `# Work package accept failed
10160
-
10161
- \`${betId}\` could not be accepted: ${msg}
10162
-
10163
- No constellation entries were accepted.`
10164
- }],
10165
- structuredContent: failure(
10166
- "BACKEND_ERROR",
10167
- `Work package accept failed: ${msg}`,
10168
- "Retry or check for accept blockers.",
10169
- [{ tool: "session", description: "Resume session", parameters: { action: "resume", betEntryId: betId } }],
10170
- diagnostics
10171
- )
10172
- };
10173
- }
10174
- for (const docId of envelope.data?.result?.committedIds ?? []) {
10175
- try {
10176
- await recordSessionActivity({ entryModified: docId });
10177
- } catch {
10178
- }
10179
- }
10180
- const result2 = envelope.data.result;
10181
- const suggestions = {
10182
- ...preflight.conflicts.length > 0 ? { conflicts: preflight.conflicts } : {}
10183
- };
10184
- const lines = [];
10185
- const hasIssues = (result2.failedIds?.length ?? 0) > 0 || (result2.conflictIds?.length ?? 0) > 0;
10186
- lines.push(
10187
- hasIssues ? `# Accepted with issues` : `# Accepted`,
10188
- "",
10189
- `**${result2.committedIds?.length ?? 0} entries** accepted onto the Chain, **${result2.totalRelations} connections** preserved.`,
10190
- hasIssues ? `\`${betId}\` was partially accepted. Review conflicts/failed entries below before considering the constellation complete.` : `\`${betId}\` and its full constellation are now source of truth.`
10191
- );
10192
- if (preflight.conflicts.length > 0) {
10193
- lines.push(
10194
- "",
10195
- `\u26A0 **Semantic conflict preflight** (advisory):`,
10196
- ...preflight.conflicts.map((c) => `- \`${c.chainEntryId}\` ${c.chainEntryName}: ${c.explanation}`)
10197
- );
10198
- }
10199
- if ((result2.committedIds?.length ?? 0) > 0) {
10200
- lines.push("", `**Accepted:** ${result2.committedIds.join(", ")}`);
10201
- }
10202
- if ((result2.alreadyCommittedIds?.length ?? 0) > 0) {
10203
- lines.push("", `**Already accepted:** ${result2.alreadyCommittedIds.join(", ")}`);
10204
- }
10205
- if ((result2.conflictIds?.length ?? 0) > 0) {
10206
- lines.push("", `**${result2.conflictIds.length} conflicts:**`);
10207
- for (const c of result2.conflictIds) {
10208
- lines.push(`- \`${c.entryId}\` ${c.name}: ${c.reason}${conflictSuffix(c)}`);
10209
- }
10210
- }
10211
- if ((result2.failedIds?.length ?? 0) > 0) {
10212
- lines.push("", `**${result2.failedIds.length} failed:**`);
10213
- for (const f of result2.failedIds) {
10214
- lines.push(`- \`${f.entryId}\` ${f.name}: ${f.error}`);
10215
- }
10216
- }
10217
- return {
10218
- content: [{ type: "text", text: lines.join("\n") }],
10219
- structuredContent: {
10220
- ok: true,
10221
- summary: envelope.summary,
10222
- data: { result: result2, suggestions },
10223
- next: envelope.next,
10224
- _meta: envelope._meta
10225
- }
10226
- };
10227
- }
10228
9895
 
10229
9896
  // src/lib/sessionNotices.ts
10230
9897
  var ANSI_AND_CONTROL_RE2 = /\x1b\[[0-9;]*[A-Za-z]|\x1b\][^\x07]*\x07|\x1b[^[\]0-9;A-Za-z]?|[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g;
@@ -10240,14 +9907,8 @@ function nextActionForVerb(verb, args) {
10240
9907
  return { tool: "feedback", description: "Read the vendor triage queue (system admins only)", parameters: { action: "queue" } };
10241
9908
  case "question.create":
10242
9909
  return { tool: "question", description: "Create a routed question", parameters: { action: "create" } };
10243
- case "question.adopt":
10244
- return { tool: "question", description: "Attach routing to a captured tension", parameters: { action: "adopt" } };
10245
9910
  case "question.assign":
10246
9911
  return { tool: "question", description: "Confirm or reassign a question", parameters: { action: "assign" } };
10247
- case "question.snooze":
10248
- return { tool: "question", description: "Snooze a routed/escalated question", parameters: { action: "snooze" } };
10249
- case "question.decline":
10250
- return { tool: "question", description: "Pass on or decline a question", parameters: { action: "decline" } };
10251
9912
  case "question.answer":
10252
9913
  return { tool: "question", description: "Answer a question", parameters: { action: "answer" } };
10253
9914
  case "question.forceClose":
@@ -10274,8 +9935,6 @@ function displayVerbFromRoute(route) {
10274
9935
  switch (route) {
10275
9936
  case "question.assign":
10276
9937
  return "take it / reassign";
10277
- case "question.decline":
10278
- return "pass / decline";
10279
9938
  case "question.forceClose":
10280
9939
  return "force-close";
10281
9940
  default:
@@ -10317,78 +9976,52 @@ function formatNoticeLines(notices) {
10317
9976
 
10318
9977
  // src/tools/session.ts
10319
9978
  var START_PREFLIGHT_NEXT = 'Next: context action=preflight collection=<kind> links=[{"type":"part_of","entryId":"<PARENT-ID>"}]';
10320
- var SESSION_ACTIONS = [
10321
- "start",
10322
- "close",
10323
- "status",
10324
- "wrapup-review",
10325
- "wrapup-commit",
10326
- "resume",
10327
- "commit-constellation"
10328
- ];
10329
- var coherencyAcknowledgementFlatSchema2 = z28.object({
10330
- response: z28.string().max(200).describe("Acknowledgement response per offender: 'linked' | 'accepted-fix' | 'diverged'."),
10331
- entryId: z28.string().max(200).optional().describe("Entry the acknowledgement links to."),
10332
- reason: z28.string().max(2e3).optional().describe("Free-text justification, required for a 'diverged' response."),
10333
- subjectEntryId: z28.string().max(200).optional().describe("The refused entry this acknowledgement answers.")
10334
- });
9979
+ var SESSION_ACTIONS = ["start", "close", "status", "wrapup-review", "resume"];
9980
+ var SESSION_MOVED = {
9981
+ "wrapup-commit": "wrapup-commit was removed. Next: session action=wrapup-review, then entries action=accept entryId=... for each draft.",
9982
+ "commit-constellation": "commit-constellation was removed. Next: session action=wrapup-review, then entries action=accept entryId=... for each draft."
9983
+ };
10335
9984
  var TEAM_PARAM_DESCRIPTION = "For 'start': the team the role is held in, by its 'TEAM-<n>' id \u2014 only needed with role, when you hold that role in more than one team; a refusal that names the way in prints it.";
10336
- var sessionSchema = z28.object({
10337
- action: z28.enum(SESSION_ACTIONS).describe(
10338
- "'start': begin a tracked session. 'close': end the session and record activity. 'status': check current session state. 'wrapup-review': review uncommitted drafts before closing (absorbs session-wrapup action=review). 'wrapup-commit': accept all uncommitted drafts (absorbs session-wrapup action=commit-all). 'resume': load session state from an existing bet entry (absorbs facilitate action=resume). 'commit-constellation': atomically accept a bet and its linked drafts (absorbs facilitate action=commit-constellation)."
10339
- ),
10340
- betEntryId: z28.string().max(200).optional().describe("For 'resume'/'commit-constellation': bet entry ID. Required for both."),
10341
- operationId: z28.string().max(200).optional().describe("For 'commit-constellation': optional idempotency key for retries."),
10342
- coherencyAcknowledgements: z28.array(coherencyAcknowledgementFlatSchema2).max(20).optional().describe(
10343
- "For 'commit-constellation': per-offender acknowledgements to retry a constellation held under standard/strict coherency mode."
10344
- ),
10345
- steeringOverrideReason: z28.string().max(2e3).optional().describe(
10346
- "For 'commit-constellation': typed override reason (>= 12 chars) to push past a coherency hold instead of acknowledging."
9985
+ var sessionSchema = z27.object({
9986
+ action: actionEnum(SESSION_ACTIONS, SESSION_MOVED).describe(
9987
+ "'start': begin a tracked session. 'close': end the session and record activity. 'status': check current session state. 'wrapup-review': list this session's drafts before closing. 'resume': load session state from an existing work package entry."
10347
9988
  ),
9989
+ betEntryId: z27.string().max(200).optional().describe("For 'resume': work package entry ID. Required."),
10348
9990
  // DEC-1715 (WP-753 O1a)
10349
- role: z28.string().max(200).optional().describe(
9991
+ role: z27.string().max(200).optional().describe(
10350
9992
  "For 'start': role to act as this session, by the '<PREFIX>-<n>' id a start reply prints beside the role name \u2014 only needed if you hold more than one; the error lists your roles if omitted."
10351
9993
  ),
10352
- team: z28.string().max(200).optional().describe(TEAM_PARAM_DESCRIPTION)
9994
+ team: z27.string().max(200).optional().describe(TEAM_PARAM_DESCRIPTION)
10353
9995
  // TASK-801
10354
9996
  });
10355
- var sessionStartVariant = z28.object({
10356
- action: z28.literal("start"),
9997
+ var sessionStartVariant = z27.object({
9998
+ action: z27.literal("start"),
10357
9999
  // DEC-1715 (WP-753 O1a): the role to act as this session — only needed when the person holds
10358
10000
  // more than one role; the server refuses and lists the choices when it's required and omitted.
10359
- role: z28.string().max(200).optional().describe(
10001
+ role: z27.string().max(200).optional().describe(
10360
10002
  "Role to act as this session, by the '<PREFIX>-<n>' id a start reply prints beside the role name \u2014 only needed if you hold more than one; the error lists your roles if omitted."
10361
10003
  ),
10362
- team: z28.string().max(200).optional().describe(TEAM_PARAM_DESCRIPTION)
10004
+ team: z27.string().max(200).optional().describe(TEAM_PARAM_DESCRIPTION)
10363
10005
  // TASK-801
10364
10006
  });
10365
- var sessionCloseVariant = z28.object({ action: z28.literal("close") });
10366
- var sessionStatusVariant = z28.object({ action: z28.literal("status") });
10367
- var sessionWrapupReviewVariant = z28.object({ action: z28.literal("wrapup-review") });
10368
- var sessionWrapupCommitVariant = z28.object({ action: z28.literal("wrapup-commit") });
10369
- var sessionResumeVariant = facilitateSchema.omit({ action: true }).extend({ action: z28.literal("resume") });
10370
- var sessionCommitConstellationVariant = facilitateSchema.omit({ action: true }).extend({ action: z28.literal("commit-constellation") });
10371
- var sessionActionUnion = z28.discriminatedUnion("action", [
10007
+ var sessionCloseVariant = z27.object({ action: z27.literal("close") });
10008
+ var sessionStatusVariant = z27.object({ action: z27.literal("status") });
10009
+ var sessionWrapupReviewVariant = z27.object({ action: z27.literal("wrapup-review") });
10010
+ var sessionResumeVariant = facilitateSchema.extend({ action: z27.literal("resume") });
10011
+ var sessionActionUnion = z27.discriminatedUnion("action", [
10372
10012
  sessionStartVariant,
10373
10013
  sessionCloseVariant,
10374
10014
  sessionStatusVariant,
10375
10015
  sessionWrapupReviewVariant,
10376
- sessionWrapupCommitVariant,
10377
- sessionResumeVariant,
10378
- sessionCommitConstellationVariant
10016
+ sessionResumeVariant
10379
10017
  ]);
10380
10018
  var SESSION_ACTION_SPECS = {
10381
10019
  // DEC-1715 (WP-753 O1a), TASK-801
10382
10020
  start: { params: ["role", "team"], description: "role is optional \u2014 only needed if you hold more than one role; team only with role, when you hold it in several teams." },
10383
10021
  close: { params: [], description: "End the current session; no params." },
10384
10022
  status: { params: [], description: "Check current session state; no params." },
10385
- "wrapup-review": { params: [], description: "Review uncommitted drafts; no params." },
10386
- "wrapup-commit": { params: [], description: "Accept all uncommitted drafts; no params." },
10387
- resume: { params: ["betEntryId"], description: "betEntryId is required." },
10388
- "commit-constellation": {
10389
- params: ["betEntryId", "operationId", "coherencyAcknowledgements", "steeringOverrideReason"],
10390
- description: "betEntryId is required; every other field is optional."
10391
- }
10023
+ "wrapup-review": { params: [], description: "List this session's drafts; no params." },
10024
+ resume: { params: ["betEntryId"], description: "betEntryId is required." }
10392
10025
  };
10393
10026
  function registerSessionTools(server) {
10394
10027
  const wrapupHandler = createWrapupHandler();
@@ -10396,10 +10029,8 @@ function registerSessionTools(server) {
10396
10029
  start: (data) => handleStart2(data),
10397
10030
  close: () => handleClose(),
10398
10031
  status: () => handleStatus(),
10399
- "wrapup-review": () => wrapupHandler({ action: "review" }),
10400
- "wrapup-commit": () => wrapupHandler({ action: "commit-all" }),
10401
- resume: (data) => handleResume(data),
10402
- "commit-constellation": (data) => handleCommitConstellation(data)
10032
+ "wrapup-review": () => wrapupHandler(),
10033
+ resume: (data) => handleResume(data)
10403
10034
  };
10404
10035
  server.registerTool(
10405
10036
  "session",
@@ -10409,15 +10040,13 @@ function registerSessionTools(server) {
10409
10040
 
10410
10041
  Session lifecycle, wrapup review, and work package facilitation.
10411
10042
 
10412
- - **start**: Begin a tracked write session for attribution. **This is the ONLY call that creates a session** \u2014 write tools (capture, entries action=update/commit, relations) require it. Its reply is the briefing; then \`orient task="<what you are doing>"\` loads the context for a task.
10043
+ - **start**: Begin a tracked write session for attribution. **This is the ONLY call that creates a session** \u2014 write tools (capture, entries action=update/accept, relations) require it. Its reply is the briefing; then \`orient task="<what you are doing>"\` loads the context for a task.
10413
10044
  - **close**: End the current session. Records structured data (entries created, modified, relations). Run \`session action=wrapup-review\` before closing.
10414
10045
  - **status**: Check current session \u2014 active or not, oriented, activity counts.
10415
- - **wrapup-review**: Review uncommitted drafts with quality scores. Run before close.
10416
- - **wrapup-commit**: Accept all uncommitted drafts. Writes no relations; create the ones you want with relations action=create.
10417
- - **resume**: Load session state (work package data, constellation, drafts) from an existing work package entry.
10418
- - **commit-constellation**: Atomically accept a work package and all its linked draft entries in one call.`,
10046
+ - **wrapup-review**: List this session's drafts with quality scores; accept each with entries action=accept. Run before close.
10047
+ - **resume**: Load session state (work package data, linked entries, drafts) from an existing work package entry.`,
10419
10048
  inputSchema: sessionSchema,
10420
- // Mixed read/write noun (§3 R3): wrapup-commit/resume/commit-constellation write.
10049
+ // Mixed read/write noun (§3 R3): start and close write.
10421
10050
  annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false }
10422
10051
  },
10423
10052
  thinWrapper(async (args) => {
@@ -10502,7 +10131,7 @@ async function handleClose() {
10502
10131
  "",
10503
10132
  text,
10504
10133
  "",
10505
- `> **${data.drafts.length} uncommitted draft(s) remain.** Run \`session action=wrapup-commit\` before closing next time.`,
10134
+ `> **${data.drafts.length} draft(s) not yet accepted.** Accept each with \`entries action=accept\` before closing next time.`,
10506
10135
  "",
10507
10136
  "---",
10508
10137
  ""
@@ -10619,10 +10248,10 @@ async function handleStatus() {
10619
10248
  }
10620
10249
 
10621
10250
  // src/tools/workspace.ts
10622
- import { z as z31 } from "zod/v3";
10251
+ import { z as z30 } from "zod/v3";
10623
10252
 
10624
10253
  // src/tools/health.ts
10625
- import { z as z29 } from "zod/v3";
10254
+ import { z as z28 } from "zod/v3";
10626
10255
 
10627
10256
  // src/lib/auditView.ts
10628
10257
  async function buildTenantAuditView(limit) {
@@ -10891,7 +10520,7 @@ async function handleWorkspaceStatus() {
10891
10520
  `- **Entries:** ${stats.totalEntries} (${stats.activeCount} accepted/active, ${stats.draftCount} draft)`,
10892
10521
  `- **Relations:** ${stats.totalRelations}`,
10893
10522
  `- **Collections:** ${stats.collectionCount}`,
10894
- `- **Orphaned:** ${stats.orphanedCount} committed entries with no relations`,
10523
+ `- **Orphaned:** ${stats.orphanedCount} accepted entries with no relations`,
10895
10524
  ""
10896
10525
  ];
10897
10526
  if (gaps.length > 0 && !result2.sampleTruncated) {
@@ -10968,60 +10597,60 @@ ${logLines.join("\n")}${seamSummaryText}` }],
10968
10597
  };
10969
10598
  }
10970
10599
  var HEALTH_ACTIONS = ["check", "whoami", "status", "audit", "self-test"];
10971
- var healthSchema = z29.object({
10972
- action: z29.enum(HEALTH_ACTIONS).describe(
10600
+ var healthSchema = z28.object({
10601
+ action: z28.enum(HEALTH_ACTIONS).describe(
10973
10602
  "'check': connectivity and workspace stats. 'whoami': session identity. 'status': workspace readiness. 'audit': session audit log. 'self-test': validate all tool schemas."
10974
10603
  ),
10975
- limit: z29.number().min(1).max(50).default(20).optional().describe("For audit: how many recent calls to show (max 50)")
10604
+ limit: z28.number().min(1).max(50).default(20).optional().describe("For audit: how many recent calls to show (max 50)")
10976
10605
  });
10977
- var healthCheckOutputSchema = z29.object({
10978
- healthy: z29.boolean(),
10979
- collections: z29.number(),
10980
- entries: z29.number(),
10981
- latencyMs: z29.number(),
10982
- workspace: z29.string()
10606
+ var healthCheckOutputSchema = z28.object({
10607
+ healthy: z28.boolean(),
10608
+ collections: z28.number(),
10609
+ entries: z28.number(),
10610
+ latencyMs: z28.number(),
10611
+ workspace: z28.string()
10983
10612
  });
10984
- var organisationHealthSchema = z29.object({
10985
- reviewed: z29.number(),
10986
- agreements: z29.number(),
10987
- disagreements: z29.number(),
10988
- abstentions: z29.number(),
10989
- agreementRate: z29.number(),
10990
- flags: z29.array(z29.object({ collection: z29.string(), count: z29.number(), suggestedCollection: z29.string() }))
10613
+ var organisationHealthSchema = z28.object({
10614
+ reviewed: z28.number(),
10615
+ agreements: z28.number(),
10616
+ disagreements: z28.number(),
10617
+ abstentions: z28.number(),
10618
+ agreementRate: z28.number(),
10619
+ flags: z28.array(z28.object({ collection: z28.string(), count: z28.number(), suggestedCollection: z28.string() }))
10991
10620
  });
10992
- var healthStatusOutputSchema = z29.object({
10993
- sampleTruncated: z29.boolean().nullable().optional(),
10994
- activeEntries: z29.number(),
10995
- totalRelations: z29.number(),
10996
- orphanedEntries: z29.number(),
10997
- checks: z29.array(z29.object({ label: z29.string(), passed: z29.boolean(), current: z29.number(), required: z29.number() })),
10998
- gaps: z29.array(z29.object({ id: z29.string(), label: z29.string(), guidance: z29.string() })),
10621
+ var healthStatusOutputSchema = z28.object({
10622
+ sampleTruncated: z28.boolean().nullable().optional(),
10623
+ activeEntries: z28.number(),
10624
+ totalRelations: z28.number(),
10625
+ orphanedEntries: z28.number(),
10626
+ checks: z28.array(z28.object({ label: z28.string(), passed: z28.boolean(), current: z28.number(), required: z28.number() })),
10627
+ gaps: z28.array(z28.object({ id: z28.string(), label: z28.string(), guidance: z28.string() })),
10999
10628
  organisationHealth: organisationHealthSchema.optional()
11000
10629
  });
11001
- var healthAuditOutputSchema = z29.object({
11002
- totalCalls: z29.number(),
11003
- calls: z29.array(z29.object({
11004
- tool: z29.string(),
11005
- action: z29.string().optional(),
11006
- timestamp: z29.string(),
11007
- durationMs: z29.number().optional()
10630
+ var healthAuditOutputSchema = z28.object({
10631
+ totalCalls: z28.number(),
10632
+ calls: z28.array(z28.object({
10633
+ tool: z28.string(),
10634
+ action: z28.string().optional(),
10635
+ timestamp: z28.string(),
10636
+ durationMs: z28.number().optional()
11008
10637
  }))
11009
10638
  });
11010
- var healthWhoamiOutputSchema = z29.object({
11011
- workspaceId: z29.string(),
11012
- workspaceName: z29.string(),
11013
- scope: z29.string(),
11014
- sessionId: z29.union([z29.string(), z29.null()]),
11015
- oriented: z29.boolean()
10639
+ var healthWhoamiOutputSchema = z28.object({
10640
+ workspaceId: z28.string(),
10641
+ workspaceName: z28.string(),
10642
+ scope: z28.string(),
10643
+ sessionId: z28.union([z28.string(), z28.null()]),
10644
+ oriented: z28.boolean()
11016
10645
  });
11017
- var selfTestOutputSchema = z29.object({
11018
- passed: z29.number(),
11019
- failed: z29.number(),
11020
- total: z29.number(),
11021
- results: z29.array(z29.object({
11022
- tool: z29.string(),
11023
- valid: z29.boolean(),
11024
- error: z29.string().optional()
10646
+ var selfTestOutputSchema = z28.object({
10647
+ passed: z28.number(),
10648
+ failed: z28.number(),
10649
+ total: z28.number(),
10650
+ results: z28.array(z28.object({
10651
+ tool: z28.string(),
10652
+ valid: z28.boolean(),
10653
+ error: z28.string().optional()
11025
10654
  }))
11026
10655
  });
11027
10656
  function handleSelfTest(server) {
@@ -11072,9 +10701,9 @@ function handleSelfTest(server) {
11072
10701
  }
11073
10702
 
11074
10703
  // src/tools/usage.ts
11075
- import { z as z30 } from "zod/v3";
11076
- var usageSummarySchema = z30.object({
11077
- periodDays: z30.number().min(1).max(90).optional().describe("Number of days to look back (default 30, max 90)")
10704
+ import { z as z29 } from "zod/v3";
10705
+ var usageSummarySchema = z29.object({
10706
+ periodDays: z29.number().min(1).max(90).optional().describe("Number of days to look back (default 30, max 90)")
11078
10707
  });
11079
10708
  async function handleUsageSummary(periodDays) {
11080
10709
  const ws = await getWorkspaceContext();
@@ -11144,20 +10773,20 @@ var WORKSPACE_ACTIONS = [
11144
10773
  "self-test",
11145
10774
  "usage"
11146
10775
  ];
11147
- var workspaceSchema = z31.object({
11148
- action: z31.enum(WORKSPACE_ACTIONS).describe(
11149
- "'check': connectivity and workspace stats (absorbs health action=check). 'whoami': session identity (absorbs health action=whoami). 'status': workspace readiness (absorbs health action=status). 'audit': session audit log (absorbs health action=audit). 'self-test': validate all tool schemas (absorbs health action=self-test). 'usage': LLM usage and cost summary (absorbs get-usage-summary)."
10776
+ var workspaceSchema = z30.object({
10777
+ action: z30.enum(WORKSPACE_ACTIONS).describe(
10778
+ "'check': connectivity and workspace stats. 'whoami': session identity. 'status': workspace readiness. 'audit': session audit log. 'self-test': validate all tool schemas. 'usage': LLM usage and cost summary."
11150
10779
  ),
11151
- limit: z31.number().min(1).max(50).optional().describe("For 'audit': how many recent calls to show (max 50, default 20)."),
11152
- periodDays: z31.number().min(1).max(90).optional().describe("For 'usage': number of days to look back (default 30, max 90).")
10780
+ limit: z30.number().min(1).max(50).optional().describe("For 'audit': how many recent calls to show (max 50, default 20)."),
10781
+ periodDays: z30.number().min(1).max(90).optional().describe("For 'usage': number of days to look back (default 30, max 90).")
11153
10782
  });
11154
- var workspaceCheckVariant = z31.object({ action: z31.literal("check") });
11155
- var workspaceWhoamiVariant = z31.object({ action: z31.literal("whoami") });
11156
- var workspaceStatusVariant = z31.object({ action: z31.literal("status") });
11157
- var workspaceAuditVariant = z31.object({ action: z31.literal("audit"), limit: z31.number().min(1).max(50).optional().default(20) });
11158
- var workspaceSelfTestVariant = z31.object({ action: z31.literal("self-test") });
11159
- var workspaceUsageVariant = z31.object({ action: z31.literal("usage"), periodDays: z31.number().min(1).max(90).optional() });
11160
- var workspaceActionUnion = z31.discriminatedUnion("action", [
10783
+ var workspaceCheckVariant = z30.object({ action: z30.literal("check") });
10784
+ var workspaceWhoamiVariant = z30.object({ action: z30.literal("whoami") });
10785
+ var workspaceStatusVariant = z30.object({ action: z30.literal("status") });
10786
+ var workspaceAuditVariant = z30.object({ action: z30.literal("audit"), limit: z30.number().min(1).max(50).optional().default(20) });
10787
+ var workspaceSelfTestVariant = z30.object({ action: z30.literal("self-test") });
10788
+ var workspaceUsageVariant = z30.object({ action: z30.literal("usage"), periodDays: z30.number().min(1).max(90).optional() });
10789
+ var workspaceActionUnion = z30.discriminatedUnion("action", [
11161
10790
  workspaceCheckVariant,
11162
10791
  workspaceWhoamiVariant,
11163
10792
  workspaceStatusVariant,
@@ -11186,7 +10815,7 @@ function registerWorkspaceTools(server) {
11186
10815
  "workspace",
11187
10816
  {
11188
10817
  title: "Workspace",
11189
- description: "Diagnostics, session identity, and usage for the current workspace. Six actions:\n\n- **check**: Verify connectivity \u2014 workspace, collections, entries, latency.\n- **whoami**: Session identity \u2014 workspace ID, slug, name.\n- **status**: Workspace readiness \u2014 checks (pass/fail), gaps, stats (entries, relations, orphans).\n- **audit**: Session audit log \u2014 last N backend calls with summary.\n- **self-test**: Validate all registered tool schemas.\n- **usage**: LLM usage and cost summary \u2014 spend, tokens, model/feature breakdown (absorbs `get-usage-summary`).",
10818
+ description: "Diagnostics, session identity, and usage for the current workspace. Six actions:\n\n- **check**: Verify connectivity \u2014 workspace, collections, entries, latency.\n- **whoami**: Session identity \u2014 workspace ID, slug, name.\n- **status**: Workspace readiness \u2014 checks (pass/fail), gaps, stats (entries, relations, orphans).\n- **audit**: Session audit log \u2014 last N backend calls with summary.\n- **self-test**: Validate all registered tool schemas.\n- **usage**: LLM usage and cost summary \u2014 spend, tokens, model/feature breakdown.",
11190
10819
  inputSchema: workspaceSchema,
11191
10820
  annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false }
11192
10821
  },
@@ -11203,7 +10832,7 @@ function registerWorkspaceTools(server) {
11203
10832
  }
11204
10833
 
11205
10834
  // src/tools/feedback.ts
11206
- import { z as z32 } from "zod/v3";
10835
+ import { z as z31 } from "zod/v3";
11207
10836
 
11208
10837
  // src/lib/productFeedbackConstants.ts
11209
10838
  var PRODUCT_FEEDBACK_CATEGORIES = ["bug", "friction", "idea", "praise", "other"];
@@ -11216,41 +10845,41 @@ var MAX_FEEDBACK_ANSWER_LENGTH = 240;
11216
10845
 
11217
10846
  // src/tools/feedback.ts
11218
10847
  var actions = ["submit", "list", "queue", "note", "group", "status"];
11219
- var category = z32.enum(PRODUCT_FEEDBACK_CATEGORIES);
11220
- var status = z32.enum(PRODUCT_FEEDBACK_STATUSES);
11221
- var vendorStatus = z32.enum(VENDOR_SETTABLE_STATUSES);
11222
- var tensionId = z32.string().regex(FEEDBACK_TENSION_ID_PATTERN);
11223
- var answer = z32.string().trim().min(1).max(MAX_FEEDBACK_ANSWER_LENGTH);
10848
+ var category = z31.enum(PRODUCT_FEEDBACK_CATEGORIES);
10849
+ var status = z31.enum(PRODUCT_FEEDBACK_STATUSES);
10850
+ var vendorStatus = z31.enum(VENDOR_SETTABLE_STATUSES);
10851
+ var tensionId = z31.string().regex(FEEDBACK_TENSION_ID_PATTERN);
10852
+ var answer = z31.string().trim().min(1).max(MAX_FEEDBACK_ANSWER_LENGTH);
11224
10853
  var MESSAGE_DISPLAY_LIMIT = 1e3;
11225
10854
  var FULL_MESSAGE_MAX_LIMIT = 5;
11226
- var feedbackSchema = z32.object({
11227
- action: z32.enum(actions).describe("submit requires message; list returns your own workspace's feedback (all statuses); queue is the vendor triage queue (system admins only) and accepts filters; note requires feedbackId+note; group requires feedbackIds+groupId (null clears); status requires feedbackId+status and may carry tensionId and answer."),
11228
- message: z32.string().max(1e4).optional().describe("Required for submit: the product feedback text (max 10,000 characters)."),
10855
+ var feedbackSchema = z31.object({
10856
+ action: z31.enum(actions).describe("submit requires message; list returns your own workspace's feedback (all statuses); queue is the vendor triage queue (system admins only) and accepts filters; note requires feedbackId+note; group requires feedbackIds+groupId (null clears); status requires feedbackId+status and may carry tensionId and answer."),
10857
+ message: z31.string().max(1e4).optional().describe("Required for submit: the product feedback text (max 10,000 characters)."),
11229
10858
  category: category.optional().describe("Submit/queue category; submit defaults to other."),
11230
- command: z32.string().max(1e3).optional().describe("Optional submit command context; argument values are scrubbed server-side."),
11231
- route: z32.string().max(500).optional().describe("Optional submit route context."),
11232
- client: z32.string().max(100).optional().describe("Optional submit client label."),
11233
- feedbackId: z32.string().max(200).optional().describe("Required for note/status: target feedback ID."),
11234
- feedbackIds: z32.array(z32.string().max(200)).max(100).optional().describe("Required for group: 1\u2013100 target feedback IDs."),
11235
- note: z32.string().max(4e3).optional().describe("Required for note: replacement triage note (max 4,000 characters)."),
10859
+ command: z31.string().max(1e3).optional().describe("Optional submit command context; argument values are scrubbed server-side."),
10860
+ route: z31.string().max(500).optional().describe("Optional submit route context."),
10861
+ client: z31.string().max(100).optional().describe("Optional submit client label."),
10862
+ feedbackId: z31.string().max(200).optional().describe("Required for note/status: target feedback ID."),
10863
+ feedbackIds: z31.array(z31.string().max(200)).max(100).optional().describe("Required for group: 1\u2013100 target feedback IDs."),
10864
+ note: z31.string().max(4e3).optional().describe("Required for note: replacement triage note (max 4,000 characters)."),
11236
10865
  status: status.optional().describe("list/queue filter (any status, including 'screening'); the status action's required target value excludes 'screening' (system-only)."),
11237
10866
  tensionId: tensionId.optional().describe("status only: the tension the report joined, its display id TEN- and a number (vendor-only, never shown to the reporter)."),
11238
10867
  answer: answer.optional().describe(`status only: the one sentence the reporter reads under their report, dated (max ${MAX_FEEDBACK_ANSWER_LENGTH} characters).`),
11239
- groupId: z32.string().min(1).max(200).nullable().optional().describe("Group filter, or required group destination; null explicitly clears grouping."),
11240
- workspaceId: z32.string().max(200).optional().describe("Queue-only filter (vendor cross-workspace triage); omitted means all workspaces. Has no effect on list \u2014 your own workspace is always injected server-side."),
11241
- since: z32.number().optional().describe("Queue-only lower createdAt window bound (inclusive) in epoch milliseconds."),
11242
- before: z32.number().optional().describe("Queue-only upper createdAt window bound (exclusive) in epoch milliseconds. A time-window FILTER, not the pager \u2014 use cursor to page."),
11243
- limit: z32.number().int().min(1).max(100).optional().describe("list/queue row limit, default 50, maximum 100."),
11244
- cursor: z32.string().max(2e3).optional().describe("Opaque pagination cursor from a previous list/queue response (continueCursor); omit for the first page."),
11245
- full: z32.boolean().optional().describe(`list/queue only: return untruncated messages; allowed only when limit <= ${FULL_MESSAGE_MAX_LIMIT}.`)
10868
+ groupId: z31.string().min(1).max(200).nullable().optional().describe("Group filter, or required group destination; null explicitly clears grouping."),
10869
+ workspaceId: z31.string().max(200).optional().describe("Queue-only filter (vendor cross-workspace triage); omitted means all workspaces. Has no effect on list \u2014 your own workspace is always injected server-side."),
10870
+ since: z31.number().optional().describe("Queue-only lower createdAt window bound (inclusive) in epoch milliseconds."),
10871
+ before: z31.number().optional().describe("Queue-only upper createdAt window bound (exclusive) in epoch milliseconds. A time-window FILTER, not the pager \u2014 use cursor to page."),
10872
+ limit: z31.number().int().min(1).max(100).optional().describe("list/queue row limit, default 50, maximum 100."),
10873
+ cursor: z31.string().max(2e3).optional().describe("Opaque pagination cursor from a previous list/queue response (continueCursor); omit for the first page."),
10874
+ full: z31.boolean().optional().describe(`list/queue only: return untruncated messages; allowed only when limit <= ${FULL_MESSAGE_MAX_LIMIT}.`)
11246
10875
  });
11247
- var union = z32.discriminatedUnion("action", [
11248
- z32.object({ action: z32.literal("submit"), message: z32.string().min(1).max(1e4), category: category.optional(), command: z32.string().max(1e3).optional(), route: z32.string().max(500).optional(), client: z32.string().max(100).optional() }),
11249
- z32.object({ action: z32.literal("list"), status: status.optional(), limit: z32.number().int().min(1).max(100).optional(), cursor: z32.string().max(2e3).optional(), full: z32.boolean().optional() }),
11250
- z32.object({ action: z32.literal("queue"), status: status.optional(), category: category.optional(), groupId: z32.string().min(1).max(200).optional(), workspaceId: z32.string().max(200).optional(), since: z32.number().optional(), before: z32.number().optional(), limit: z32.number().int().min(1).max(100).optional(), cursor: z32.string().max(2e3).optional(), full: z32.boolean().optional() }),
11251
- z32.object({ action: z32.literal("note"), feedbackId: z32.string().min(1).max(200), note: z32.string().max(4e3) }),
11252
- z32.object({ action: z32.literal("group"), feedbackIds: z32.array(z32.string().min(1).max(200)).min(1).max(100), groupId: z32.string().min(1).max(200).nullable() }),
11253
- z32.object({ action: z32.literal("status"), feedbackId: z32.string().min(1).max(200), status: vendorStatus, tensionId: tensionId.optional(), answer: answer.optional() })
10876
+ var union = z31.discriminatedUnion("action", [
10877
+ z31.object({ action: z31.literal("submit"), message: z31.string().min(1).max(1e4), category: category.optional(), command: z31.string().max(1e3).optional(), route: z31.string().max(500).optional(), client: z31.string().max(100).optional() }),
10878
+ z31.object({ action: z31.literal("list"), status: status.optional(), limit: z31.number().int().min(1).max(100).optional(), cursor: z31.string().max(2e3).optional(), full: z31.boolean().optional() }),
10879
+ z31.object({ action: z31.literal("queue"), status: status.optional(), category: category.optional(), groupId: z31.string().min(1).max(200).optional(), workspaceId: z31.string().max(200).optional(), since: z31.number().optional(), before: z31.number().optional(), limit: z31.number().int().min(1).max(100).optional(), cursor: z31.string().max(2e3).optional(), full: z31.boolean().optional() }),
10880
+ z31.object({ action: z31.literal("note"), feedbackId: z31.string().min(1).max(200), note: z31.string().max(4e3) }),
10881
+ z31.object({ action: z31.literal("group"), feedbackIds: z31.array(z31.string().min(1).max(200)).min(1).max(100), groupId: z31.string().min(1).max(200).nullable() }),
10882
+ z31.object({ action: z31.literal("status"), feedbackId: z31.string().min(1).max(200), status: vendorStatus, tensionId: tensionId.optional(), answer: answer.optional() })
11254
10883
  ]);
11255
10884
  var specs = {
11256
10885
  submit: { params: ["message", "category", "command", "route", "client"], description: "message is required; category defaults to other." },
@@ -11379,19 +11008,19 @@ function registerFeedbackTool(server) {
11379
11008
  }
11380
11009
 
11381
11010
  // src/tools/conflicts.ts
11382
- import { z as z33 } from "zod/v3";
11011
+ import { z as z32 } from "zod/v3";
11383
11012
  var ACTIONS = ["list", "resolve"];
11384
- var mode = z33.enum(["actionable", "all"]);
11385
- var verdict = z33.enum(["real", "noise"]);
11386
- var conflictsSchema = z33.object({
11387
- action: z33.enum(ACTIONS),
11013
+ var mode = z32.enum(["actionable", "all"]);
11014
+ var verdict = z32.enum(["real", "noise"]);
11015
+ var conflictsSchema = z32.object({
11016
+ action: z32.enum(ACTIONS),
11388
11017
  mode: mode.optional().describe("list: all adds judged and snoozed rows."),
11389
- issueId: z33.string().max(200).optional().describe("resolve: an id from list."),
11018
+ issueId: z32.string().max(200).optional().describe("resolve: an id from list."),
11390
11019
  verdict: verdict.optional().describe("resolve: real keeps the row open; noise closes it.")
11391
11020
  });
11392
- var conflictsActionUnion = z33.discriminatedUnion("action", [
11393
- z33.object({ action: z33.literal("list"), mode: mode.optional() }),
11394
- z33.object({ action: z33.literal("resolve"), issueId: z33.string().min(1).max(200), verdict })
11021
+ var conflictsActionUnion = z32.discriminatedUnion("action", [
11022
+ z32.object({ action: z32.literal("list"), mode: mode.optional() }),
11023
+ z32.object({ action: z32.literal("resolve"), issueId: z32.string().min(1).max(200), verdict })
11395
11024
  ]);
11396
11025
  var CONFLICTS_ACTION_SPECS = {
11397
11026
  list: { params: ["mode"], description: "mode defaults to actionable." },
@@ -11434,26 +11063,26 @@ function registerConflictsTool(server) {
11434
11063
  }
11435
11064
 
11436
11065
  // src/tools/question.ts
11437
- import { z as z34 } from "zod/v3";
11066
+ import { z as z33 } from "zod/v3";
11438
11067
  var QUESTION_ACTIONS = ["create", "assign", "answer", "force-close", "list"];
11439
- var questionSchema = z34.object({
11440
- action: z34.enum(QUESTION_ACTIONS).describe(
11068
+ var questionSchema = z33.object({
11069
+ action: z33.enum(QUESTION_ACTIONS).describe(
11441
11070
  "'create': create a new routed question from text \u2014 the dedicated birth action; every question is born escalated to the team lead (generic entry creation and move-and-retype also pair a routing facet). 'assign': reassign ownership to a role (toRole required \u2014 no bare self-confirm, no toPerson). 'answer': close the loop \u2014 writes the answer on the question and moves it to answered; --entry links an existing decision instead. 'force-close': Team-Lead-only escape hatch \u2014 reason required. 'list': the ack-gate read model \u2014 what you owe (or, with mine:true, every question you asked, including closed ones)."
11442
11071
  ),
11443
- entryId: z34.string().max(200).optional().describe("Target question's id (human TEN-nnn form or a raw entry id). Required for every action except 'create'/'list'."),
11444
- text: z34.string().max(5e3).optional().describe("'create': the question text. 'answer': the answer text (mutually exclusive with answerEntryId, max 2000 chars)."),
11445
- blocks: z34.array(z34.string().max(200)).max(50).optional().describe("'create': entry ids this question is blocking (repeatable)."),
11446
- toRole: z34.string().max(200).optional().describe("'assign': reassign to this role (human ROL-nnn form or a raw entry id) \u2014 required."),
11447
- reason: z34.string().max(2e3).optional().describe("'force-close': required reason."),
11448
- answerEntryId: z34.string().max(200).optional().describe("'answer': point at an already-written entry instead of supplying text (mutually exclusive with text)."),
11449
- mine: z34.boolean().optional().describe("'list': true for arm C (every question YOU asked, every status). Omit/false for the ack-gate view (what you owe).")
11072
+ entryId: z33.string().max(200).optional().describe("Target question's id (human TEN-nnn form or a raw entry id). Required for every action except 'create'/'list'."),
11073
+ text: z33.string().max(5e3).optional().describe("'create': the question text. 'answer': the answer text (mutually exclusive with answerEntryId, max 2000 chars)."),
11074
+ blocks: z33.array(z33.string().max(200)).max(50).optional().describe("'create': entry ids this question is blocking (repeatable)."),
11075
+ toRole: z33.string().max(200).optional().describe("'assign': reassign to this role (human ROL-nnn form or a raw entry id) \u2014 required."),
11076
+ reason: z33.string().max(2e3).optional().describe("'force-close': required reason."),
11077
+ answerEntryId: z33.string().max(200).optional().describe("'answer': point at an already-written entry instead of supplying text (mutually exclusive with text)."),
11078
+ mine: z33.boolean().optional().describe("'list': true for arm C (every question YOU asked, every status). Omit/false for the ack-gate view (what you owe).")
11450
11079
  });
11451
- var createVariant = z34.object({ action: z34.literal("create"), text: z34.string().min(1).max(5e3), blocks: z34.array(z34.string().max(200)).max(50).optional() });
11452
- var assignVariant = z34.object({ action: z34.literal("assign"), entryId: z34.string().max(200), toRole: z34.string().max(200).min(1) });
11453
- var answerVariant = z34.object({ action: z34.literal("answer"), entryId: z34.string().max(200), text: z34.string().max(2e3).optional(), answerEntryId: z34.string().max(200).optional() });
11454
- var forceCloseVariant = z34.object({ action: z34.literal("force-close"), entryId: z34.string().max(200), reason: z34.string().min(1).max(2e3) });
11455
- var listVariant = z34.object({ action: z34.literal("list"), mine: z34.boolean().optional() });
11456
- var questionActionUnion = z34.discriminatedUnion("action", [
11080
+ var createVariant = z33.object({ action: z33.literal("create"), text: z33.string().min(1).max(5e3), blocks: z33.array(z33.string().max(200)).max(50).optional() });
11081
+ var assignVariant = z33.object({ action: z33.literal("assign"), entryId: z33.string().max(200), toRole: z33.string().max(200).min(1) });
11082
+ var answerVariant = z33.object({ action: z33.literal("answer"), entryId: z33.string().max(200), text: z33.string().max(2e3).optional(), answerEntryId: z33.string().max(200).optional() });
11083
+ var forceCloseVariant = z33.object({ action: z33.literal("force-close"), entryId: z33.string().max(200), reason: z33.string().min(1).max(2e3) });
11084
+ var listVariant = z33.object({ action: z33.literal("list"), mine: z33.boolean().optional() });
11085
+ var questionActionUnion = z33.discriminatedUnion("action", [
11457
11086
  createVariant,
11458
11087
  assignVariant,
11459
11088
  answerVariant,
@@ -11672,7 +11301,7 @@ function registerResources(server) {
11672
11301
  async (uri) => {
11673
11302
  const collections = await kernelQuery("chain.listCollections") ?? [];
11674
11303
  if (collections.length === 0) {
11675
- return { contents: [{ uri: uri.href, text: "No collections in this workspace. Ask a platform admin to provision one, or enable a module ontology pack \u2014 `collections action=create` is no longer self-serve.", mimeType: "text/markdown" }] };
11304
+ return { contents: [{ uri: uri.href, text: "No collections in this workspace. Ask a platform admin to provision one, or enable a module ontology pack.", mimeType: "text/markdown" }] };
11676
11305
  }
11677
11306
  const formatted = collections.map((c) => {
11678
11307
  const fieldList = (c.fields ?? []).map((f) => ` - \`${f.key}\` (${f.type}${f.required ? ", required" : ""}${f.searchable ? ", searchable" : ""})`).join("\n");
@@ -11935,7 +11564,7 @@ ${entry.labels.map((l) => `- ${l.name ?? l.slug}`).join("\n")}`);
11935
11564
  }
11936
11565
 
11937
11566
  // src/prompts/index.ts
11938
- import { z as z35 } from "zod/v3";
11567
+ import { z as z34 } from "zod/v3";
11939
11568
  async function buildReviewAgainstRulesPrompt(domain) {
11940
11569
  const entries = await kernelQuery("chain.listEntries", { collectionSlug: "rules" });
11941
11570
  const rules = entries.slice(0, 50);
@@ -12017,27 +11646,27 @@ function registerPrompts(server) {
12017
11646
  server.prompt(
12018
11647
  "review-against-rules",
12019
11648
  "Review code or a design decision against the rules, focused on a given area. Fetches the rules and asks you to do a structured compliance review.",
12020
- { domain: z35.string().describe("Business rule domain (e.g. 'Identity & Access', 'Governance & Decision-Making')") },
11649
+ { domain: z34.string().describe("Business rule domain (e.g. 'Identity & Access', 'Governance & Decision-Making')") },
12021
11650
  async ({ domain }) => buildReviewAgainstRulesPrompt(domain)
12022
11651
  );
12023
11652
  server.prompt(
12024
11653
  "name-check",
12025
11654
  "Check variable names, field names, or API names against the glossary for terminology alignment. Flags drift from canonical terms.",
12026
- { names: z35.string().describe("Comma-separated list of names to check (e.g. 'user_id, workspace_id, entry_status')") },
11655
+ { names: z34.string().describe("Comma-separated list of names to check (e.g. 'user_id, workspace_id, entry_status')") },
12027
11656
  async ({ names }) => buildNameCheckPrompt(names)
12028
11657
  );
12029
11658
  server.prompt(
12030
11659
  "draft-decision-record",
12031
11660
  "Draft a structured decision record from a description of what was decided. Includes context from recent decisions and relevant rules.",
12032
- { context: z35.string().describe("Description of the decision (e.g. 'We decided to keep one body field per entry because...')") },
11661
+ { context: z34.string().describe("Description of the decision (e.g. 'We decided to keep one body field per entry because...')") },
12033
11662
  async ({ context }) => buildDraftDecisionRecordPrompt(context)
12034
11663
  );
12035
11664
  server.prompt(
12036
11665
  "draft-rule-from-context",
12037
11666
  "Draft a new business rule from an observation or discovery made while coding. Fetches existing rules for the domain to ensure consistency.",
12038
11667
  {
12039
- observation: z35.string().describe("What you observed or discovered (e.g. 'A workspace can have more than one owner role')"),
12040
- domain: z35.string().describe("Which domain this rule belongs to (e.g. 'Governance & Decision-Making')")
11668
+ observation: z34.string().describe("What you observed or discovered (e.g. 'A workspace can have more than one owner role')"),
11669
+ domain: z34.string().describe("Which domain this rule belongs to (e.g. 'Governance & Decision-Making')")
12041
11670
  },
12042
11671
  async ({ observation, domain }) => buildDraftRuleFromContextPrompt(observation, domain)
12043
11672
  );
@@ -12126,16 +11755,16 @@ var INSTRUCTIONS = [
12126
11755
  "",
12127
11756
  "## Writing",
12128
11757
  "",
12129
- "Write actions (capture, entries update and commit, relations create, batch-create and delete, people invite and remove, role seat and unseat) need an active session and a readwrite key.",
11758
+ "Write actions (capture, entries update and accept, relations create, batch-create and delete, people invite and remove, role seat and unseat) need an active session and a readwrite key.",
12130
11759
  "Pass the `sessionId` that `session action=start` returned on every write: the connection does not remember it.",
12131
- "Use `capture` to create an entry and read its reply: it lands as a draft, except a question, which is born open and needs no `entries action=commit`.",
11760
+ "Use `capture` to create an entry and read its reply: it lands as a draft, except a question, which is born open and needs no `entries action=accept`.",
12132
11761
  "Link entries with `relations action=create` \u2014 a relation is written only when you ask, with exactly the verb you send.",
12133
11762
  ...SPINE_LINKS_LINES,
12134
11763
  // TASK-1022 (WP-862): the spine grammar session start prints, a backup for the clients that load instructions
12135
11764
  "Finish with `session action=wrapup-review`, then `session action=close`.",
12136
11765
  "If the work falls outside the active work packages, name the gap and ask the user before designing it."
12137
11766
  ].join("\n");
12138
- var sessionIdArg = z36.string().max(200).optional().describe(
11767
+ var sessionIdArg = z35.string().max(200).optional().describe(
12139
11768
  "The sessionId `session action=start` returned. Pass it on every write: the connection does not remember your session between calls."
12140
11769
  );
12141
11770
  function acceptSessionIdOnEveryTool(server) {
@@ -12204,4 +11833,4 @@ export {
12204
11833
  SERVER_VERSION,
12205
11834
  createProductBrainServer
12206
11835
  };
12207
- //# sourceMappingURL=chunk-AMTSVZXV.js.map
11836
+ //# sourceMappingURL=chunk-FFOGLME6.js.map