@productbrain/mcp 0.0.1-beta.5738 → 0.0.1-beta.5751

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.
@@ -42,13 +42,60 @@ import {
42
42
  trackSessionCaptureRate,
43
43
  trackWriteBackHintServed,
44
44
  trackZeroCaptureAuditFired
45
- } from "./chunk-AFWQI35U.js";
45
+ } from "./chunk-Y7DPWFQQ.js";
46
46
 
47
47
  // src/server.ts
48
48
  import { McpServer as McpServer2 } from "@modelcontextprotocol/sdk/server/mcp.js";
49
49
 
50
+ // src/lib/createEntryPreviewResult.ts
51
+ async function resolvePreviewPreflight(result2, links) {
52
+ if (!links?.length) return result2.preflight;
53
+ try {
54
+ return await kernelQuery("chain.preflightEntry", {
55
+ collectionSlug: result2.collection,
56
+ canonicalKey: result2.preflight.kind ?? void 0,
57
+ links: links.map((link) => ({ entryId: link.to, type: link.type }))
58
+ });
59
+ } catch {
60
+ return {
61
+ ...result2.preflight,
62
+ checks: [
63
+ ...result2.preflight.checks,
64
+ {
65
+ id: "link-recheck",
66
+ status: "not_checked",
67
+ blocking: false,
68
+ message: "Selected links could not be rechecked now; target existence and relation policy are checked at capture."
69
+ }
70
+ ]
71
+ };
72
+ }
73
+ }
74
+ function formatPreflightCheck(check) {
75
+ if (check.status === "missing" && check.blocking) return `Blocked: ${check.message}`;
76
+ if (check.status === "incomplete") return `Unverified: ${check.message}`;
77
+ if (check.status === "not_checked") return `Checked later: ${check.message}`;
78
+ return check.message;
79
+ }
80
+ function renderEntryPreflight(preflight) {
81
+ return [
82
+ ...preflight.checks.map(formatPreflightCheck),
83
+ ...preflight.requiredFields.length ? [`Required information: ${preflight.requiredFields.join(", ")}.`] : [],
84
+ preflight.notice
85
+ ];
86
+ }
87
+ function isPreviewCreateEntryResult(result2) {
88
+ return "preview" in result2 && result2.preview === true;
89
+ }
90
+ function extractPreviewWouldBlock(result2, preview) {
91
+ return preview && result2 && isPreviewCreateEntryResult(result2) ? { wouldBlock: result2.wouldBlock === true, blockingReason: result2.blockingReason } : void 0;
92
+ }
93
+ function resolveEffectiveCollection(result2, preview, fallbackCollection) {
94
+ return preview && result2 && isPreviewCreateEntryResult(result2) ? result2.collection ?? fallbackCollection : fallbackCollection;
95
+ }
96
+
50
97
  // src/tools/entries.ts
51
- import { z as z10 } from "zod/v3";
98
+ import { z as z11 } from "zod/v3";
52
99
 
53
100
  // src/envelope.ts
54
101
  import { z } from "zod/v3";
@@ -1079,6 +1126,7 @@ var batchCapturePreviewOutputSchema = z3.object({
1079
1126
  // WouldCaptureEntry's doc comment. Absent exactly when `entryIdAssignedAtCapture` is true.
1080
1127
  entryId: z3.string().optional(),
1081
1128
  entryIdAssignedAtCapture: z3.literal(true).optional(),
1129
+ preflight: z3.custom().optional(),
1082
1130
  collection: z3.string(),
1083
1131
  name: z3.string(),
1084
1132
  classifiedBy: z3.string().optional(),
@@ -1092,6 +1140,7 @@ var batchCapturePreviewOutputSchema = z3.object({
1092
1140
  wouldBlock: z3.array(z3.object({
1093
1141
  entryId: z3.string().optional(),
1094
1142
  entryIdAssignedAtCapture: z3.literal(true).optional(),
1143
+ preflight: z3.custom().optional(),
1095
1144
  collection: z3.string(),
1096
1145
  name: z3.string(),
1097
1146
  blockingReason: z3.string().optional(),
@@ -1155,6 +1204,7 @@ function buildBatchPreviewFromResults(created, failed, skipped, requested, origi
1155
1204
  // auto-allocated (i.e. the caller supplied it for this item) — see WouldCaptureEntry's
1156
1205
  // doc comment for why an auto-ID cannot be predicted per-item within a preview batch.
1157
1206
  wouldCapture: wouldCaptureEntries.map((r) => ({
1207
+ ...r.preflight ? { preflight: r.preflight } : {},
1158
1208
  ...r.entryIdAssignedAtCapture ? { entryIdAssignedAtCapture: true } : { entryId: r.entryId },
1159
1209
  collection: r.collection,
1160
1210
  name: r.name,
@@ -1163,6 +1213,7 @@ function buildBatchPreviewFromResults(created, failed, skipped, requested, origi
1163
1213
  ...r.warnings?.length ? { warnings: r.warnings } : {}
1164
1214
  })),
1165
1215
  wouldBlock: wouldBlockEntries.map((r) => ({
1216
+ ...r.preflight ? { preflight: r.preflight } : {},
1166
1217
  ...r.entryIdAssignedAtCapture ? { entryIdAssignedAtCapture: true } : { entryId: r.entryId },
1167
1218
  collection: r.collection,
1168
1219
  name: r.name,
@@ -1195,6 +1246,7 @@ function buildBatchPreviewResult(input) {
1195
1246
  const idNote = r.entryId ? `**${r.entryId}**: ` : "";
1196
1247
  const assignedNote = r.entryIdAssignedAtCapture ? " (ID assigned at capture)" : "";
1197
1248
  lines.push(`- ${idNote}**${r.name}** [${r.collection}]${classNote}${warnNote}${assignedNote}`);
1249
+ if (r.preflight) lines.push(...renderEntryPreflight(r.preflight));
1198
1250
  }
1199
1251
  lines.push("");
1200
1252
  }
@@ -1205,6 +1257,7 @@ function buildBatchPreviewResult(input) {
1205
1257
  const idNote = b.entryId ? `**${b.entryId}**: ` : "";
1206
1258
  const assignedNote = b.entryIdAssignedAtCapture ? " (ID assigned at capture)" : "";
1207
1259
  lines.push(`- ${idNote}**${b.name}** [${b.collection}]${reasonNote}${assignedNote}`);
1260
+ if (b.preflight) lines.push(...renderEntryPreflight(b.preflight));
1208
1261
  }
1209
1262
  lines.push("");
1210
1263
  }
@@ -1261,17 +1314,6 @@ function buildBatchPreviewResult(input) {
1261
1314
  };
1262
1315
  }
1263
1316
 
1264
- // src/lib/createEntryPreviewResult.ts
1265
- function isPreviewCreateEntryResult(result2) {
1266
- return "preview" in result2 && result2.preview === true;
1267
- }
1268
- function extractPreviewWouldBlock(result2, preview) {
1269
- return preview && result2 && isPreviewCreateEntryResult(result2) ? { wouldBlock: result2.wouldBlock === true, blockingReason: result2.blockingReason } : void 0;
1270
- }
1271
- function resolveEffectiveCollection(result2, preview, fallbackCollection) {
1272
- return preview && result2 && isPreviewCreateEntryResult(result2) ? result2.collection ?? fallbackCollection : fallbackCollection;
1273
- }
1274
-
1275
1317
  // src/lib/entryDataNormalization.ts
1276
1318
  function isEmptyValue(v) {
1277
1319
  return v == null || (Array.isArray(v) ? v.length === 0 : String(v).trim() === "");
@@ -1518,6 +1560,7 @@ var groundingReportSchema = z4.object({
1518
1560
  });
1519
1561
  var taskAlignmentSchema = z4.record(z4.unknown());
1520
1562
  var captureSinglePreviewOutputSchema = z4.object({
1563
+ preflight: z4.custom().optional(),
1521
1564
  entryId: z4.string(),
1522
1565
  name: z4.string(),
1523
1566
  collection: z4.string(),
@@ -2405,6 +2448,7 @@ ${groundingReport.governance.map((g) => `- **${g.entryId}** ${g.name} [${g.colle
2405
2448
  ...links && links.length > 0 ? { deferLLMSchedule: true } : {}
2406
2449
  });
2407
2450
  if (result2 && isPreviewCreateEntryResult(result2)) {
2451
+ const preflight = await resolvePreviewPreflight(result2, links);
2408
2452
  const hasGrounding = groundingReport.related.length > 0 || groundingReport.duplicates.length > 0 || groundingReport.governance.length > 0;
2409
2453
  const groundingSummary = hasGrounding ? `
2410
2454
 
@@ -2419,6 +2463,7 @@ ${groundingReport.governance.map((g) => `- **${g.entryId}** ${g.name} [${g.colle
2419
2463
  wouldBlock ? `Preview: would be BLOCKED \u2014 "${name}" \u2014 no DB writes` : `Preview: would capture "${name}" \u2014 no DB writes`,
2420
2464
  {
2421
2465
  entryId: result2.entryId,
2466
+ preflight,
2422
2467
  name,
2423
2468
  // P0 round 4 (fix 1/3, root): see resolveEffectiveCollection's doc comment
2424
2469
  // (lib/createEntryPreviewResult.ts) for why this must be the server's EFFECTIVE
@@ -2455,9 +2500,11 @@ ${groundingReport.governance.map((g) => `- **${g.entryId}** ${g.name} [${g.colle
2455
2500
  if (result2.contract) {
2456
2501
  previewEnvelope.contract = result2.contract;
2457
2502
  }
2458
- const taskAlignmentNote = result2.taskAlignment ? `
2503
+ const taskAlignmentNote = (result2.taskAlignment ? `
2504
+
2505
+ **Task alignment:** ${result2.taskAlignment.wording}` : "") + `
2459
2506
 
2460
- **Task alignment:** ${result2.taskAlignment.wording}` : "";
2507
+ ${renderEntryPreflight(preflight).join("\n")}`;
2461
2508
  return {
2462
2509
  content: [{ type: "text", text: `# ${headline}
2463
2510
 
@@ -2989,7 +3036,7 @@ Use \`entries action=get\` to inspect the existing entry, or \`entries action=up
2989
3036
  if (userLinkResults.length === 0) {
2990
3037
  lines.push(`1. **Connect it:** \`relations action=suggest entryId="${eid}"\` \u2014 discover what this should link to`);
2991
3038
  }
2992
- lines.push(`${userLinkResults.length === 0 ? "2" : "1"}. **Accept it:** \`entries action=commit entryId="${eid}"\` \u2014 promote from draft to SSOT on the Chain`);
3039
+ lines.push(`${userLinkResults.length === 0 ? "2" : "1"}. **Review the possibility:** Keep this visible draft while it is an alternative. Accept only when commitment is intended and your role is authorized. Types reserved for human acceptance require human ratification. An audit advisory is not a reason to accept it.`);
2993
3040
  if (hasQualityGaps) {
2994
3041
  lines.push(`${userLinkResults.length === 0 ? "3" : "2"}. **Improve quality:** \`entries action=update entryId="${eid}"\` \u2014 fill missing fields`);
2995
3042
  }
@@ -3007,14 +3054,13 @@ Use \`entries action=get\` to inspect the existing entry, or \`entries action=up
3007
3054
  } catch {
3008
3055
  }
3009
3056
  const next = [];
3010
- if (finalStatus === "committed") {
3011
- next.push({ tool: "relations", description: "Discover connections", parameters: { action: "suggest", entryId: finalEntryId } });
3012
- } else if (finalStatus === "proposed") {
3057
+ if (finalStatus === "committed" || finalStatus === "proposed") {
3013
3058
  next.push({ tool: "relations", description: "Discover connections", parameters: { action: "suggest", entryId: finalEntryId } });
3014
3059
  } else {
3015
3060
  if (userLinkResults.length === 0) {
3016
3061
  next.push({ tool: "relations", description: "Discover links", parameters: { action: "suggest", entryId: finalEntryId } });
3017
3062
  }
3063
+ next.push({ tool: "entries", description: "Review the draft alternative", parameters: { action: "get", entryId: finalEntryId } });
3018
3064
  next.push({ tool: "entries", description: "Accept onto Chain", parameters: { action: "commit", entryId: finalEntryId } });
3019
3065
  }
3020
3066
  const qualityPhrase = verdictQualityPhrase(verdictResult);
@@ -3327,6 +3373,7 @@ async function handleBatchCapture(server, { entries, autoCommit, preview }) {
3327
3373
  ...entry.ownerTeamEntryId ? { ownerTeamEntryId: entry.ownerTeamEntryId } : {},
3328
3374
  ...entry.ownerRoleEntryId ? { ownerRoleEntryId: entry.ownerRoleEntryId } : {}
3329
3375
  });
3376
+ const preflight = isPreviewCreateEntryResult(rawResult) ? await resolvePreviewPreflight(rawResult, entry.relations) : void 0;
3330
3377
  const previewWouldBlock = extractPreviewWouldBlock(rawResult, preview);
3331
3378
  const effectiveCollection = resolveEffectiveCollection(rawResult, preview, resolvedSlug);
3332
3379
  const result2 = rawResult;
@@ -3500,6 +3547,7 @@ async function handleBatchCapture(server, { entries, autoCommit, preview }) {
3500
3547
  confidence,
3501
3548
  confidenceTier,
3502
3549
  ...previewWouldBlock ? { wouldBlock: previewWouldBlock.wouldBlock } : {},
3550
+ ...preflight ? { preflight } : {},
3503
3551
  ...previewWouldBlock?.blockingReason ? { blockingReason: previewWouldBlock.blockingReason } : {},
3504
3552
  // Fix 1 (TEN-2918 follow-up): not caller-supplied — the preview projection
3505
3553
  // must not report this predicted-but-duplicable ID as concrete.
@@ -3679,7 +3727,7 @@ _Use \`entries action=move\` to correct any misclassified entries._`);
3679
3727
  lines.push(`- **Connect:** Run \`relations action=suggest\` on key entries to build the knowledge graph`);
3680
3728
  }
3681
3729
  if (drafts.length > 0) {
3682
- lines.push(`- **Accept:** Use \`entries action=commit\` to promote remaining drafts to SSOT`);
3730
+ lines.push("- **Review possibilities:** Retain useful alternatives as visible drafts. Accept only intended commitments within your role's authority. Types reserved for human acceptance require human ratification. Do not accept a draft merely to clear an advisory.");
3683
3731
  }
3684
3732
  if (skippedLowConfidence.length > 0) {
3685
3733
  lines.push(`- **Classify:** Re-capture ${skippedLowConfidence.length} skipped entries with explicit collections`);
@@ -3698,7 +3746,8 @@ _Use \`entries action=move\` to correct any misclassified entries._`);
3698
3746
  next.push({ tool: "relations", description: "Discover connections", parameters: { action: "suggest", entryId: created[0].entryId } });
3699
3747
  }
3700
3748
  if (firstDraft) {
3701
- next.push({ tool: "entries", description: "Accept first draft", parameters: { action: "commit", entryId: firstDraft.entryId } });
3749
+ next.push({ tool: "entries", description: "Review first draft alternative", parameters: { action: "get", entryId: firstDraft.entryId } });
3750
+ next.push({ tool: "entries", description: "Accept onto Chain", parameters: { action: "commit", entryId: firstDraft.entryId } });
3702
3751
  }
3703
3752
  if (skippedLowConfidence.length > 0) {
3704
3753
  next.push({ tool: "capture", description: `Capture skipped entry with explicit collection`, parameters: { name: skippedLowConfidence[0].name, collection: skippedLowConfidence[0].suggestedCollection ?? "" } });
@@ -4778,47 +4827,8 @@ ${recovery}`,
4778
4827
  }
4779
4828
  }
4780
4829
 
4781
- // src/tools/entries.ts
4782
- function sanitizeEntryData(data) {
4783
- if (!data || typeof data !== "object") return void 0;
4784
- const filtered = Object.fromEntries(
4785
- Object.entries(data).filter(([key]) => !key.startsWith("_"))
4786
- );
4787
- return Object.keys(filtered).length > 0 ? filtered : void 0;
4788
- }
4789
- function renderWhyLine(e) {
4790
- const why = typeof e.why === "string" ? e.why : "";
4791
- if (e.whyQuality === "missing") {
4792
- return { line: `**Why:** \u2014 (no rationale captured)`, why, whySourceKey: null };
4793
- }
4794
- if (why.length > 0) {
4795
- const suffix = e.whyQuality === "restated" ? " (restated)" : "";
4796
- const d = e.data ?? {};
4797
- let whySourceKey = null;
4798
- const kf = e.whyField;
4799
- if ((kf === "rationale" || kf === "description") && typeof d[kf] === "string" && d[kf].trim().length > 0) {
4800
- whySourceKey = kf;
4801
- } else if (typeof d.rationale === "string" && d.rationale.trim().length > 0) {
4802
- whySourceKey = "rationale";
4803
- }
4804
- return { line: `**Why:** ${why}${suffix}`, why, whySourceKey };
4805
- }
4806
- return { line: null, why, whySourceKey: null };
4807
- }
4808
- function renderVerificationLine(e) {
4809
- if (!e.verificationStatus) return null;
4810
- const verifiedBy = typeof e.verifiedBy === "string" ? e.verifiedBy : void 0;
4811
- const attestation = e.attestation && typeof e.attestation === "object" ? e.attestation : void 0;
4812
- const strength = attestation && typeof attestation.strength === "string" ? attestation.strength : void 0;
4813
- const basis = attestation && typeof attestation.basis === "string" ? attestation.basis : void 0;
4814
- let who;
4815
- if (basis && basis !== "attested") {
4816
- who = verifiedBy ? ` (${verifiedBy})` : "";
4817
- } else {
4818
- who = verifiedBy ? ` \u2014 by ${verifiedBy}${strength ? ` (${strength})` : ""}` : "";
4819
- }
4820
- return `**Verification:** ${String(e.verificationStatus)}${who}`;
4821
- }
4830
+ // src/tools/entriesContract.ts
4831
+ import { z as z10 } from "zod/v3";
4822
4832
  var ENTRIES_ACTIONS = [
4823
4833
  "list",
4824
4834
  "get",
@@ -4828,7 +4838,8 @@ var ENTRIES_ACTIONS = [
4828
4838
  "commit",
4829
4839
  "history",
4830
4840
  "move",
4831
- "verify"
4841
+ "verify",
4842
+ "preflight"
4832
4843
  ];
4833
4844
  var entriesStatusFilterSchema = z10.union([z10.string().max(200), z10.array(z10.enum(["draft", "active", "accepted", "deprecated", "archived"])).max(5)]);
4834
4845
  var coherencyAcknowledgementFlatSchema = z10.object({
@@ -4836,15 +4847,17 @@ var coherencyAcknowledgementFlatSchema = z10.object({
4836
4847
  entryId: z10.string().max(200).optional().describe("Authorizing entry being linked/accepted (required for 'linked' and 'accepted-fix')."),
4837
4848
  reason: z10.string().max(2e3).optional().describe("Divergence rationale (required for 'diverged', \u226512 chars).")
4838
4849
  });
4850
+ var preflightLinks = z10.array(z10.object({ type: z10.string().max(200), entryId: z10.string().max(200) })).max(50).optional();
4839
4851
  var entriesSchema = z10.object({
4852
+ links: preflightLinks.describe("For preflight: proposed context links; saves nothing."),
4840
4853
  action: z10.enum(ENTRIES_ACTIONS).describe(
4841
- "'list': browse entries with filters. 'get': fetch one entry by ID. 'batch': fetch multiple entries. 'search': full-text search. 'update': change fields on an existing entry (draft by default). 'commit': accept a draft entry onto the Chain. 'history': audit trail for an entry. '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)."
4854
+ "'preflight': inspect structural requirements before composing (requires collection). 'list': browse entries with filters. 'get': fetch one entry by ID. 'batch': fetch multiple entries. 'search': full-text search. 'update': change fields on an existing entry (draft by default). 'commit': accept a draft entry onto the Chain. 'history': audit trail for an entry. '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)."
4842
4855
  ),
4843
4856
  entryId: z10.string().max(200).optional().describe(
4844
4857
  "Entry ID, e.g. '<PREFIX>-<n>'. Required for: get, update, commit, history, move, verify."
4845
4858
  ),
4846
4859
  entryIds: z10.array(z10.string().max(200)).min(1).max(20).optional().describe("Entry IDs for 'batch', e.g. ['TYPE-strategy', 'STR-jljeg7']"),
4847
- collection: z10.string().max(200).optional().describe("Collection slug \u2014 for 'list'/'search': scope filter, e.g. 'glossary', 'tracking-events'."),
4860
+ collection: z10.string().max(200).optional().describe("Collection slug \u2014 for 'list'/'search': scope filter, e.g. 'glossary', 'tracking-events'. For 'preflight': the collection the entry would be composed into (required)."),
4848
4861
  status: entriesStatusFilterSchema.optional().describe(
4849
4862
  "For 'list': one lifecycle value (draft|active|accepted|deprecated|archived; active/accepted are the same trust level). For 'search': one value OR an array of up to 5 (e.g. ['active','accepted']). For 'update': draft|active|deprecated|archived ONLY \u2014 'accepted' is set via 'commit', never 'update'. Workflow values use `workflowStatus` instead."
4850
4863
  ),
@@ -4858,7 +4871,7 @@ var entriesSchema = z10.object({
4858
4871
  data: z10.record(z10.unknown()).optional().describe("For 'update': fields to update (merged with existing data)."),
4859
4872
  order: z10.number().optional().describe("For 'update': new sort order."),
4860
4873
  canonicalKey: z10.string().max(200).optional().describe(
4861
- "For 'update': semantic type (e.g. 'decision', 'tension'); only changeable on draft/uncommitted entries. For 'move': optional atomic move+retype target."
4874
+ "For 'update': semantic type (e.g. 'decision', 'tension'); only changeable on draft/uncommitted entries. For 'move': optional atomic move+retype target. For 'preflight': optional semantic type to check requirements for."
4862
4875
  ),
4863
4876
  autoPublish: z10.boolean().optional().default(false).describe(
4864
4877
  "For 'update': only true when the user explicitly asks to publish. Default false = draft."
@@ -4917,6 +4930,7 @@ var entriesMoveVariant = z10.object({
4917
4930
  });
4918
4931
  var entriesVerifyVariant = verifyEntrySchema.extend({ action: z10.literal("verify") });
4919
4932
  var entriesActionUnion = z10.discriminatedUnion("action", [
4933
+ z10.object({ action: z10.literal("preflight"), collection: z10.string().max(200), canonicalKey: z10.string().max(200).optional(), links: preflightLinks }),
4920
4934
  entriesListVariant,
4921
4935
  entriesGetVariant,
4922
4936
  entriesBatchVariant,
@@ -4928,6 +4942,7 @@ var entriesActionUnion = z10.discriminatedUnion("action", [
4928
4942
  entriesVerifyVariant
4929
4943
  ]);
4930
4944
  var ENTRIES_ACTION_SPECS = {
4945
+ preflight: { params: ["collection", "canonicalKey", "links"], description: "Inspect structure before composition; no writes or permission grant." },
4931
4946
  list: { params: ["collection", "status", "tag", "label"], description: "Browse entries; all params optional." },
4932
4947
  get: { params: ["entryId"], description: "Fetch one entry by ID." },
4933
4948
  batch: { params: ["entryIds"], description: "Fetch up to 20 entries by ID." },
@@ -4938,15 +4953,70 @@ var ENTRIES_ACTION_SPECS = {
4938
4953
  move: { params: ["entryId", "toCollection", "canonicalKey"], description: "entryId and toCollection are required; canonicalKey is optional (atomic move+retype)." },
4939
4954
  verify: { params: ["entryId"], description: "entryId is required." }
4940
4955
  };
4941
- var entriesGetOutputSchema = z10.object({
4942
- entryId: z10.string(),
4943
- name: z10.string(),
4944
- collection: z10.string(),
4945
- status: z10.string(),
4946
- capturedAt: z10.number().optional(),
4947
- origin: z10.string().optional(),
4948
- originDetail: z10.string().optional(),
4949
- verificationStatus: z10.string().optional(),
4956
+
4957
+ // src/tools/entries.ts
4958
+ function projectEntryRelations(value) {
4959
+ if (!Array.isArray(value)) return [];
4960
+ return value.map((r) => ({
4961
+ ...r.otherEntryId ? { entryId: r.otherEntryId } : {},
4962
+ name: r.otherName ?? "unknown",
4963
+ type: r.type ?? "unknown",
4964
+ direction: r.direction ?? "unknown",
4965
+ status: r.otherStatus ?? "unknown"
4966
+ }));
4967
+ }
4968
+ function relationLines(value) {
4969
+ return projectEntryRelations(value).map((r) => `- ${r.direction === "outgoing" ? "\u2192" : "\u2190"} **${r.type}** ${r.entryId ? `${r.entryId}: ${r.name}` : r.name} [${r.status}]`);
4970
+ }
4971
+ function sanitizeEntryData(data) {
4972
+ if (!data || typeof data !== "object") return void 0;
4973
+ const filtered = Object.fromEntries(
4974
+ Object.entries(data).filter(([key]) => !key.startsWith("_"))
4975
+ );
4976
+ return Object.keys(filtered).length > 0 ? filtered : void 0;
4977
+ }
4978
+ function renderWhyLine(e) {
4979
+ const why = typeof e.why === "string" ? e.why : "";
4980
+ if (e.whyQuality === "missing") {
4981
+ return { line: `**Why:** \u2014 (no rationale captured)`, why, whySourceKey: null };
4982
+ }
4983
+ if (why.length > 0) {
4984
+ const suffix = e.whyQuality === "restated" ? " (restated)" : "";
4985
+ const d = e.data ?? {};
4986
+ let whySourceKey = null;
4987
+ const kf = e.whyField;
4988
+ if ((kf === "rationale" || kf === "description") && typeof d[kf] === "string" && d[kf].trim().length > 0) {
4989
+ whySourceKey = kf;
4990
+ } else if (typeof d.rationale === "string" && d.rationale.trim().length > 0) {
4991
+ whySourceKey = "rationale";
4992
+ }
4993
+ return { line: `**Why:** ${why}${suffix}`, why, whySourceKey };
4994
+ }
4995
+ return { line: null, why, whySourceKey: null };
4996
+ }
4997
+ function renderVerificationLine(e) {
4998
+ if (!e.verificationStatus) return null;
4999
+ const verifiedBy = typeof e.verifiedBy === "string" ? e.verifiedBy : void 0;
5000
+ const attestation = e.attestation && typeof e.attestation === "object" ? e.attestation : void 0;
5001
+ const strength = attestation && typeof attestation.strength === "string" ? attestation.strength : void 0;
5002
+ const basis = attestation && typeof attestation.basis === "string" ? attestation.basis : void 0;
5003
+ let who;
5004
+ if (basis && basis !== "attested") {
5005
+ who = verifiedBy ? ` (${verifiedBy})` : "";
5006
+ } else {
5007
+ who = verifiedBy ? ` \u2014 by ${verifiedBy}${strength ? ` (${strength})` : ""}` : "";
5008
+ }
5009
+ return `**Verification:** ${String(e.verificationStatus)}${who}`;
5010
+ }
5011
+ var entriesGetOutputSchema = z11.object({
5012
+ entryId: z11.string(),
5013
+ name: z11.string(),
5014
+ collection: z11.string(),
5015
+ status: z11.string(),
5016
+ capturedAt: z11.number().optional(),
5017
+ origin: z11.string().optional(),
5018
+ originDetail: z11.string().optional(),
5019
+ verificationStatus: z11.string().optional(),
4950
5020
  // Attestation-model finding (PR #341 review): the server's honest verifier label and
4951
5021
  // derived attestation strength/basis — connectors NEVER re-derive strength (spec §5),
4952
5022
  // they only render what chain.getEntry ships. Mirrors packages/cli EntryFromApi.
@@ -4955,75 +5025,80 @@ var entriesGetOutputSchema = z10.object({
4955
5025
  // attestation.ts's AttestationStrength SSOT (allowlisted in Check D —
4956
5026
  // scripts/check-collection-ssot.mjs's CHECK_D_ALLOWLIST — with the full
4957
5027
  // reasoning for why this can't just import that module). Update both together.
4958
- verifiedBy: z10.string().optional(),
4959
- attestation: z10.object({
4960
- strength: z10.enum(["human-direct", "delegated", "system", "unattested"]),
4961
- basis: z10.string().optional()
5028
+ verifiedBy: z11.string().optional(),
5029
+ attestation: z11.object({
5030
+ strength: z11.enum(["human-direct", "delegated", "system", "unattested"]),
5031
+ basis: z11.string().optional()
4962
5032
  }).optional(),
4963
- sourceRef: z10.string().optional(),
4964
- sourceExcerpt: z10.string().optional(),
4965
- why: z10.string().optional(),
5033
+ sourceRef: z11.string().optional(),
5034
+ sourceExcerpt: z11.string().optional(),
5035
+ why: z11.string().optional(),
4966
5036
  // TEN-2191: quality of the captured WHY — 'rationale' | 'missing' | 'restated'.
4967
- whyQuality: z10.enum(["rationale", "missing", "restated"]).optional(),
4968
- data: z10.record(z10.unknown()).optional(),
4969
- relations: z10.array(z10.object({
4970
- entryId: z10.string().optional(),
4971
- name: z10.string(),
4972
- type: z10.string(),
4973
- direction: z10.string()
5037
+ whyQuality: z11.enum(["rationale", "missing", "restated"]).optional(),
5038
+ data: z11.record(z11.unknown()).optional(),
5039
+ relations: z11.array(z11.object({
5040
+ entryId: z11.string().optional(),
5041
+ name: z11.string(),
5042
+ type: z11.string(),
5043
+ direction: z11.string(),
5044
+ status: z11.string().optional()
4974
5045
  })).optional(),
4975
- labels: z10.array(z10.string()).optional()
5046
+ labels: z11.array(z11.string()).optional()
4976
5047
  }).passthrough();
4977
- var entriesListOutputSchema = z10.object({
4978
- entries: z10.array(z10.object({
4979
- entryId: z10.string(),
4980
- name: z10.string(),
4981
- collection: z10.string(),
4982
- status: z10.string()
5048
+ var entriesListOutputSchema = z11.object({
5049
+ entries: z11.array(z11.object({
5050
+ entryId: z11.string(),
5051
+ name: z11.string(),
5052
+ collection: z11.string(),
5053
+ status: z11.string()
4983
5054
  })),
4984
- total: z10.number()
5055
+ total: z11.number()
4985
5056
  });
4986
- var entriesSearchOutputSchema = z10.object({
4987
- results: z10.array(z10.object({
4988
- entryId: z10.string(),
4989
- name: z10.string(),
4990
- collection: z10.string(),
4991
- status: z10.string(),
4992
- score: z10.number().optional()
5057
+ var entriesSearchOutputSchema = z11.object({
5058
+ results: z11.array(z11.object({
5059
+ entryId: z11.string(),
5060
+ name: z11.string(),
5061
+ collection: z11.string(),
5062
+ status: z11.string(),
5063
+ score: z11.number().optional()
4993
5064
  })),
4994
- total: z10.number(),
4995
- query: z10.string()
5065
+ total: z11.number(),
5066
+ query: z11.string()
4996
5067
  });
4997
- var entriesBatchOutputSchema = z10.object({
4998
- entries: z10.array(z10.object({
4999
- entryId: z10.string(),
5000
- name: z10.string(),
5001
- collection: z10.string(),
5002
- status: z10.string(),
5003
- capturedAt: z10.number().optional(),
5004
- origin: z10.string().optional(),
5005
- originDetail: z10.string().optional(),
5006
- verificationStatus: z10.string().optional(),
5068
+ var entriesBatchOutputSchema = z11.object({
5069
+ entries: z11.array(z11.object({
5070
+ entryId: z11.string(),
5071
+ name: z11.string(),
5072
+ collection: z11.string(),
5073
+ status: z11.string(),
5074
+ capturedAt: z11.number().optional(),
5075
+ origin: z11.string().optional(),
5076
+ originDetail: z11.string().optional(),
5077
+ verificationStatus: z11.string().optional(),
5007
5078
  // Attestation-model finding (PR #341 review): mirror entriesGetOutputSchema — batch
5008
5079
  // entries now carry the same honest verifiedBy/attestation fields. Literal set is
5009
5080
  // the same hand-kept SSOT mirror — see entriesGetOutputSchema's attestation
5010
5081
  // comment above for the full Check D / kernel-import reasoning.
5011
- verifiedBy: z10.string().optional(),
5012
- attestation: z10.object({
5013
- strength: z10.enum(["human-direct", "delegated", "system", "unattested"]),
5014
- basis: z10.string().optional()
5082
+ verifiedBy: z11.string().optional(),
5083
+ attestation: z11.object({
5084
+ strength: z11.enum(["human-direct", "delegated", "system", "unattested"]),
5085
+ basis: z11.string().optional()
5015
5086
  }).optional(),
5016
- sourceRef: z10.string().optional(),
5017
- sourceExcerpt: z10.string().optional(),
5087
+ sourceRef: z11.string().optional(),
5088
+ sourceExcerpt: z11.string().optional(),
5018
5089
  // TEN-2191: mirror entriesGetOutputSchema — batch entries now carry why/whyQuality.
5019
- why: z10.string().optional(),
5020
- whyQuality: z10.enum(["rationale", "missing", "restated"]).optional(),
5021
- data: z10.record(z10.unknown()).optional()
5090
+ why: z11.string().optional(),
5091
+ whyQuality: z11.enum(["rationale", "missing", "restated"]).optional(),
5092
+ data: z11.record(z11.unknown()).optional()
5022
5093
  }).passthrough()),
5023
- total: z10.number()
5094
+ total: z11.number()
5024
5095
  });
5025
5096
  function registerEntriesTools(server) {
5026
5097
  const entriesHandlers = {
5098
+ preflight: async (data) => {
5099
+ const result2 = await kernelQuery("chain.preflightEntry", { collectionSlug: data.collection, canonicalKey: data.canonicalKey, links: data.links });
5100
+ return { content: [{ type: "text", text: renderEntryPreflight(result2).join("\n") }], structuredContent: success("Structural requirements checked; nothing saved.", result2) };
5101
+ },
5027
5102
  list: (data) => handleList(data.collection, data.status, data.tag, data.label),
5028
5103
  get: (data) => handleGet(data.entryId),
5029
5104
  batch: (data) => handleBatch(data.entryIds),
@@ -5040,7 +5115,7 @@ function registerEntriesTools(server) {
5040
5115
  "entries",
5041
5116
  {
5042
5117
  title: "Entries",
5043
- description: 'Read and manage entries on the Chain. One tool for the entry lifecycle.\n\n- **list**: Browse entries with optional filters (collection, status, tag, label). Use collections action=list first to discover slugs.\n- **get**: Fetch a single entry by ID \u2014 full record with data, labels, relations, history.\n- **batch**: Fetch multiple entries (max 20) in one call. Same shape as get per entry.\n- **search**: Full-text search across entries. Scope by collection or filter by status.\n- **update**: Change fields on an existing entry (draft by default \u2014 never autoPublish without explicit user confirmation).\n- **commit**: Accept a draft entry onto the Chain (SSOT). Runs the contradiction preflight first.\n- **history**: Audit trail for an entry.\n- **move**: Relocate an entry to a different collection; pass canonicalKey too for an atomic move+retype.\n- **verify**: Mark an entry as verified (lightweight, no codebase scan \u2014 see `quality action=verify-chain` for that).\n\nUse `entries action=get entryId="..."` to fetch one. Use `entries action=search query="..."` to discover.',
5118
+ description: 'Read and manage entries on the Chain. One tool for the entry lifecycle.\n\n- **preflight**: Inspect a type and selected context before composing. No writes, capacity reservation or authority grant.\n- **list**: Browse entries with optional filters (collection, status, tag, label). Use collections action=list first to discover slugs.\n- **get**: Fetch a single entry by ID \u2014 full record with data, labels, relations, history.\n- **batch**: Fetch multiple entries (max 20) in one call. Same shape as get per entry.\n- **search**: Full-text search across entries. Scope by collection or filter by status.\n- **update**: Change fields on an existing entry (draft by default \u2014 never autoPublish without explicit user confirmation).\n- **commit**: Accept a draft entry onto the Chain (SSOT). Runs the contradiction preflight first.\n- **history**: Audit trail for an entry.\n- **move**: Relocate an entry to a different collection; pass canonicalKey too for an atomic move+retype.\n- **verify**: Mark an entry as verified (lightweight, no codebase scan \u2014 see `quality action=verify-chain` for that).\n\nUse `entries action=get entryId="..."` to fetch one. Use `entries action=search query="..."` to discover.',
5044
5119
  inputSchema: entriesSchema,
5045
5120
  // Mixed read/write noun (§3 R3): can't be marked read-only once update/commit/move
5046
5121
  // live here too — accepted for the 11-tool default (§9 R3).
@@ -5104,11 +5179,7 @@ async function handleGet(entryId) {
5104
5179
  }
5105
5180
  if (Array.isArray(e.relations) && e.relations.length > 0) {
5106
5181
  lines.push("", "## Relations");
5107
- for (const r of e.relations) {
5108
- const arrow = r.direction === "outgoing" ? "\u2192" : "\u2190";
5109
- const other = r.otherEntryId ? `${r.otherEntryId}: ${r.otherName}` : r.otherName ?? "unknown";
5110
- lines.push(`- ${arrow} **${r.type}** ${other}`);
5111
- }
5182
+ lines.push(...relationLines(e.relations));
5112
5183
  }
5113
5184
  if (Array.isArray(e.history) && e.history.length > 0) {
5114
5185
  lines.push("", "## History (last 10)");
@@ -5149,12 +5220,7 @@ async function handleGet(entryId) {
5149
5220
  // that commit 8f3b1664 left in the structured payload. (Codex finding, TEN-2191.)
5150
5221
  ...filteredData ? { data: filteredData } : {},
5151
5222
  ...Array.isArray(e.relations) && e.relations.length > 0 ? {
5152
- relations: e.relations.map((r) => ({
5153
- ...r.otherEntryId ? { entryId: r.otherEntryId } : {},
5154
- name: r.otherName ?? "unknown",
5155
- type: r.type ?? "unknown",
5156
- direction: r.direction ?? "unknown"
5157
- }))
5223
+ relations: projectEntryRelations(e.relations)
5158
5224
  } : {},
5159
5225
  ...Array.isArray(e.labels) && e.labels.length > 0 ? { labels: e.labels.map((l) => l.slug ?? l.name ?? "") } : {}
5160
5226
  };
@@ -5223,11 +5289,7 @@ async function handleBatch(entryIds) {
5223
5289
  }
5224
5290
  if (Array.isArray(entry.relations) && entry.relations.length > 0) {
5225
5291
  lines.push("", "**Relations:**");
5226
- for (const rel of entry.relations) {
5227
- const dir = rel.direction === "outgoing" ? "\u2192" : "\u2190";
5228
- const other = rel.otherEntryId ?? rel.otherName ?? "?";
5229
- lines.push(`- ${dir} [${rel.type}] ${other}`);
5230
- }
5292
+ lines.push(...relationLines(entry.relations));
5231
5293
  }
5232
5294
  if (Array.isArray(entry.history) && entry.history.length > 0) {
5233
5295
  lines.push("", "**History (last 5):**");
@@ -5262,7 +5324,8 @@ async function handleBatch(entryIds) {
5262
5324
  // TEN-2191: surface why/whyQuality in structured payload — mirrors handleGet.
5263
5325
  ...entryWhy.length > 0 ? { why: entryWhy } : {},
5264
5326
  ...entry.whyQuality ? { whyQuality: String(entry.whyQuality) } : {},
5265
- ...entryFilteredData ? { data: entryFilteredData } : {}
5327
+ ...entryFilteredData ? { data: entryFilteredData } : {},
5328
+ ...Array.isArray(entry.relations) && entry.relations.length ? { relations: projectEntryRelations(entry.relations) } : {}
5266
5329
  };
5267
5330
  });
5268
5331
  const total = structuredEntries.length;
@@ -5412,41 +5475,41 @@ ${footer}` }],
5412
5475
  }
5413
5476
 
5414
5477
  // src/tools/relations.ts
5415
- import { z as z12 } from "zod/v3";
5478
+ import { z as z13 } from "zod/v3";
5416
5479
 
5417
5480
  // src/tools/graph.ts
5418
- import { z as z11 } from "zod/v3";
5481
+ import { z as z12 } from "zod/v3";
5419
5482
  var GRAPH_ACTIONS = ["find", "suggest"];
5420
- var graphSchema = z11.object({
5421
- action: z11.enum(GRAPH_ACTIONS).describe(
5483
+ var graphSchema = z12.object({
5484
+ action: z12.enum(GRAPH_ACTIONS).describe(
5422
5485
  "'find': traverse relations from an entry (graph walk). 'suggest': discover potential connections for an entry."
5423
5486
  ),
5424
- entryId: z11.string().max(200).describe("Entry ID, e.g. '<PREFIX>-<n>'"),
5425
- direction: z11.enum(["incoming", "outgoing", "both"]).default("both").optional().describe("For find: 'incoming' = what references this, 'outgoing' = what this references"),
5426
- limit: z11.number().min(1).max(20).default(10).optional().describe("For suggest: max suggestions to return"),
5427
- depth: z11.number().min(1).max(3).default(2).optional().describe("For suggest: graph traversal depth")
5487
+ entryId: z12.string().max(200).describe("Entry ID, e.g. '<PREFIX>-<n>'"),
5488
+ direction: z12.enum(["incoming", "outgoing", "both"]).default("both").optional().describe("For find: 'incoming' = what references this, 'outgoing' = what this references"),
5489
+ limit: z12.number().min(1).max(20).default(10).optional().describe("For suggest: max suggestions to return"),
5490
+ depth: z12.number().min(1).max(3).default(2).optional().describe("For suggest: graph traversal depth")
5428
5491
  });
5429
- var graphFindOutputSchema = z11.object({
5430
- entryId: z11.string(),
5431
- relations: z11.array(z11.object({
5432
- entryId: z11.string().optional(),
5433
- name: z11.string(),
5434
- type: z11.string(),
5435
- direction: z11.enum(["outgoing", "incoming"])
5492
+ var graphFindOutputSchema = z12.object({
5493
+ entryId: z12.string(),
5494
+ relations: z12.array(z12.object({
5495
+ entryId: z12.string().optional(),
5496
+ name: z12.string(),
5497
+ type: z12.string(),
5498
+ direction: z12.enum(["outgoing", "incoming"])
5436
5499
  })),
5437
- total: z11.number()
5500
+ total: z12.number()
5438
5501
  });
5439
- var graphSuggestOutputSchema = z11.object({
5440
- entryId: z11.string(),
5441
- suggestions: z11.array(z11.object({
5442
- targetEntryId: z11.string().optional(),
5443
- targetName: z11.string(),
5444
- relationType: z11.string(),
5445
- direction: z11.string(),
5446
- confidence: z11.number(),
5447
- reason: z11.string()
5502
+ var graphSuggestOutputSchema = z12.object({
5503
+ entryId: z12.string(),
5504
+ suggestions: z12.array(z12.object({
5505
+ targetEntryId: z12.string().optional(),
5506
+ targetName: z12.string(),
5507
+ relationType: z12.string(),
5508
+ direction: z12.string(),
5509
+ confidence: z12.number(),
5510
+ reason: z12.string()
5448
5511
  })),
5449
- total: z11.number()
5512
+ total: z12.number()
5450
5513
  });
5451
5514
  async function handleFind(entryId, direction) {
5452
5515
  const relations = await kernelQuery("chain.listEntryRelations", { entryId });
@@ -5637,64 +5700,64 @@ async function handleSuggest(entryId, limit, depth) {
5637
5700
 
5638
5701
  // src/tools/relations.ts
5639
5702
  var RELATIONS_ACTIONS = ["create", "batch-create", "dismiss", "delete", "find", "suggest"];
5640
- var relationItemSchema = z12.object({
5641
- from: z12.string().max(200),
5642
- to: z12.string().max(200),
5643
- type: z12.string().max(200)
5703
+ var relationItemSchema = z13.object({
5704
+ from: z13.string().max(200),
5705
+ to: z13.string().max(200),
5706
+ type: z13.string().max(200)
5644
5707
  });
5645
- var relationsSchema = z12.object({
5646
- action: z12.enum(RELATIONS_ACTIONS).describe(
5708
+ var relationsSchema = z13.object({
5709
+ action: z13.enum(RELATIONS_ACTIONS).describe(
5647
5710
  "'create': link two entries. 'batch-create': create multiple relations (validates every item before writing any). 'dismiss': record that a suggestion was not relevant. 'delete': remove a relation. 'find': traverse relations from an entry (graph walk, absorbs graph action=find). 'suggest': discover potential connections for an entry (absorbs graph action=suggest)."
5648
5711
  ),
5649
- from: z12.string().max(200).optional().describe("For 'create'/'dismiss'/'delete': source entry ID."),
5650
- to: z12.string().max(200).optional().describe("For 'create'/'dismiss'/'delete': target entry ID."),
5651
- type: z12.string().max(200).optional().describe("For 'create'/'dismiss'/'delete': relation type."),
5652
- score: z12.number().optional().describe("For 'dismiss': suggestion score from action=suggest."),
5653
- relations: z12.array(relationItemSchema).min(1).max(20).optional().describe("For 'batch-create': array of {from, to, type}."),
5712
+ from: z13.string().max(200).optional().describe("For 'create'/'dismiss'/'delete': source entry ID."),
5713
+ to: z13.string().max(200).optional().describe("For 'create'/'dismiss'/'delete': target entry ID."),
5714
+ type: z13.string().max(200).optional().describe("For 'create'/'dismiss'/'delete': relation type."),
5715
+ score: z13.number().optional().describe("For 'dismiss': suggestion score from action=suggest."),
5716
+ relations: z13.array(relationItemSchema).min(1).max(20).optional().describe("For 'batch-create': array of {from, to, type}."),
5654
5717
  // WP-316 S3: Preview gate — dry-run mode for action=create.
5655
- preview: z12.boolean().optional().describe("For 'create': if true, validates the relation without writing. Returns what would happen. Default false."),
5656
- entryId: z12.string().max(200).optional().describe("For 'find'/'suggest': entry ID, e.g. '<PREFIX>-<n>'."),
5657
- direction: z12.enum(["incoming", "outgoing", "both"]).optional().describe("For 'find': 'incoming' = what references this, 'outgoing' = what this references. Default 'both'."),
5658
- limit: z12.number().min(1).max(20).optional().describe("For 'suggest': max suggestions to return. Default 10."),
5659
- depth: z12.number().min(1).max(3).optional().describe("For 'suggest': graph traversal depth. Default 2.")
5718
+ preview: z13.boolean().optional().describe("For 'create': if true, validates the relation without writing. Returns what would happen. Default false."),
5719
+ entryId: z13.string().max(200).optional().describe("For 'find'/'suggest': entry ID, e.g. '<PREFIX>-<n>'."),
5720
+ direction: z13.enum(["incoming", "outgoing", "both"]).optional().describe("For 'find': 'incoming' = what references this, 'outgoing' = what this references. Default 'both'."),
5721
+ limit: z13.number().min(1).max(20).optional().describe("For 'suggest': max suggestions to return. Default 10."),
5722
+ depth: z13.number().min(1).max(3).optional().describe("For 'suggest': graph traversal depth. Default 2.")
5660
5723
  });
5661
- var relationsCreateVariant = z12.object({
5662
- action: z12.literal("create"),
5663
- from: z12.string().max(200),
5664
- to: z12.string().max(200),
5665
- type: z12.string().max(200),
5666
- score: z12.number().optional(),
5667
- preview: z12.boolean().optional()
5724
+ var relationsCreateVariant = z13.object({
5725
+ action: z13.literal("create"),
5726
+ from: z13.string().max(200),
5727
+ to: z13.string().max(200),
5728
+ type: z13.string().max(200),
5729
+ score: z13.number().optional(),
5730
+ preview: z13.boolean().optional()
5668
5731
  });
5669
- var relationsBatchCreateVariant = z12.object({
5670
- action: z12.literal("batch-create"),
5671
- relations: z12.array(relationItemSchema).min(1).max(20)
5732
+ var relationsBatchCreateVariant = z13.object({
5733
+ action: z13.literal("batch-create"),
5734
+ relations: z13.array(relationItemSchema).min(1).max(20)
5672
5735
  });
5673
- var relationsDismissVariant = z12.object({
5674
- action: z12.literal("dismiss"),
5675
- from: z12.string().max(200),
5676
- to: z12.string().max(200),
5677
- type: z12.string().max(200).optional(),
5678
- score: z12.number().optional()
5736
+ var relationsDismissVariant = z13.object({
5737
+ action: z13.literal("dismiss"),
5738
+ from: z13.string().max(200),
5739
+ to: z13.string().max(200),
5740
+ type: z13.string().max(200).optional(),
5741
+ score: z13.number().optional()
5679
5742
  });
5680
- var relationsDeleteVariant = z12.object({
5681
- action: z12.literal("delete"),
5682
- from: z12.string().max(200),
5683
- to: z12.string().max(200),
5684
- type: z12.string().max(200)
5743
+ var relationsDeleteVariant = z13.object({
5744
+ action: z13.literal("delete"),
5745
+ from: z13.string().max(200),
5746
+ to: z13.string().max(200),
5747
+ type: z13.string().max(200)
5685
5748
  });
5686
- var relationsFindVariant = z12.object({
5687
- action: z12.literal("find"),
5688
- entryId: z12.string().max(200),
5689
- direction: z12.enum(["incoming", "outgoing", "both"]).optional().default("both")
5749
+ var relationsFindVariant = z13.object({
5750
+ action: z13.literal("find"),
5751
+ entryId: z13.string().max(200),
5752
+ direction: z13.enum(["incoming", "outgoing", "both"]).optional().default("both")
5690
5753
  });
5691
- var relationsSuggestVariant = z12.object({
5692
- action: z12.literal("suggest"),
5693
- entryId: z12.string().max(200),
5694
- limit: z12.number().min(1).max(20).optional().default(10),
5695
- depth: z12.number().min(1).max(3).optional().default(2)
5754
+ var relationsSuggestVariant = z13.object({
5755
+ action: z13.literal("suggest"),
5756
+ entryId: z13.string().max(200),
5757
+ limit: z13.number().min(1).max(20).optional().default(10),
5758
+ depth: z13.number().min(1).max(3).optional().default(2)
5696
5759
  });
5697
- var relationsActionUnion = z12.discriminatedUnion("action", [
5760
+ var relationsActionUnion = z13.discriminatedUnion("action", [
5698
5761
  relationsCreateVariant,
5699
5762
  relationsBatchCreateVariant,
5700
5763
  relationsDismissVariant,
@@ -6049,19 +6112,19 @@ async function handleDelete(from, to, type) {
6049
6112
  }
6050
6113
 
6051
6114
  // src/tools/context.ts
6052
- import { z as z14 } from "zod/v3";
6115
+ import { z as z15 } from "zod/v3";
6053
6116
 
6054
6117
  // src/tools/documents.ts
6055
- import { z as z13 } from "zod/v3";
6118
+ import { z as z14 } from "zod/v3";
6056
6119
  var DOCUMENTS_ACTIONS = ["get-last-verified-brief"];
6057
- var documentsSchema = z13.object({
6058
- action: z13.enum(DOCUMENTS_ACTIONS).describe(
6120
+ var documentsSchema = z14.object({
6121
+ action: z14.enum(DOCUMENTS_ACTIONS).describe(
6059
6122
  "'get-last-verified-brief': fetch the most recent verified brief snapshot for a (templateId, scopeKey) pair. Returns the verified summary so agents can build delta narratives ('since you last verified, X workstreams advanced')."
6060
6123
  ),
6061
- templateId: z13.string().max(200).describe(
6124
+ templateId: z14.string().max(200).describe(
6062
6125
  "Brief template identifier \u2014 currently 'steering-brief' is the only registered template."
6063
6126
  ),
6064
- scopeKey: z13.string().max(200).describe(
6127
+ scopeKey: z14.string().max(200).describe(
6065
6128
  "Canonical scope key. Use 'workspace:<workspaceId>' for the full workspace brief, or 'initiative:<INI-ID>' for an initiative-scoped brief. The same formula is applied at write time (chainwork/docKernel/scopeKey.ts), so passing the wrong shape returns exists:false."
6066
6129
  )
6067
6130
  });
@@ -6141,89 +6204,89 @@ function epistemicCollectionHint(collectionName) {
6141
6204
  return "";
6142
6205
  }
6143
6206
  var CONTEXT_ACTIONS = ["gather", "build", "neighborhood", "changes", "chain", "cross-cut", "incremental", "brief", "last-verified-brief"];
6144
- var contextSchema = z14.object({
6207
+ var contextSchema = z15.object({
6145
6208
  // provenance: neighborhood BET-142; changes/chain/cross-cut/incremental/brief BET-239 (E4, E6)
6146
- action: z14.enum(CONTEXT_ACTIONS).describe(
6209
+ action: z15.enum(CONTEXT_ACTIONS).describe(
6147
6210
  "'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 + 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."
6148
6211
  ),
6149
- entryId: z14.string().max(200).optional().describe("For 'build'/'neighborhood'/'chain': entry ID, e.g. '<PREFIX>-<n>'. For 'gather': optional entry ID for entry-graph mode."),
6150
- mapEntryId: z14.string().max(200).optional().describe(
6212
+ entryId: z15.string().max(200).optional().describe("For 'build'/'neighborhood'/'chain': entry ID, e.g. '<PREFIX>-<n>'. For 'gather': optional entry ID for entry-graph mode."),
6213
+ mapEntryId: z15.string().max(200).optional().describe(
6151
6214
  "For 'gather': journey map entry ID for journey-aware context. Returns context organised by journey stage. Takes precedence over entryId when both are supplied. Example: '<PREFIX>-<n>'."
6152
6215
  ),
6153
- task: z14.string().max(2e3).optional().describe("For 'gather': natural-language task description for loading task-relevant governance, binding constraints, and supporting context."),
6154
- since: z14.string().max(200).optional().describe(
6216
+ task: z15.string().max(2e3).optional().describe("For 'gather': natural-language task description for loading task-relevant governance, binding constraints, and supporting context."),
6217
+ since: z15.string().max(200).optional().describe(
6155
6218
  "For 'changes': ISO 8601 timestamp \u2014 returns entries/relations modified since this time. For 'brief' briefType='delta': optional custom timestamp. Example: '2026-03-24T00:00:00Z'."
6156
6219
  ),
6157
- direction: z14.enum(["outgoing", "incoming"]).default("outgoing").optional().describe("For 'chain' action: traversal direction. 'outgoing' follows relations from source, 'incoming' follows relations to source. Default: outgoing."),
6158
- relationType: z14.string().max(200).optional().describe(
6220
+ direction: z15.enum(["outgoing", "incoming"]).default("outgoing").optional().describe("For 'chain' action: traversal direction. 'outgoing' follows relations from source, 'incoming' follows relations to source. Default: outgoing."),
6221
+ relationType: z15.string().max(200).optional().describe(
6159
6222
  "Relation type filter. For 'chain': optional filter to traverse only this relation type. For 'cross-cut': required \u2014 scans all relations of this type across the workspace. Examples: 'part_of', 'informs', 'governs', 'blocks', 'depends_on'."
6160
6223
  ),
6161
- mode: z14.enum(["search", "graph"]).default("search").optional().describe("For gather: 'search' (default) or 'graph' (enhanced with provenance paths). Ignored when mapEntryId is provided."),
6162
- maxHops: z14.number().min(1).max(4).default(2).describe("Relation traversal depth (1=direct only, 2=default, 3=wide net, 4=deep chain walk)"),
6163
- maxResults: z14.number().min(1).max(25).default(10).optional().describe("Max entries to return in gather task mode (default 10)"),
6164
- strategy: z14.enum(["hybrid", "keyword"]).default("keyword").optional().describe("Seed strategy for task-based gather: 'keyword' (FTS only, default) or 'hybrid' (vector + FTS). Only affects task mode."),
6165
- skill: z14.string().max(200).optional().describe(
6224
+ mode: z15.enum(["search", "graph"]).default("search").optional().describe("For gather: 'search' (default) or 'graph' (enhanced with provenance paths). Ignored when mapEntryId is provided."),
6225
+ maxHops: z15.number().min(1).max(4).default(2).describe("Relation traversal depth (1=direct only, 2=default, 3=wide net, 4=deep chain walk)"),
6226
+ maxResults: z15.number().min(1).max(25).default(10).optional().describe("Max entries to return in gather task mode (default 10)"),
6227
+ strategy: z15.enum(["hybrid", "keyword"]).default("keyword").optional().describe("Seed strategy for task-based gather: 'keyword' (FTS only, default) or 'hybrid' (vector + FTS). Only affects task mode."),
6228
+ skill: z15.string().max(200).optional().describe(
6166
6229
  "Skill name for 'incremental' action \u2014 identifies which skill's brief history to compare against. Examples: 'preflight', 'shaping', 'review'. Required when action is 'incremental'."
6167
6230
  ),
6168
- briefType: z14.enum(["steering", "confidence", "delta"]).optional().describe(
6231
+ briefType: z15.enum(["steering", "confidence", "delta"]).optional().describe(
6169
6232
  "Compound query type for 'brief' action. 'steering': 7d changes + structural aggregation (part_of, depends_on, constrains) + incremental delta + workspace readiness. 'confidence': 7d changes + active bets summary + active tensions breakdown. 'delta': changes + relations since a custom timestamp (use 'since' param). Required when action is 'brief'."
6170
6233
  ),
6171
- templateId: z14.string().max(200).optional().describe(
6234
+ templateId: z15.string().max(200).optional().describe(
6172
6235
  "For 'last-verified-brief': brief template identifier \u2014 currently 'steering-brief' is the only registered template."
6173
6236
  ),
6174
- scopeKey: z14.string().max(200).optional().describe(
6237
+ scopeKey: z15.string().max(200).optional().describe(
6175
6238
  "For 'last-verified-brief': canonical scope key \u2014 'workspace:<workspaceId>' or 'initiative:<INI-ID>'."
6176
6239
  )
6177
6240
  });
6178
- var contextGatherVariant = z14.object({
6179
- action: z14.literal("gather"),
6180
- entryId: z14.string().max(200).optional(),
6181
- mapEntryId: z14.string().max(200).optional(),
6182
- task: z14.string().max(2e3).optional(),
6183
- mode: z14.enum(["search", "graph"]).optional().default("search"),
6184
- maxHops: z14.number().min(1).max(4).optional().default(2),
6185
- maxResults: z14.number().min(1).max(25).optional().default(10),
6186
- strategy: z14.enum(["hybrid", "keyword"]).optional().default("keyword")
6241
+ var contextGatherVariant = z15.object({
6242
+ action: z15.literal("gather"),
6243
+ entryId: z15.string().max(200).optional(),
6244
+ mapEntryId: z15.string().max(200).optional(),
6245
+ task: z15.string().max(2e3).optional(),
6246
+ mode: z15.enum(["search", "graph"]).optional().default("search"),
6247
+ maxHops: z15.number().min(1).max(4).optional().default(2),
6248
+ maxResults: z15.number().min(1).max(25).optional().default(10),
6249
+ strategy: z15.enum(["hybrid", "keyword"]).optional().default("keyword")
6187
6250
  });
6188
- var contextBuildVariant = z14.object({
6189
- action: z14.literal("build"),
6190
- entryId: z14.string().max(200),
6191
- maxHops: z14.number().min(1).max(4).optional().default(2)
6251
+ var contextBuildVariant = z15.object({
6252
+ action: z15.literal("build"),
6253
+ entryId: z15.string().max(200),
6254
+ maxHops: z15.number().min(1).max(4).optional().default(2)
6192
6255
  });
6193
- var contextNeighborhoodVariant = z14.object({
6194
- action: z14.literal("neighborhood"),
6195
- entryId: z14.string().max(200)
6256
+ var contextNeighborhoodVariant = z15.object({
6257
+ action: z15.literal("neighborhood"),
6258
+ entryId: z15.string().max(200)
6196
6259
  });
6197
- var contextChangesVariant = z14.object({
6198
- action: z14.literal("changes"),
6199
- since: z14.string().max(200)
6260
+ var contextChangesVariant = z15.object({
6261
+ action: z15.literal("changes"),
6262
+ since: z15.string().max(200)
6200
6263
  });
6201
- var contextChainVariant = z14.object({
6202
- action: z14.literal("chain"),
6203
- entryId: z14.string().max(200),
6204
- direction: z14.enum(["outgoing", "incoming"]).optional().default("outgoing"),
6205
- maxHops: z14.number().min(1).max(4).optional().default(2),
6206
- relationType: z14.string().max(200).optional()
6264
+ var contextChainVariant = z15.object({
6265
+ action: z15.literal("chain"),
6266
+ entryId: z15.string().max(200),
6267
+ direction: z15.enum(["outgoing", "incoming"]).optional().default("outgoing"),
6268
+ maxHops: z15.number().min(1).max(4).optional().default(2),
6269
+ relationType: z15.string().max(200).optional()
6207
6270
  });
6208
- var contextCrossCutVariant = z14.object({
6209
- action: z14.literal("cross-cut"),
6210
- relationType: z14.string().max(200)
6271
+ var contextCrossCutVariant = z15.object({
6272
+ action: z15.literal("cross-cut"),
6273
+ relationType: z15.string().max(200)
6211
6274
  });
6212
- var contextIncrementalVariant = z14.object({
6213
- action: z14.literal("incremental"),
6214
- skill: z14.string().max(200)
6275
+ var contextIncrementalVariant = z15.object({
6276
+ action: z15.literal("incremental"),
6277
+ skill: z15.string().max(200)
6215
6278
  });
6216
- var contextBriefVariant = z14.object({
6217
- action: z14.literal("brief"),
6218
- briefType: z14.enum(["steering", "confidence", "delta"]),
6219
- since: z14.string().max(200).optional()
6279
+ var contextBriefVariant = z15.object({
6280
+ action: z15.literal("brief"),
6281
+ briefType: z15.enum(["steering", "confidence", "delta"]),
6282
+ since: z15.string().max(200).optional()
6220
6283
  });
6221
- var contextLastVerifiedBriefVariant = z14.object({
6222
- action: z14.literal("last-verified-brief"),
6223
- templateId: z14.string().max(200),
6224
- scopeKey: z14.string().max(200)
6284
+ var contextLastVerifiedBriefVariant = z15.object({
6285
+ action: z15.literal("last-verified-brief"),
6286
+ templateId: z15.string().max(200),
6287
+ scopeKey: z15.string().max(200)
6225
6288
  });
6226
- var contextActionUnion = z14.discriminatedUnion("action", [
6289
+ var contextActionUnion = z15.discriminatedUnion("action", [
6227
6290
  contextGatherVariant,
6228
6291
  contextBuildVariant,
6229
6292
  contextNeighborhoodVariant,
@@ -7265,20 +7328,20 @@ function formatTimeAgo(ms) {
7265
7328
  }
7266
7329
 
7267
7330
  // src/tools/collections.ts
7268
- import { z as z16 } from "zod/v3";
7331
+ import { z as z17 } from "zod/v3";
7269
7332
 
7270
7333
  // src/tools/labels.ts
7271
- import { z as z15 } from "zod/v3";
7272
- var labelsSchema = z15.object({
7273
- action: z15.enum(["list", "create", "update", "delete", "apply", "remove"]).describe("Action: list all labels, create/update/delete a label, or apply/remove a label on an entry"),
7274
- slug: z15.string().max(200).optional().describe("Label slug (required for create/update/delete/apply/remove)"),
7275
- name: z15.string().max(500).optional().describe("Display name (required for create)"),
7276
- color: z15.string().max(50).optional().describe("Hex color, e.g. '#ef4444'"),
7277
- description: z15.string().max(2e3).optional().describe("What this label means"),
7278
- parentSlug: z15.string().max(200).optional().describe("Parent group slug for label hierarchy"),
7279
- isGroup: z15.boolean().optional().describe("True if this is a group container, not a taggable label"),
7280
- order: z15.number().optional().describe("Sort order within its group"),
7281
- entryId: z15.string().max(200).optional().describe("Entry ID for apply/remove actions")
7334
+ import { z as z16 } from "zod/v3";
7335
+ var labelsSchema = z16.object({
7336
+ action: z16.enum(["list", "create", "update", "delete", "apply", "remove"]).describe("Action: list all labels, create/update/delete a label, or apply/remove a label on an entry"),
7337
+ slug: z16.string().max(200).optional().describe("Label slug (required for create/update/delete/apply/remove)"),
7338
+ name: z16.string().max(500).optional().describe("Display name (required for create)"),
7339
+ color: z16.string().max(50).optional().describe("Hex color, e.g. '#ef4444'"),
7340
+ description: z16.string().max(2e3).optional().describe("What this label means"),
7341
+ parentSlug: z16.string().max(200).optional().describe("Parent group slug for label hierarchy"),
7342
+ isGroup: z16.boolean().optional().describe("True if this is a group container, not a taggable label"),
7343
+ order: z16.number().optional().describe("Sort order within its group"),
7344
+ entryId: z16.string().max(200).optional().describe("Entry ID for apply/remove actions")
7282
7345
  });
7283
7346
  async function handleLabelsList() {
7284
7347
  const labels = await kernelQuery("chain.listLabels");
@@ -7382,118 +7445,118 @@ var COLLECTIONS_ACTIONS = [
7382
7445
  "label-apply",
7383
7446
  "label-remove"
7384
7447
  ];
7385
- var qualityCriterionSchema = z16.object({
7386
- field: z16.string().max(200).describe("Entry data field key this criterion applies to, e.g. 'description', 'owner'"),
7448
+ var qualityCriterionSchema = z17.object({
7449
+ field: z17.string().max(200).describe("Entry data field key this criterion applies to, e.g. 'description', 'owner'"),
7387
7450
  // WP-480 S1: `max_length` — must mirror the Convex rule union, or the tool rejects a
7388
7451
  // valid criterion before the request ever reaches the server.
7389
- rule: z16.enum(["required", "min_length", "max_length", "pattern"]).describe("'required': field must be non-empty (blocks accept). 'min_length': minimum string length (warns). 'max_length': maximum string length (warns). 'pattern': regex match (warns)."),
7390
- value: z16.string().max(500).optional().describe("For min_length/max_length: the length bound as a string integer. For pattern: the regex string. Unused for 'required'.")
7452
+ rule: z17.enum(["required", "min_length", "max_length", "pattern"]).describe("'required': field must be non-empty (blocks accept). 'min_length': minimum string length (warns). 'max_length': maximum string length (warns). 'pattern': regex match (warns)."),
7453
+ value: z17.string().max(500).optional().describe("For min_length/max_length: the length bound as a string integer. For pattern: the regex string. Unused for 'required'.")
7391
7454
  });
7392
- var fieldSchema = z16.object({
7393
- key: z16.string().max(200).describe("Field key, e.g. 'description', 'severity', 'status'"),
7394
- label: z16.string().max(200).describe("Display label, e.g. 'Description', 'Severity'"),
7395
- type: z16.string().max(50).describe("Field type: 'string', 'select', 'array', 'number', 'boolean'"),
7396
- required: z16.boolean().optional().describe("Whether this field is required"),
7397
- options: z16.array(z16.string().max(200)).max(200).optional().describe("Options for 'select' type fields"),
7398
- searchable: z16.boolean().optional().describe("Whether this field is included in full-text search"),
7399
- displayHint: z16.enum(["hero", "badge", "meta", "section", "hidden", "inline-meta"]).optional().describe("V2 rendering hint: how the field should be displayed in Cortex"),
7400
- zone: z16.enum(["header", "body", "meta"]).optional().describe("V2 layout zone: where the field appears in the entry view"),
7401
- colorMap: z16.record(z16.string().max(50)).optional().describe("V2 value-to-semantic-color mapping, e.g. { critical: 'danger', low: 'success' }"),
7455
+ var fieldSchema = z17.object({
7456
+ key: z17.string().max(200).describe("Field key, e.g. 'description', 'severity', 'status'"),
7457
+ label: z17.string().max(200).describe("Display label, e.g. 'Description', 'Severity'"),
7458
+ type: z17.string().max(50).describe("Field type: 'string', 'select', 'array', 'number', 'boolean'"),
7459
+ required: z17.boolean().optional().describe("Whether this field is required"),
7460
+ options: z17.array(z17.string().max(200)).max(200).optional().describe("Options for 'select' type fields"),
7461
+ searchable: z17.boolean().optional().describe("Whether this field is included in full-text search"),
7462
+ displayHint: z17.enum(["hero", "badge", "meta", "section", "hidden", "inline-meta"]).optional().describe("V2 rendering hint: how the field should be displayed in Cortex"),
7463
+ zone: z17.enum(["header", "body", "meta"]).optional().describe("V2 layout zone: where the field appears in the entry view"),
7464
+ colorMap: z17.record(z17.string().max(50)).optional().describe("V2 value-to-semantic-color mapping, e.g. { critical: 'danger', low: 'success' }"),
7402
7465
  // ENT-61
7403
- accentSource: z16.boolean().optional().describe("When true, this field's colorMap value drives the card-level accent styling"),
7466
+ accentSource: z17.boolean().optional().describe("When true, this field's colorMap value drives the card-level accent styling"),
7404
7467
  // ENT-61
7405
- iconMap: z16.record(z16.string(), z16.string().max(50)).optional().describe("Maps field values to icons (emoji/symbol), prepended to badge text"),
7406
- helpText: z16.string().max(2e3).optional().describe("Help text shown in editors and describe output"),
7407
- optionDescriptions: z16.record(z16.string().max(500)).optional().describe("Per-option guidance for select fields"),
7468
+ iconMap: z17.record(z17.string(), z17.string().max(50)).optional().describe("Maps field values to icons (emoji/symbol), prepended to badge text"),
7469
+ helpText: z17.string().max(2e3).optional().describe("Help text shown in editors and describe output"),
7470
+ optionDescriptions: z17.record(z17.string().max(500)).optional().describe("Per-option guidance for select fields"),
7408
7471
  // BET-136
7409
- semanticRole: z16.enum(["problem", "appetite", "elements", "architecture", "done_when", "risks", "exclusions"]).optional().describe("Semantic role for schema-driven consumers \u2014 enables field-key-independent validation and rendering"),
7472
+ semanticRole: z17.enum(["problem", "appetite", "elements", "architecture", "done_when", "risks", "exclusions"]).optional().describe("Semantic role for schema-driven consumers \u2014 enables field-key-independent validation and rendering"),
7410
7473
  // BET-196
7411
- maxLength: z16.number().optional().describe("Maximum character length for field values. Three-tier resolution: explicit > displayHint > type fallback."),
7474
+ maxLength: z17.number().optional().describe("Maximum character length for field values. Three-tier resolution: explicit > displayHint > type fallback."),
7412
7475
  // BET-196
7413
- minLength: z16.number().optional().describe("Minimum character length for field values. Only explicit \u2014 no defaults.")
7476
+ minLength: z17.number().optional().describe("Minimum character length for field values. Only explicit \u2014 no defaults.")
7414
7477
  });
7415
- var collectionsSchema = z16.object({
7416
- action: z16.enum(COLLECTIONS_ACTIONS).describe(
7478
+ var collectionsSchema = z17.object({
7479
+ action: z17.enum(COLLECTIONS_ACTIONS).describe(
7417
7480
  "'list': browse all collections. 'update': update an existing collection. 'describe': full documentation for one collection \u2014 fields, option guides, usage guidance, examples. 'audit': health report for all collections \u2014 missing classification, icon, displayHint coverage, and field schema gaps. 'export': full system_collection_definitions export with classification metadata (thinkingLayer, classificationPriority, classificationCheck, classificationSignals, governanceRole, governanceFunction, timelineRole, canBeElementOf, descriptionFieldKey). Admin only. 'label-list'/'label-create'/'label-update'/'label-delete'/'label-apply'/'label-remove': manage workspace labels (absorbs the `labels` tool). Creating a new collection is not offered here \u2014 ask a platform admin to provision it, or enable the module ontology pack that owns the drawer."
7418
7481
  ),
7419
- slug: z16.string().max(200).optional().describe("URL-safe identifier for create/update, e.g. 'glossary', 'tech-debt'. For label-*: label slug."),
7420
- name: z16.string().max(500).optional().describe("Display name for create, or new name for update. For label-create: label display name."),
7421
- description: z16.string().max(2e4).optional().describe("What this collection is for. For label-create/label-update: what the label means."),
7422
- purpose: z16.string().max(2e3).optional().describe("Why this collection exists \u2014 strategic reason"),
7423
- icon: z16.string().max(50).optional().describe("Emoji icon for the collection"),
7424
- navGroup: z16.enum(["daily", "strategic", "governance", "reference", "collections"]).optional().describe("Sidebar placement: 'daily', 'strategic', 'governance', 'reference', 'collections'"),
7425
- fields: z16.array(fieldSchema).max(200).optional().describe("Field definitions for create, or replacement schema for update (replaces all fields)"),
7426
- axis: z16.enum(["work", "none", "pending"]).optional().describe("REQUIRED for create: 'work' (needs stageLabelMap + validWorkflowStatuses), 'none', or 'pending'. For update: only settable on a non-system-stratum (custom) collection \u2014 the repair path for a legacy collection that predates the axis contract."),
7427
- stageLabelMap: z16.record(z16.string(), z16.enum(["open", "in_progress", "done", "stopped", "tag"])).optional().describe("Required when axis is 'work': maps each valid workflowStatus to a canonical stage."),
7482
+ slug: z17.string().max(200).optional().describe("URL-safe identifier for create/update, e.g. 'glossary', 'tech-debt'. For label-*: label slug."),
7483
+ name: z17.string().max(500).optional().describe("Display name for create, or new name for update. For label-create: label display name."),
7484
+ description: z17.string().max(2e4).optional().describe("What this collection is for. For label-create/label-update: what the label means."),
7485
+ purpose: z17.string().max(2e3).optional().describe("Why this collection exists \u2014 strategic reason"),
7486
+ icon: z17.string().max(50).optional().describe("Emoji icon for the collection"),
7487
+ navGroup: z17.enum(["daily", "strategic", "governance", "reference", "collections"]).optional().describe("Sidebar placement: 'daily', 'strategic', 'governance', 'reference', 'collections'"),
7488
+ fields: z17.array(fieldSchema).max(200).optional().describe("Field definitions for create, or replacement schema for update (replaces all fields)"),
7489
+ axis: z17.enum(["work", "none", "pending"]).optional().describe("REQUIRED for create: 'work' (needs stageLabelMap + validWorkflowStatuses), 'none', or 'pending'. For update: only settable on a non-system-stratum (custom) collection \u2014 the repair path for a legacy collection that predates the axis contract."),
7490
+ stageLabelMap: z17.record(z17.string(), z17.enum(["open", "in_progress", "done", "stopped", "tag"])).optional().describe("Required when axis is 'work': maps each valid workflowStatus to a canonical stage."),
7428
7491
  // ENT-62
7429
- defaultCanonicalKey: z16.string().max(200).optional().describe("The canonical_key entries in this collection default to (e.g. 'decision', 'insight'). Consumers read from collection doc; code map is fallback."),
7492
+ defaultCanonicalKey: z17.string().max(200).optional().describe("The canonical_key entries in this collection default to (e.g. 'decision', 'insight'). Consumers read from collection doc; code map is fallback."),
7430
7493
  // ENT-67
7431
- defaultWorkflowStatus: z16.string().max(200).optional().describe("Default workflowStatus for new entries. Must be in validWorkflowStatuses when set (e.g. 'hypothesis' for insights)."),
7494
+ defaultWorkflowStatus: z17.string().max(200).optional().describe("Default workflowStatus for new entries. Must be in validWorkflowStatuses when set (e.g. 'hypothesis' for insights)."),
7432
7495
  // ENT-65
7433
- validWorkflowStatuses: z16.array(z16.string().max(200)).max(50).optional().describe("The allowed workflowStatus values for entries in this collection. New entries are validated against this list. Empty array means no constraint."),
7496
+ validWorkflowStatuses: z17.array(z17.string().max(200)).max(50).optional().describe("The allowed workflowStatus values for entries in this collection. New entries are validated against this list. Empty array means no constraint."),
7434
7497
  // ENT-65, FEAT-200
7435
- classificationCheck: z16.string().max(500).optional().describe("LLM decision-tree check for this collection (3\u2013500 chars). Guides the classifier in routing entries here."),
7498
+ classificationCheck: z17.string().max(500).optional().describe("LLM decision-tree check for this collection (3\u2013500 chars). Guides the classifier in routing entries here."),
7436
7499
  // ENT-65, FEAT-200
7437
- classificationPriority: z16.number().optional().describe("Classifier priority (1\u20139, lower = higher priority). Used with classificationCheck to order the decision tree."),
7500
+ classificationPriority: z17.number().optional().describe("Classifier priority (1\u20139, lower = higher priority). Used with classificationCheck to order the decision tree."),
7438
7501
  // FEAT-301 Slice 2: quality gate criteria and usage guidance.
7439
7502
  // FEAT-257
7440
- qualityCriteria: z16.array(qualityCriterionSchema).max(50).optional().describe("Per-collection accept gate rules. 'required' rule hard-blocks accepts on empty fields; 'min_length'/'pattern' rules warn. Pass an empty array to clear all criteria."),
7441
- usageGuidance: z16.string().max(2e4).optional().describe("Plain-text guidance shown to agents and users: when to use this collection, when not to, and what makes a good entry."),
7503
+ qualityCriteria: z17.array(qualityCriterionSchema).max(50).optional().describe("Per-collection accept gate rules. 'required' rule hard-blocks accepts on empty fields; 'min_length'/'pattern' rules warn. Pass an empty array to clear all criteria."),
7504
+ usageGuidance: z17.string().max(2e4).optional().describe("Plain-text guidance shown to agents and users: when to use this collection, when not to, and what makes a good entry."),
7442
7505
  // For label-*
7443
- color: z16.string().max(50).optional().describe("For label-create/label-update: hex color, e.g. '#ef4444'."),
7444
- parentSlug: z16.string().max(200).optional().describe("For label-create: parent group slug for label hierarchy."),
7445
- isGroup: z16.boolean().optional().describe("For label-create/label-update: true if this is a group container, not a taggable label."),
7446
- order: z16.number().optional().describe("For label-create/label-update: sort order within its group."),
7447
- entryId: z16.string().max(200).optional().describe("For label-apply/label-remove: entry ID.")
7506
+ color: z17.string().max(50).optional().describe("For label-create/label-update: hex color, e.g. '#ef4444'."),
7507
+ parentSlug: z17.string().max(200).optional().describe("For label-create: parent group slug for label hierarchy."),
7508
+ isGroup: z17.boolean().optional().describe("For label-create/label-update: true if this is a group container, not a taggable label."),
7509
+ order: z17.number().optional().describe("For label-create/label-update: sort order within its group."),
7510
+ entryId: z17.string().max(200).optional().describe("For label-apply/label-remove: entry ID.")
7448
7511
  });
7449
- var collectionsListVariant = z16.object({ action: z16.literal("list") });
7450
- var collectionsDescribeVariant = z16.object({ action: z16.literal("describe"), slug: z16.string().max(200) });
7451
- var collectionsUpdateVariant = z16.object({
7452
- action: z16.literal("update"),
7453
- slug: z16.string().max(200),
7454
- name: z16.string().max(500).optional(),
7455
- description: z16.string().max(2e4).optional(),
7456
- purpose: z16.string().max(2e3).optional(),
7457
- icon: z16.string().max(50).optional(),
7458
- navGroup: z16.enum(["daily", "strategic", "governance", "reference", "collections"]).optional(),
7459
- fields: z16.array(fieldSchema).optional(),
7460
- axis: z16.enum(["work", "none", "pending"]).optional(),
7461
- stageLabelMap: z16.record(z16.string(), z16.enum(["open", "in_progress", "done", "stopped", "tag"])).optional(),
7512
+ var collectionsListVariant = z17.object({ action: z17.literal("list") });
7513
+ var collectionsDescribeVariant = z17.object({ action: z17.literal("describe"), slug: z17.string().max(200) });
7514
+ var collectionsUpdateVariant = z17.object({
7515
+ action: z17.literal("update"),
7516
+ slug: z17.string().max(200),
7517
+ name: z17.string().max(500).optional(),
7518
+ description: z17.string().max(2e4).optional(),
7519
+ purpose: z17.string().max(2e3).optional(),
7520
+ icon: z17.string().max(50).optional(),
7521
+ navGroup: z17.enum(["daily", "strategic", "governance", "reference", "collections"]).optional(),
7522
+ fields: z17.array(fieldSchema).optional(),
7523
+ axis: z17.enum(["work", "none", "pending"]).optional(),
7524
+ stageLabelMap: z17.record(z17.string(), z17.enum(["open", "in_progress", "done", "stopped", "tag"])).optional(),
7462
7525
  // WP-640 SWEEP (P1): axis/stageLabelMap repair legacy custom collections — see collections.ts's updateCollection.
7463
- defaultCanonicalKey: z16.string().max(200).optional(),
7464
- defaultWorkflowStatus: z16.string().max(200).optional(),
7465
- validWorkflowStatuses: z16.array(z16.string().max(200)).optional(),
7466
- classificationCheck: z16.string().max(500).optional(),
7467
- classificationPriority: z16.number().optional(),
7468
- qualityCriteria: z16.array(qualityCriterionSchema).optional(),
7469
- usageGuidance: z16.string().max(2e4).optional()
7526
+ defaultCanonicalKey: z17.string().max(200).optional(),
7527
+ defaultWorkflowStatus: z17.string().max(200).optional(),
7528
+ validWorkflowStatuses: z17.array(z17.string().max(200)).optional(),
7529
+ classificationCheck: z17.string().max(500).optional(),
7530
+ classificationPriority: z17.number().optional(),
7531
+ qualityCriteria: z17.array(qualityCriterionSchema).optional(),
7532
+ usageGuidance: z17.string().max(2e4).optional()
7470
7533
  });
7471
- var collectionsAuditVariant = z16.object({ action: z16.literal("audit") });
7472
- var collectionsExportVariant = z16.object({ action: z16.literal("export") });
7473
- var collectionsLabelListVariant = z16.object({ action: z16.literal("label-list") });
7474
- var collectionsLabelCreateVariant = z16.object({
7475
- action: z16.literal("label-create"),
7476
- slug: z16.string().max(200),
7477
- name: z16.string().max(500),
7478
- color: z16.string().max(50).optional(),
7479
- description: z16.string().max(2e3).optional(),
7480
- parentSlug: z16.string().max(200).optional(),
7481
- isGroup: z16.boolean().optional(),
7482
- order: z16.number().optional()
7534
+ var collectionsAuditVariant = z17.object({ action: z17.literal("audit") });
7535
+ var collectionsExportVariant = z17.object({ action: z17.literal("export") });
7536
+ var collectionsLabelListVariant = z17.object({ action: z17.literal("label-list") });
7537
+ var collectionsLabelCreateVariant = z17.object({
7538
+ action: z17.literal("label-create"),
7539
+ slug: z17.string().max(200),
7540
+ name: z17.string().max(500),
7541
+ color: z17.string().max(50).optional(),
7542
+ description: z17.string().max(2e3).optional(),
7543
+ parentSlug: z17.string().max(200).optional(),
7544
+ isGroup: z17.boolean().optional(),
7545
+ order: z17.number().optional()
7483
7546
  });
7484
- var collectionsLabelUpdateVariant = z16.object({
7485
- action: z16.literal("label-update"),
7486
- slug: z16.string().max(200),
7487
- name: z16.string().max(500).optional(),
7488
- color: z16.string().max(50).optional(),
7489
- description: z16.string().max(2e3).optional(),
7490
- isGroup: z16.boolean().optional(),
7491
- order: z16.number().optional()
7547
+ var collectionsLabelUpdateVariant = z17.object({
7548
+ action: z17.literal("label-update"),
7549
+ slug: z17.string().max(200),
7550
+ name: z17.string().max(500).optional(),
7551
+ color: z17.string().max(50).optional(),
7552
+ description: z17.string().max(2e3).optional(),
7553
+ isGroup: z17.boolean().optional(),
7554
+ order: z17.number().optional()
7492
7555
  });
7493
- var collectionsLabelDeleteVariant = z16.object({ action: z16.literal("label-delete"), slug: z16.string().max(200) });
7494
- var collectionsLabelApplyVariant = z16.object({ action: z16.literal("label-apply"), slug: z16.string().max(200), entryId: z16.string().max(200) });
7495
- var collectionsLabelRemoveVariant = z16.object({ action: z16.literal("label-remove"), slug: z16.string().max(200), entryId: z16.string().max(200) });
7496
- var collectionsActionUnion = z16.discriminatedUnion("action", [
7556
+ var collectionsLabelDeleteVariant = z17.object({ action: z17.literal("label-delete"), slug: z17.string().max(200) });
7557
+ var collectionsLabelApplyVariant = z17.object({ action: z17.literal("label-apply"), slug: z17.string().max(200), entryId: z17.string().max(200) });
7558
+ var collectionsLabelRemoveVariant = z17.object({ action: z17.literal("label-remove"), slug: z17.string().max(200), entryId: z17.string().max(200) });
7559
+ var collectionsActionUnion = z17.discriminatedUnion("action", [
7497
7560
  collectionsListVariant,
7498
7561
  collectionsDescribeVariant,
7499
7562
  collectionsUpdateVariant,
@@ -7795,7 +7858,7 @@ async function handleExport() {
7795
7858
  }
7796
7859
 
7797
7860
  // src/tools/orient.ts
7798
- import { z as z20 } from "zod/v3";
7861
+ import { z as z21 } from "zod/v3";
7799
7862
 
7800
7863
  // src/tools/planned-work.ts
7801
7864
  function buildPlannedWork(allEntries) {
@@ -8819,12 +8882,12 @@ function replaceVocabTokens(body, workspaceCtx, collectionCtxMap) {
8819
8882
  }
8820
8883
 
8821
8884
  // src/tools/start_pb.ts
8822
- import { z as z18 } from "zod/v3";
8885
+ import { z as z19 } from "zod/v3";
8823
8886
 
8824
8887
  // src/tools/skills.ts
8825
- import { z as z17 } from "zod/v3";
8826
- var skillsSchema = z17.object({
8827
- entryId: z17.string().min(1).describe(
8888
+ import { z as z18 } from "zod/v3";
8889
+ var skillsSchema = z18.object({
8890
+ entryId: z18.string().min(1).describe(
8828
8891
  "Workspace-scoped skill entry id (e.g. 'SKILL-pb-setup'). The tool refuses non-skill entries (canonicalKey !== 'skill') with INVALID_KIND."
8829
8892
  )
8830
8893
  });
@@ -8930,8 +8993,8 @@ function formatAdoptDiscoveryLine(display) {
8930
8993
  }
8931
8994
 
8932
8995
  // src/tools/start_pb.ts
8933
- var startPbSchema = z18.object({
8934
- task: z18.string().max(2e3).optional().describe(
8996
+ var startPbSchema = z19.object({
8997
+ task: z19.string().max(2e3).optional().describe(
8935
8998
  "What you're about to work on (e.g. 'implementing auth middleware'). Grounded/connected workspaces: filters governance to show relevant principles, standards, and business rules. Blank/seeded workspaces: ignored (setup flow takes over)."
8936
8999
  )
8937
9000
  // TEN-2431: no `scope` param — start_pb's governance matches orient's scope-BLIND RENDERED
@@ -9289,15 +9352,15 @@ ${FEEDBACK_SUBMIT_HINT}` }],
9289
9352
  }
9290
9353
 
9291
9354
  // src/tools/record_activation.ts
9292
- import { z as z19 } from "zod/v3";
9293
- var recordActivationSchema = z19.object({
9294
- confirmedEntryCount: z19.number().int().min(0).describe(
9355
+ import { z as z20 } from "zod/v3";
9356
+ var recordActivationSchema = z20.object({
9357
+ confirmedEntryCount: z20.number().int().min(0).describe(
9295
9358
  "Confirmed-entry count from the Phase 4 capture loop. The mutation enforces >=10."
9296
9359
  ),
9297
- entriesAcrossCollections: z19.number().int().min(0).describe(
9360
+ entriesAcrossCollections: z20.number().int().min(0).describe(
9298
9361
  "Number of distinct collections those entries span. The mutation enforces >=2 (diversity soft-gate)."
9299
9362
  ),
9300
- retrievalDemoConfirmed: z19.boolean().describe(
9363
+ retrievalDemoConfirmed: z20.boolean().describe(
9301
9364
  "True if the retrieval round-trip ran successfully in Phase 4. The mutation rejects false."
9302
9365
  )
9303
9366
  });
@@ -9370,65 +9433,65 @@ async function markOrientedWithSnapshotFallback(agentSessionId, coherenceSnapsho
9370
9433
  }
9371
9434
  }
9372
9435
  var ORIENT_ACTIONS = ["start", "task", "record-activation"];
9373
- var orientSchema = z20.object({
9374
- action: z20.enum(ORIENT_ACTIONS).optional().default("task").describe(
9436
+ var orientSchema = z21.object({
9437
+ action: z21.enum(ORIENT_ACTIONS).optional().default("task").describe(
9375
9438
  "'start': universal session opener (absorbs start_pb) \u2014 stage-aware setup skill or standup briefing. 'task': task-grounded context loader \u2014 the original orient behavior. 'record-activation': chat-only activation receipt writer (absorbs record_activation)."
9376
9439
  ),
9377
- mode: z20.enum(["full", "brief"]).optional().default("full").describe("For 'task': full = full context (default). brief = compact summary for mid-session re-orientation. Prefer using the `tier` param for depth control."),
9378
- tier: z20.enum(["summary", "standard", "full"]).optional().describe(
9440
+ mode: z21.enum(["full", "brief"]).optional().default("full").describe("For 'task': full = full context (default). brief = compact summary for mid-session re-orientation. Prefer using the `tier` param for depth control."),
9441
+ tier: z21.enum(["summary", "standard", "full"]).optional().describe(
9379
9442
  "For 'task': payload depth. Defaults to summary (~10 KB) when task is provided; standard (~256 KB) when task is absent. Pass summary, standard, or full to override."
9380
9443
  ),
9381
- task: z20.string().max(2e3).optional().describe(
9444
+ task: z21.string().max(2e3).optional().describe(
9382
9445
  "For 'task': natural-language task description for task-scoped context. For 'start': what you're about to work on. When provided to 'task', orient returns scored, relevant entries for the task."
9383
9446
  ),
9384
- scope: z20.string().max(200).optional().describe("For 'task': optional domain scope to filter governance to entries relevant for this domain. Forwarded to Convex for workspace-specific validation."),
9447
+ scope: z21.string().max(200).optional().describe("For 'task': optional domain scope to filter governance to entries relevant for this domain. Forwarded to Convex for workspace-specific validation."),
9385
9448
  // WP-486 Slice 1 (FEAT-1371, TEN-2724): the startup-signal envelope `resolveStartupDomain` already
9386
9449
  // consumes (`startupResolver.ts:344-379`) but this tool never sent. Nested to match the server's
9387
9450
  // `StartupResolutionSignals` shape exactly — every field optional, sanitized server-side.
9388
- startupSignals: z20.object({
9389
- changedPaths: z20.array(z20.string()).max(25).optional().describe("Paths changed in the current working tree, if known (e.g. from a prior git status/diff tool call)."),
9390
- reviewedArtifactRefs: z20.array(z20.string()).max(25).optional().describe("Chain entry IDs the caller has already reviewed this session, if tracked."),
9391
- branchName: z20.string().max(120).optional().describe("Current git branch name, if known."),
9392
- worktreeName: z20.string().max(120).optional().describe("Current worktree/directory name, if known.")
9451
+ startupSignals: z21.object({
9452
+ changedPaths: z21.array(z21.string()).max(25).optional().describe("Paths changed in the current working tree, if known (e.g. from a prior git status/diff tool call)."),
9453
+ reviewedArtifactRefs: z21.array(z21.string()).max(25).optional().describe("Chain entry IDs the caller has already reviewed this session, if tracked."),
9454
+ branchName: z21.string().max(120).optional().describe("Current git branch name, if known."),
9455
+ worktreeName: z21.string().max(120).optional().describe("Current worktree/directory name, if known.")
9393
9456
  }).optional().describe("For 'task': best-effort startup signals for domain resolution \u2014 changedPaths/reviewedArtifactRefs/branchName/worktreeName. All optional; omit fields you don't know."),
9394
- invocationPath: z20.enum(["session-start", "session-close", "manual-orient", "handshake", "unknown"]).optional().describe("For 'task': how this orient was invoked. Defaults to 'manual-orient' (the direct `orient task=...` call shape) when omitted."),
9395
- confirmedEntryCount: z20.number().int().min(0).optional().describe(
9457
+ invocationPath: z21.enum(["session-start", "session-close", "manual-orient", "handshake", "unknown"]).optional().describe("For 'task': how this orient was invoked. Defaults to 'manual-orient' (the direct `orient task=...` call shape) when omitted."),
9458
+ confirmedEntryCount: z21.number().int().min(0).optional().describe(
9396
9459
  "For 'record-activation': confirmed-entry count from the Phase 4 capture loop. The mutation enforces >=10."
9397
9460
  ),
9398
- entriesAcrossCollections: z20.number().int().min(0).optional().describe(
9461
+ entriesAcrossCollections: z21.number().int().min(0).optional().describe(
9399
9462
  "For 'record-activation': number of distinct collections those entries span. The mutation enforces >=2 (diversity soft-gate)."
9400
9463
  ),
9401
- retrievalDemoConfirmed: z20.boolean().optional().describe(
9464
+ retrievalDemoConfirmed: z21.boolean().optional().describe(
9402
9465
  "For 'record-activation': true if the retrieval round-trip ran successfully in Phase 4. The mutation rejects false."
9403
9466
  )
9404
9467
  });
9405
- var orientStartVariant = z20.object({
9406
- action: z20.literal("start"),
9407
- task: z20.string().max(2e3).optional()
9468
+ var orientStartVariant = z21.object({
9469
+ action: z21.literal("start"),
9470
+ task: z21.string().max(2e3).optional()
9408
9471
  });
9409
- var orientTaskVariant = z20.object({
9410
- action: z20.literal("task"),
9411
- mode: z20.enum(["full", "brief"]).optional().default("full"),
9412
- tier: z20.enum(["summary", "standard", "full"]).optional(),
9413
- task: z20.string().max(2e3).optional(),
9414
- scope: z20.string().max(200).optional(),
9472
+ var orientTaskVariant = z21.object({
9473
+ action: z21.literal("task"),
9474
+ mode: z21.enum(["full", "brief"]).optional().default("full"),
9475
+ tier: z21.enum(["summary", "standard", "full"]).optional(),
9476
+ task: z21.string().max(2e3).optional(),
9477
+ scope: z21.string().max(200).optional(),
9415
9478
  // WP-486 Slice 1 (FEAT-1371) — mirrors orientSchema's top-level declaration above; see its
9416
9479
  // doc comment for the shape rationale.
9417
- startupSignals: z20.object({
9418
- changedPaths: z20.array(z20.string()).max(25).optional(),
9419
- reviewedArtifactRefs: z20.array(z20.string()).max(25).optional(),
9420
- branchName: z20.string().max(120).optional(),
9421
- worktreeName: z20.string().max(120).optional()
9480
+ startupSignals: z21.object({
9481
+ changedPaths: z21.array(z21.string()).max(25).optional(),
9482
+ reviewedArtifactRefs: z21.array(z21.string()).max(25).optional(),
9483
+ branchName: z21.string().max(120).optional(),
9484
+ worktreeName: z21.string().max(120).optional()
9422
9485
  }).optional(),
9423
- invocationPath: z20.enum(["session-start", "session-close", "manual-orient", "handshake", "unknown"]).optional()
9486
+ invocationPath: z21.enum(["session-start", "session-close", "manual-orient", "handshake", "unknown"]).optional()
9424
9487
  });
9425
- var orientRecordActivationVariant = z20.object({
9426
- action: z20.literal("record-activation"),
9427
- confirmedEntryCount: z20.number().int().min(0),
9428
- entriesAcrossCollections: z20.number().int().min(0),
9429
- retrievalDemoConfirmed: z20.boolean()
9488
+ var orientRecordActivationVariant = z21.object({
9489
+ action: z21.literal("record-activation"),
9490
+ confirmedEntryCount: z21.number().int().min(0),
9491
+ entriesAcrossCollections: z21.number().int().min(0),
9492
+ retrievalDemoConfirmed: z21.boolean()
9430
9493
  });
9431
- var orientActionUnion = z20.discriminatedUnion("action", [
9494
+ var orientActionUnion = z21.discriminatedUnion("action", [
9432
9495
  orientStartVariant,
9433
9496
  orientTaskVariant,
9434
9497
  orientRecordActivationVariant
@@ -10289,7 +10352,7 @@ async function _handleOrient({ mode = "full", tier, task, scope, startupSignals,
10289
10352
  }
10290
10353
 
10291
10354
  // src/tools/workflows.ts
10292
- import { z as z21 } from "zod/v3";
10355
+ import { z as z22 } from "zod/v3";
10293
10356
 
10294
10357
  // src/workflows/descriptor.ts
10295
10358
  function cloneWorkflowQuestion(question) {
@@ -11129,75 +11192,75 @@ function workflowRunOutputToText(output) {
11129
11192
 
11130
11193
  // src/tools/workflows.ts
11131
11194
  var WORKFLOWS_ACTIONS = ["list", "start", "checkpoint", "get-run", "load-skill"];
11132
- var jsonValueSchema = z21.lazy(
11133
- () => z21.union([
11134
- z21.string(),
11135
- z21.number(),
11136
- z21.boolean(),
11137
- z21.null(),
11138
- z21.array(jsonValueSchema),
11139
- z21.record(jsonValueSchema)
11195
+ var jsonValueSchema = z22.lazy(
11196
+ () => z22.union([
11197
+ z22.string(),
11198
+ z22.number(),
11199
+ z22.boolean(),
11200
+ z22.null(),
11201
+ z22.array(jsonValueSchema),
11202
+ z22.record(jsonValueSchema)
11140
11203
  ])
11141
11204
  );
11142
- var workflowRunOutputInputSchema = z21.union([
11143
- z21.object({
11144
- format: z21.literal("freetext"),
11145
- value: z21.string()
11205
+ var workflowRunOutputInputSchema = z22.union([
11206
+ z22.object({
11207
+ format: z22.literal("freetext"),
11208
+ value: z22.string()
11146
11209
  }),
11147
- z21.object({
11148
- format: z21.literal("list"),
11149
- value: z21.array(z21.string())
11210
+ z22.object({
11211
+ format: z22.literal("list"),
11212
+ value: z22.array(z22.string())
11150
11213
  }),
11151
- z21.object({
11152
- format: z21.literal("choice"),
11153
- value: z21.union([z21.string(), z21.array(z21.string())])
11214
+ z22.object({
11215
+ format: z22.literal("choice"),
11216
+ value: z22.union([z22.string(), z22.array(z22.string())])
11154
11217
  }),
11155
- z21.object({
11156
- format: z21.literal("structured"),
11218
+ z22.object({
11219
+ format: z22.literal("structured"),
11157
11220
  value: jsonValueSchema
11158
11221
  })
11159
11222
  ]);
11160
- var workflowsSchema = z21.object({
11161
- action: z21.enum(WORKFLOWS_ACTIONS).describe(
11223
+ var workflowsSchema = z22.object({
11224
+ action: z22.enum(WORKFLOWS_ACTIONS).describe(
11162
11225
  "'list': browse available workflows. 'start': start or resume a workflow \u2014 returns first (or current) round and next-step checkpoint call. 'checkpoint': record round output or final summary. 'get-run': inspect a persisted workflow run. 'load-skill': load the markdown body of a SKILL-* entry from the workspace (absorbs the `skills` tool). Requires entryId."
11163
11226
  ),
11164
- workflowId: z21.string().max(200).optional().describe("Workflow ID for start, checkpoint, or get-run, e.g. 'retro', 'implementation-review'"),
11165
- runId: z21.string().max(200).optional().describe("Workflow run ID: for get-run, which run to load; for checkpoint, target this run (avoids session drift \u2014 pass runId from get-run)."),
11166
- roundId: z21.string().max(200).optional().describe("Round ID for checkpoint, e.g. 'what-went-well'"),
11167
- output: z21.union([z21.string(), workflowRunOutputInputSchema]).optional().describe("The round's output \u2014 either legacy synthesized text or a typed workflow run payload."),
11168
- isFinal: z21.boolean().optional().describe("If true, finalize an existing durable workflow run from its terminal round and create the summary chain entry."),
11169
- restart: z21.boolean().optional().describe("If true, start a new durable run from the workflow's first round in the current session."),
11170
- summaryName: z21.string().max(500).optional().describe("Optional name for final chain entry. If omitted, the workflow summary template is used."),
11171
- summaryDescription: z21.string().max(2e4).optional().describe("Optional override for the final chain entry description. Defaults to the final round output text."),
11172
- summaryEntryId: z21.string().max(200).optional().describe("Link an existing entry as the run's summary instead of creating one. Used by facilitated workflows (e.g. shape) where the primary record is created by the specialized tool."),
11173
- entryId: z21.string().max(200).optional().describe("For 'load-skill': workspace-scoped skill entry id (e.g. 'SKILL-pb-setup'). Refuses non-skill entries (canonicalKey !== 'skill') with INVALID_KIND."),
11227
+ workflowId: z22.string().max(200).optional().describe("Workflow ID for start, checkpoint, or get-run, e.g. 'retro', 'implementation-review'"),
11228
+ runId: z22.string().max(200).optional().describe("Workflow run ID: for get-run, which run to load; for checkpoint, target this run (avoids session drift \u2014 pass runId from get-run)."),
11229
+ roundId: z22.string().max(200).optional().describe("Round ID for checkpoint, e.g. 'what-went-well'"),
11230
+ output: z22.union([z22.string(), workflowRunOutputInputSchema]).optional().describe("The round's output \u2014 either legacy synthesized text or a typed workflow run payload."),
11231
+ isFinal: z22.boolean().optional().describe("If true, finalize an existing durable workflow run from its terminal round and create the summary chain entry."),
11232
+ restart: z22.boolean().optional().describe("If true, start a new durable run from the workflow's first round in the current session."),
11233
+ summaryName: z22.string().max(500).optional().describe("Optional name for final chain entry. If omitted, the workflow summary template is used."),
11234
+ summaryDescription: z22.string().max(2e4).optional().describe("Optional override for the final chain entry description. Defaults to the final round output text."),
11235
+ summaryEntryId: z22.string().max(200).optional().describe("Link an existing entry as the run's summary instead of creating one. Used by facilitated workflows (e.g. shape) where the primary record is created by the specialized tool."),
11236
+ entryId: z22.string().max(200).optional().describe("For 'load-skill': workspace-scoped skill entry id (e.g. 'SKILL-pb-setup'). Refuses non-skill entries (canonicalKey !== 'skill') with INVALID_KIND."),
11174
11237
  // WP-513: team+role to create the finalize summary AS OWNER of (rung 2 only).
11175
- ownerTeamEntryId: z21.string().max(200).optional().describe("For 'checkpoint' (isFinal): owning team (rung-2)."),
11176
- ownerRoleEntryId: z21.string().max(200).optional().describe("For 'checkpoint' (isFinal): owning role (rung-2).")
11238
+ ownerTeamEntryId: z22.string().max(200).optional().describe("For 'checkpoint' (isFinal): owning team (rung-2)."),
11239
+ ownerRoleEntryId: z22.string().max(200).optional().describe("For 'checkpoint' (isFinal): owning role (rung-2).")
11177
11240
  });
11178
- var workflowsListVariant = z21.object({ action: z21.literal("list") });
11179
- var workflowsGetRunVariant = z21.object({
11180
- action: z21.literal("get-run"),
11181
- runId: z21.string().max(200).optional(),
11182
- workflowId: z21.string().max(200).optional()
11241
+ var workflowsListVariant = z22.object({ action: z22.literal("list") });
11242
+ var workflowsGetRunVariant = z22.object({
11243
+ action: z22.literal("get-run"),
11244
+ runId: z22.string().max(200).optional(),
11245
+ workflowId: z22.string().max(200).optional()
11183
11246
  });
11184
- var workflowsStartVariant = z21.object({ action: z21.literal("start"), workflowId: z21.string().max(200) });
11185
- var workflowsCheckpointVariant = z21.object({
11186
- action: z21.literal("checkpoint"),
11187
- workflowId: z21.string().max(200),
11188
- roundId: z21.string().max(200),
11189
- output: z21.union([z21.string(), workflowRunOutputInputSchema]),
11190
- isFinal: z21.boolean().optional(),
11191
- restart: z21.boolean().optional(),
11192
- summaryName: z21.string().max(500).optional(),
11193
- summaryDescription: z21.string().max(2e4).optional(),
11194
- summaryEntryId: z21.string().max(200).optional(),
11195
- runId: z21.string().max(200).optional(),
11196
- ownerTeamEntryId: z21.string().max(200).optional(),
11197
- ownerRoleEntryId: z21.string().max(200).optional()
11247
+ var workflowsStartVariant = z22.object({ action: z22.literal("start"), workflowId: z22.string().max(200) });
11248
+ var workflowsCheckpointVariant = z22.object({
11249
+ action: z22.literal("checkpoint"),
11250
+ workflowId: z22.string().max(200),
11251
+ roundId: z22.string().max(200),
11252
+ output: z22.union([z22.string(), workflowRunOutputInputSchema]),
11253
+ isFinal: z22.boolean().optional(),
11254
+ restart: z22.boolean().optional(),
11255
+ summaryName: z22.string().max(500).optional(),
11256
+ summaryDescription: z22.string().max(2e4).optional(),
11257
+ summaryEntryId: z22.string().max(200).optional(),
11258
+ runId: z22.string().max(200).optional(),
11259
+ ownerTeamEntryId: z22.string().max(200).optional(),
11260
+ ownerRoleEntryId: z22.string().max(200).optional()
11198
11261
  });
11199
- var workflowsLoadSkillVariant = z21.object({ action: z21.literal("load-skill"), entryId: z21.string().max(200).min(1) });
11200
- var workflowsActionUnion = z21.discriminatedUnion("action", [
11262
+ var workflowsLoadSkillVariant = z22.object({ action: z22.literal("load-skill"), entryId: z22.string().max(200).min(1) });
11263
+ var workflowsActionUnion = z22.discriminatedUnion("action", [
11201
11264
  workflowsListVariant,
11202
11265
  workflowsGetRunVariant,
11203
11266
  workflowsStartVariant,
@@ -11937,10 +12000,10 @@ function parseListOutput(output) {
11937
12000
  }
11938
12001
 
11939
12002
  // src/tools/quality.ts
11940
- import { z as z23 } from "zod/v3";
12003
+ import { z as z24 } from "zod/v3";
11941
12004
 
11942
12005
  // src/tools/audit.ts
11943
- import { z as z22 } from "zod/v3";
12006
+ import { z as z23 } from "zod/v3";
11944
12007
  var VOCAB_TTL_MS = 5 * 60 * 1e3;
11945
12008
  var MAX_VOCAB_KEYS = 100;
11946
12009
  var vocabCache = /* @__PURE__ */ new Map();
@@ -11970,12 +12033,12 @@ function evictVocabIfFull() {
11970
12033
  }
11971
12034
  }
11972
12035
  var AUDIT_ACTIONS = ["run"];
11973
- var auditSchema = z22.object({
11974
- action: z22.enum(AUDIT_ACTIONS).describe(
12036
+ var auditSchema = z23.object({
12037
+ action: z23.enum(AUDIT_ACTIONS).describe(
11975
12038
  "'run': run the hygiene audit for a work package entry."
11976
12039
  ),
11977
- entryId: z22.string().describe("Work package entry ID to audit, e.g. '<PREFIX>-<n>'"),
11978
- phase: z22.enum(["shaping", "handoff"]).default("shaping").optional().describe(
12040
+ entryId: z23.string().describe("Work package entry ID to audit, e.g. '<PREFIX>-<n>'"),
12041
+ phase: z23.enum(["shaping", "handoff"]).default("shaping").optional().describe(
11979
12042
  "'shaping': check shaping-phase fields only. 'handoff': check all required fields including buildContract/buildSequence/exclusions/risks. Default: shaping."
11980
12043
  )
11981
12044
  });
@@ -12168,44 +12231,44 @@ async function handleSpineCheck(story, refresh = false) {
12168
12231
 
12169
12232
  // src/tools/quality.ts
12170
12233
  var QUALITY_ACTIONS = ["check", "re-evaluate", "verify-chain", "audit", "spine-check"];
12171
- var qualitySchema = z23.object({
12172
- action: z23.enum(QUALITY_ACTIONS).describe(
12234
+ var qualitySchema = z24.object({
12235
+ action: z24.enum(QUALITY_ACTIONS).describe(
12173
12236
  "'check': read the entry's server quality verdict (tier + criteria). 're-evaluate': trigger fresh evaluation. 'verify-chain': verify entries against the codebase (codeMapping drift, cross-references) \u2014 absorbs `verify`. 'audit': hygiene audit for a work package entry \u2014 absorbs `audit`. 'spine-check': structural completeness of the purpose+vision+strategy spine \u2014 story:true also runs the on-demand one-story judgment."
12174
12237
  ),
12175
- entryId: z23.string().max(200).optional().describe("For 'check'/'re-evaluate'/'audit': entry ID, e.g. 'TEN-graph-db', '<PREFIX>-<n>'."),
12176
- context: z23.enum(["capture", "commit", "review"]).default("review").optional().describe("For re-evaluate: evaluation context"),
12177
- collection: z23.string().max(200).optional().describe("For 'verify-chain': collection slug to verify (default: glossary)."),
12178
- mode: z23.enum(["report", "fix"]).optional().describe("For 'verify-chain': 'report' = read-only trust report (default). 'fix' = also update drifted codeMapping statuses."),
12179
- phase: z23.enum(["shaping", "handoff"]).optional().describe(
12238
+ entryId: z24.string().max(200).optional().describe("For 'check'/'re-evaluate'/'audit': entry ID, e.g. 'TEN-graph-db', '<PREFIX>-<n>'."),
12239
+ context: z24.enum(["capture", "commit", "review"]).default("review").optional().describe("For re-evaluate: evaluation context"),
12240
+ collection: z24.string().max(200).optional().describe("For 'verify-chain': collection slug to verify (default: glossary)."),
12241
+ mode: z24.enum(["report", "fix"]).optional().describe("For 'verify-chain': 'report' = read-only trust report (default). 'fix' = also update drifted codeMapping statuses."),
12242
+ phase: z24.enum(["shaping", "handoff"]).optional().describe(
12180
12243
  "For 'audit': 'shaping' checks shaping-phase fields only (default). 'handoff' checks all required fields including buildContract/buildSequence/exclusions/risks."
12181
12244
  ),
12182
- story: z23.boolean().optional().describe("For 'spine-check': also run the on-demand one-story LLM judgment (never scheduled; result labelled [unvalidated])."),
12183
- refresh: z23.boolean().optional().describe(
12245
+ story: z24.boolean().optional().describe("For 'spine-check': also run the on-demand one-story LLM judgment (never scheduled; result labelled [unvalidated])."),
12246
+ refresh: z24.boolean().optional().describe(
12184
12247
  "For 'spine-check': force a new run even if a fresh verdict already exists. Default false \u2014 a plain call NEVER re-triggers work just to read the last result; it auto-schedules only when no run is already in flight AND the stored verdict is absent/stale/missing the requested story pass."
12185
12248
  )
12186
12249
  });
12187
- var qualityCheckVariant = z23.object({ action: z23.literal("check"), entryId: z23.string().max(200) });
12188
- var qualityReEvaluateVariant = z23.object({
12189
- action: z23.literal("re-evaluate"),
12190
- entryId: z23.string().max(200),
12191
- context: z23.enum(["capture", "commit", "review"]).optional().default("review")
12250
+ var qualityCheckVariant = z24.object({ action: z24.literal("check"), entryId: z24.string().max(200) });
12251
+ var qualityReEvaluateVariant = z24.object({
12252
+ action: z24.literal("re-evaluate"),
12253
+ entryId: z24.string().max(200),
12254
+ context: z24.enum(["capture", "commit", "review"]).optional().default("review")
12192
12255
  });
12193
- var qualityVerifyChainVariant = z23.object({
12194
- action: z23.literal("verify-chain"),
12195
- collection: z23.string().max(200).optional().default("glossary"),
12196
- mode: z23.enum(["report", "fix"]).optional().default("report")
12256
+ var qualityVerifyChainVariant = z24.object({
12257
+ action: z24.literal("verify-chain"),
12258
+ collection: z24.string().max(200).optional().default("glossary"),
12259
+ mode: z24.enum(["report", "fix"]).optional().default("report")
12197
12260
  });
12198
- var qualityAuditVariant = z23.object({
12199
- action: z23.literal("audit"),
12200
- entryId: z23.string().max(200),
12201
- phase: z23.enum(["shaping", "handoff"]).optional().default("shaping")
12261
+ var qualityAuditVariant = z24.object({
12262
+ action: z24.literal("audit"),
12263
+ entryId: z24.string().max(200),
12264
+ phase: z24.enum(["shaping", "handoff"]).optional().default("shaping")
12202
12265
  });
12203
- var qualitySpineCheckVariant = z23.object({
12204
- action: z23.literal("spine-check"),
12205
- story: z23.boolean().optional().default(false),
12206
- refresh: z23.boolean().optional().default(false)
12266
+ var qualitySpineCheckVariant = z24.object({
12267
+ action: z24.literal("spine-check"),
12268
+ story: z24.boolean().optional().default(false),
12269
+ refresh: z24.boolean().optional().default(false)
12207
12270
  });
12208
- var qualityActionUnion = z23.discriminatedUnion("action", [
12271
+ var qualityActionUnion = z24.discriminatedUnion("action", [
12209
12272
  qualityCheckVariant,
12210
12273
  qualityReEvaluateVariant,
12211
12274
  qualityVerifyChainVariant,
@@ -12219,34 +12282,34 @@ var QUALITY_ACTION_SPECS = {
12219
12282
  audit: { params: ["entryId", "phase"], description: "entryId is required." },
12220
12283
  "spine-check": { params: ["story", "refresh"], description: "All params optional; story and refresh default to false \u2014 a plain call never re-triggers work, it just reads back the latest verdict (auto-refreshing only when stale/absent)." }
12221
12284
  };
12222
- var qualityCheckOutputSchema = z23.object({
12223
- entryId: z23.string(),
12285
+ var qualityCheckOutputSchema = z24.object({
12286
+ entryId: z24.string(),
12224
12287
  /** WP-480 S1: false = the ID does not resolve to an entry (typo/deleted) — distinct from "no verdict yet". */
12225
- entryFound: z23.boolean().optional(),
12226
- hasVerdict: z23.boolean(),
12288
+ entryFound: z24.boolean().optional(),
12289
+ hasVerdict: z24.boolean(),
12227
12290
  /** WP-480 S1: the verdict was judged against content the entry no longer has — re-evaluate for a current one. */
12228
- stale: z23.boolean().optional(),
12229
- tier: z23.string().optional(),
12230
- passed: z23.boolean().optional(),
12231
- criteria: z23.array(z23.object({
12232
- id: z23.string(),
12233
- passed: z23.boolean(),
12234
- hint: z23.string().optional()
12291
+ stale: z24.boolean().optional(),
12292
+ tier: z24.string().optional(),
12293
+ passed: z24.boolean().optional(),
12294
+ criteria: z24.array(z24.object({
12295
+ id: z24.string(),
12296
+ passed: z24.boolean(),
12297
+ hint: z24.string().optional()
12235
12298
  }))
12236
12299
  });
12237
- var qualityReevaluateOutputSchema = z23.object({
12238
- entryId: z23.string(),
12239
- context: z23.string(),
12240
- score: z23.number(),
12241
- maxScore: z23.number(),
12242
- improved: z23.boolean()
12300
+ var qualityReevaluateOutputSchema = z24.object({
12301
+ entryId: z24.string(),
12302
+ context: z24.string(),
12303
+ score: z24.number(),
12304
+ maxScore: z24.number(),
12305
+ improved: z24.boolean()
12243
12306
  });
12244
- var qualitySpineCheckOutputSchema = z23.object({
12245
- hasVerdict: z23.boolean(),
12246
- noSpineEntries: z23.boolean().optional(),
12247
- structuralPassed: z23.boolean().optional(),
12248
- storyPassed: z23.boolean().nullable().optional(),
12249
- stale: z23.boolean().optional()
12307
+ var qualitySpineCheckOutputSchema = z24.object({
12308
+ hasVerdict: z24.boolean(),
12309
+ noSpineEntries: z24.boolean().optional(),
12310
+ structuralPassed: z24.boolean().optional(),
12311
+ storyPassed: z24.boolean().nullable().optional(),
12312
+ stale: z24.boolean().optional()
12250
12313
  });
12251
12314
  function registerQualityTools(server) {
12252
12315
  const qualityHandlers = {
@@ -12428,10 +12491,10 @@ async function handleReEvaluate(entryId, context) {
12428
12491
  }
12429
12492
 
12430
12493
  // src/tools/session.ts
12431
- import { z as z26 } from "zod/v3";
12494
+ import { z as z27 } from "zod/v3";
12432
12495
 
12433
12496
  // src/tools/wrapup.ts
12434
- import { z as z24 } from "zod/v3";
12497
+ import { z as z25 } from "zod/v3";
12435
12498
 
12436
12499
  // src/lib/compose-wrapup-view.ts
12437
12500
  function toComposed(e) {
@@ -12885,8 +12948,8 @@ async function runWrapupCommitAll(data, cachedSuggestions) {
12885
12948
  overflowUnscanned
12886
12949
  };
12887
12950
  }
12888
- var wrapupSchema = z24.object({
12889
- action: z24.enum(["review", "commit-all"]).optional().describe(
12951
+ var wrapupSchema = z25.object({
12952
+ action: z25.enum(["review", "commit-all"]).optional().describe(
12890
12953
  "Action to perform. 'review' (default) shows the wrapup summary. 'commit-all' accepts all uncommitted drafts and creates suggested links."
12891
12954
  )
12892
12955
  });
@@ -12987,26 +13050,26 @@ ${text}` : text;
12987
13050
  }
12988
13051
 
12989
13052
  // src/tools/facilitate.ts
12990
- import { z as z25 } from "zod/v3";
13053
+ import { z as z26 } from "zod/v3";
12991
13054
  var FACILITATE_ACTIONS = ["resume", "commit-constellation"];
12992
- var coherencyAcknowledgementSchema = z25.object({
12993
- response: z25.string().max(200).describe("Acknowledgement response per offender: 'linked' | 'accepted-fix' | 'diverged'."),
12994
- entryId: z25.string().max(200).optional().describe("Entry the acknowledgement links to (e.g. the strategic spine entry)."),
12995
- reason: z25.string().max(2e3).optional().describe("Free-text justification, required for a 'diverged' response."),
12996
- subjectEntryId: z25.string().max(200).optional().describe("The refused entry this acknowledgement answers.")
13055
+ var coherencyAcknowledgementSchema = z26.object({
13056
+ response: z26.string().max(200).describe("Acknowledgement response per offender: 'linked' | 'accepted-fix' | 'diverged'."),
13057
+ entryId: z26.string().max(200).optional().describe("Entry the acknowledgement links to (e.g. the strategic spine entry)."),
13058
+ reason: z26.string().max(2e3).optional().describe("Free-text justification, required for a 'diverged' response."),
13059
+ subjectEntryId: z26.string().max(200).optional().describe("The refused entry this acknowledgement answers.")
12997
13060
  });
12998
- var facilitateSchema = z25.object({
12999
- action: z25.enum(FACILITATE_ACTIONS).describe(
13061
+ var facilitateSchema = z26.object({
13062
+ action: z26.enum(FACILITATE_ACTIONS).describe(
13000
13063
  "'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."
13001
13064
  ),
13002
- betEntryId: z25.string().max(200).optional().describe("Bet entry ID. Required for both actions."),
13003
- operationId: z25.string().max(200).optional().describe("Optional idempotency key for commit-constellation retries."),
13065
+ betEntryId: z26.string().max(200).optional().describe("Bet entry ID. Required for both actions."),
13066
+ operationId: z26.string().max(200).optional().describe("Optional idempotency key for commit-constellation retries."),
13004
13067
  // WP-465 slice ⑤: coherency retry controls for a COHERENCY_REFUSED constellation hold.
13005
13068
  // Forwarded verbatim to agentKnowledge.facilitateEnvelope (validation lives at the gate).
13006
- coherencyAcknowledgements: z25.array(coherencyAcknowledgementSchema).max(20).optional().describe(
13069
+ coherencyAcknowledgements: z26.array(coherencyAcknowledgementSchema).max(20).optional().describe(
13007
13070
  "Per-offender acknowledgements to retry a constellation held under standard/strict coherency mode. Each: {subjectEntryId, response: 'linked' | 'accepted-fix' | 'diverged', entryId?, reason?}."
13008
13071
  ),
13009
- steeringOverrideReason: z25.string().max(2e3).optional().describe(
13072
+ steeringOverrideReason: z26.string().max(2e3).optional().describe(
13010
13073
  "Typed override reason (>= 12 chars) to push a constellation past a coherency hold instead of acknowledging."
13011
13074
  )
13012
13075
  });
@@ -13259,33 +13322,33 @@ var SESSION_ACTIONS = [
13259
13322
  "resume",
13260
13323
  "commit-constellation"
13261
13324
  ];
13262
- var coherencyAcknowledgementFlatSchema2 = z26.object({
13263
- response: z26.string().max(200).describe("Acknowledgement response per offender: 'linked' | 'accepted-fix' | 'diverged'."),
13264
- entryId: z26.string().max(200).optional().describe("Entry the acknowledgement links to."),
13265
- reason: z26.string().max(2e3).optional().describe("Free-text justification, required for a 'diverged' response."),
13266
- subjectEntryId: z26.string().max(200).optional().describe("The refused entry this acknowledgement answers.")
13325
+ var coherencyAcknowledgementFlatSchema2 = z27.object({
13326
+ response: z27.string().max(200).describe("Acknowledgement response per offender: 'linked' | 'accepted-fix' | 'diverged'."),
13327
+ entryId: z27.string().max(200).optional().describe("Entry the acknowledgement links to."),
13328
+ reason: z27.string().max(2e3).optional().describe("Free-text justification, required for a 'diverged' response."),
13329
+ subjectEntryId: z27.string().max(200).optional().describe("The refused entry this acknowledgement answers.")
13267
13330
  });
13268
- var sessionSchema = z26.object({
13269
- action: z26.enum(SESSION_ACTIONS).describe(
13331
+ var sessionSchema = z27.object({
13332
+ action: z27.enum(SESSION_ACTIONS).describe(
13270
13333
  "'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)."
13271
13334
  ),
13272
- betEntryId: z26.string().max(200).optional().describe("For 'resume'/'commit-constellation': bet entry ID. Required for both."),
13273
- operationId: z26.string().max(200).optional().describe("For 'commit-constellation': optional idempotency key for retries."),
13274
- coherencyAcknowledgements: z26.array(coherencyAcknowledgementFlatSchema2).max(20).optional().describe(
13335
+ betEntryId: z27.string().max(200).optional().describe("For 'resume'/'commit-constellation': bet entry ID. Required for both."),
13336
+ operationId: z27.string().max(200).optional().describe("For 'commit-constellation': optional idempotency key for retries."),
13337
+ coherencyAcknowledgements: z27.array(coherencyAcknowledgementFlatSchema2).max(20).optional().describe(
13275
13338
  "For 'commit-constellation': per-offender acknowledgements to retry a constellation held under standard/strict coherency mode."
13276
13339
  ),
13277
- steeringOverrideReason: z26.string().max(2e3).optional().describe(
13340
+ steeringOverrideReason: z27.string().max(2e3).optional().describe(
13278
13341
  "For 'commit-constellation': typed override reason (>= 12 chars) to push past a coherency hold instead of acknowledging."
13279
13342
  )
13280
13343
  });
13281
- var sessionStartVariant = z26.object({ action: z26.literal("start") });
13282
- var sessionCloseVariant = z26.object({ action: z26.literal("close") });
13283
- var sessionStatusVariant = z26.object({ action: z26.literal("status") });
13284
- var sessionWrapupReviewVariant = z26.object({ action: z26.literal("wrapup-review") });
13285
- var sessionWrapupCommitVariant = z26.object({ action: z26.literal("wrapup-commit") });
13286
- var sessionResumeVariant = facilitateSchema.omit({ action: true }).extend({ action: z26.literal("resume") });
13287
- var sessionCommitConstellationVariant = facilitateSchema.omit({ action: true }).extend({ action: z26.literal("commit-constellation") });
13288
- var sessionActionUnion = z26.discriminatedUnion("action", [
13344
+ var sessionStartVariant = z27.object({ action: z27.literal("start") });
13345
+ var sessionCloseVariant = z27.object({ action: z27.literal("close") });
13346
+ var sessionStatusVariant = z27.object({ action: z27.literal("status") });
13347
+ var sessionWrapupReviewVariant = z27.object({ action: z27.literal("wrapup-review") });
13348
+ var sessionWrapupCommitVariant = z27.object({ action: z27.literal("wrapup-commit") });
13349
+ var sessionResumeVariant = facilitateSchema.omit({ action: true }).extend({ action: z27.literal("resume") });
13350
+ var sessionCommitConstellationVariant = facilitateSchema.omit({ action: true }).extend({ action: z27.literal("commit-constellation") });
13351
+ var sessionActionUnion = z27.discriminatedUnion("action", [
13289
13352
  sessionStartVariant,
13290
13353
  sessionCloseVariant,
13291
13354
  sessionStatusVariant,
@@ -13524,7 +13587,7 @@ async function handleStatus() {
13524
13587
  }
13525
13588
 
13526
13589
  // src/tools/gitchain.ts
13527
- import { z as z27 } from "zod/v3";
13590
+ import { z as z28 } from "zod/v3";
13528
13591
 
13529
13592
  // src/lib/versionDisplay.ts
13530
13593
  function toVersionDisplay(version) {
@@ -13533,51 +13596,51 @@ function toVersionDisplay(version) {
13533
13596
  }
13534
13597
 
13535
13598
  // src/tools/gitchain.ts
13536
- var chainSchema = z27.object({
13537
- action: z27.enum(["create", "get", "list", "edit"]).describe("Action: create a process, get process details, list all processes, or edit a process link"),
13538
- chainEntryId: z27.string().max(200).optional().describe("Chain entry ID (required for get/edit)"),
13539
- title: z27.string().max(500).optional().describe("Process title (required for create)"),
13540
- chainTypeId: z27.string().max(200).optional().default("strategy-coherence").describe("Process template slug for create: 'strategy-coherence', 'idm-proposal', or any custom template slug"),
13541
- description: z27.string().max(2e4).optional().describe("Description (for create)"),
13542
- linkId: z27.string().max(200).optional().describe("Link to edit (for edit action): problem, insight, choice, action, outcome"),
13543
- content: z27.string().max(5e4).optional().describe("New content for the link (for edit action)"),
13544
- status: z27.string().max(200).optional().describe("Filter by status for list: 'draft' or 'active'"),
13545
- author: z27.string().max(200).optional().describe("Who is performing the action. Defaults to 'mcp'."),
13599
+ var chainSchema = z28.object({
13600
+ action: z28.enum(["create", "get", "list", "edit"]).describe("Action: create a process, get process details, list all processes, or edit a process link"),
13601
+ chainEntryId: z28.string().max(200).optional().describe("Chain entry ID (required for get/edit)"),
13602
+ title: z28.string().max(500).optional().describe("Process title (required for create)"),
13603
+ chainTypeId: z28.string().max(200).optional().default("strategy-coherence").describe("Process template slug for create: 'strategy-coherence', 'idm-proposal', or any custom template slug"),
13604
+ description: z28.string().max(2e4).optional().describe("Description (for create)"),
13605
+ linkId: z28.string().max(200).optional().describe("Link to edit (for edit action): problem, insight, choice, action, outcome"),
13606
+ content: z28.string().max(5e4).optional().describe("New content for the link (for edit action)"),
13607
+ status: z28.string().max(200).optional().describe("Filter by status for list: 'draft' or 'active'"),
13608
+ author: z28.string().max(200).optional().describe("Who is performing the action. Defaults to 'mcp'."),
13546
13609
  // WP-513 review round 3 (P1): team+role to create AS OWNER of (rung 2 only) — entry ID or entryId (e.g. "TEAM-1").
13547
- ownerTeamEntryId: z27.string().max(200).optional().describe("For 'create': owning team (rung-2 workspaces)."),
13548
- ownerRoleEntryId: z27.string().max(200).optional().describe("For 'create': owning role (rung-2 workspaces).")
13610
+ ownerTeamEntryId: z28.string().max(200).optional().describe("For 'create': owning team (rung-2 workspaces)."),
13611
+ ownerRoleEntryId: z28.string().max(200).optional().describe("For 'create': owning role (rung-2 workspaces).")
13549
13612
  });
13550
- var chainVersionSchema = z27.object({
13551
- action: z27.enum(["commit", "list", "diff", "revert", "history"]).describe("Action: commit a snapshot, list commits, diff two versions, revert to a version, or view history"),
13552
- chainEntryId: z27.string().max(200).describe("The chain's entry ID"),
13553
- commitMessage: z27.string().max(2e3).optional().describe("Commit message (required for commit). Convention: type(link): description"),
13554
- versionA: z27.number().optional().describe("Earlier version for diff"),
13555
- versionB: z27.number().optional().describe("Later version for diff"),
13556
- toVersion: z27.number().optional().describe("Version number to revert to"),
13557
- author: z27.string().max(200).optional().describe("Who is performing the action. Defaults to 'mcp'.")
13613
+ var chainVersionSchema = z28.object({
13614
+ action: z28.enum(["commit", "list", "diff", "revert", "history"]).describe("Action: commit a snapshot, list commits, diff two versions, revert to a version, or view history"),
13615
+ chainEntryId: z28.string().max(200).describe("The chain's entry ID"),
13616
+ commitMessage: z28.string().max(2e3).optional().describe("Commit message (required for commit). Convention: type(link): description"),
13617
+ versionA: z28.number().optional().describe("Earlier version for diff"),
13618
+ versionB: z28.number().optional().describe("Later version for diff"),
13619
+ toVersion: z28.number().optional().describe("Version number to revert to"),
13620
+ author: z28.string().max(200).optional().describe("Who is performing the action. Defaults to 'mcp'.")
13558
13621
  });
13559
- var chainBranchSchema = z27.object({
13560
- action: z27.enum(["create", "list", "merge", "conflicts"]).describe("Action: create a branch, list branches, merge a branch, or check for conflicts"),
13561
- chainEntryId: z27.string().max(200).describe("The chain's entry ID"),
13562
- branchName: z27.string().max(200).optional().describe("Branch name (required for merge/conflicts, optional for create)"),
13563
- strategy: z27.enum(["merge_commit", "squash"]).optional().describe("Merge strategy: 'merge_commit' (default) or 'squash'"),
13564
- author: z27.string().max(200).optional().describe("Who is performing the action. Defaults to 'mcp'.")
13622
+ var chainBranchSchema = z28.object({
13623
+ action: z28.enum(["create", "list", "merge", "conflicts"]).describe("Action: create a branch, list branches, merge a branch, or check for conflicts"),
13624
+ chainEntryId: z28.string().max(200).describe("The chain's entry ID"),
13625
+ branchName: z28.string().max(200).optional().describe("Branch name (required for merge/conflicts, optional for create)"),
13626
+ strategy: z28.enum(["merge_commit", "squash"]).optional().describe("Merge strategy: 'merge_commit' (default) or 'squash'"),
13627
+ author: z28.string().max(200).optional().describe("Who is performing the action. Defaults to 'mcp'.")
13565
13628
  });
13566
- var chainReviewSchema = z27.object({
13567
- action: z27.enum(["gate", "comment", "resolve-comment", "list-comments"]).describe("Action: run coherence gate, add a comment, resolve a comment, or list comments"),
13629
+ var chainReviewSchema = z28.object({
13630
+ action: z28.enum(["gate", "comment", "resolve-comment", "list-comments"]).describe("Action: run coherence gate, add a comment, resolve a comment, or list comments"),
13568
13631
  // Finding #12: optional at the base (mirrors chainSchema's chainEntryId pattern at
13569
13632
  // line ~690) — resolve-comment resolves purely by commentId (handleChainReview never
13570
13633
  // reads chainEntryId in that branch) and the compound-tool's advertised schema
13571
13634
  // (chainReviewCompoundSchema below) already documents it as optional for that action.
13572
13635
  // Per-action variants that DO need it (gate/comment/list-comments) re-require it below,
13573
13636
  // same pattern as chainGetVariant/chainEditVariant re-requiring over chainSchema's base.
13574
- chainEntryId: z27.string().max(200).optional().describe("The chain's entry ID. Required for every action except 'resolve-comment'."),
13575
- commitMessage: z27.string().max(2e3).optional().describe("Commit message to lint (for gate action)"),
13576
- versionNumber: z27.number().optional().describe("Version to comment on or list comments for"),
13577
- linkId: z27.string().max(200).optional().describe("Link this comment targets (optional for comment)"),
13578
- body: z27.string().max(2e4).optional().describe("Comment text (required for comment action)"),
13579
- commentId: z27.string().max(200).optional().describe("Comment ID (required for resolve-comment)"),
13580
- author: z27.string().max(200).optional().describe("Who is performing the action. Defaults to 'mcp'.")
13637
+ chainEntryId: z28.string().max(200).optional().describe("The chain's entry ID. Required for every action except 'resolve-comment'."),
13638
+ commitMessage: z28.string().max(2e3).optional().describe("Commit message to lint (for gate action)"),
13639
+ versionNumber: z28.number().optional().describe("Version to comment on or list comments for"),
13640
+ linkId: z28.string().max(200).optional().describe("Link this comment targets (optional for comment)"),
13641
+ body: z28.string().max(2e4).optional().describe("Comment text (required for comment action)"),
13642
+ commentId: z28.string().max(200).optional().describe("Comment ID (required for resolve-comment)"),
13643
+ author: z28.string().max(200).optional().describe("Who is performing the action. Defaults to 'mcp'.")
13581
13644
  });
13582
13645
  function linkSummary(links) {
13583
13646
  return Object.entries(links).map(([id, content]) => {
@@ -14085,57 +14148,57 @@ var CHAIN_REVIEW_ACTIONS = [
14085
14148
  "branch.merge",
14086
14149
  "branch.conflicts"
14087
14150
  ];
14088
- var chainCompoundSchema = z27.object({
14089
- action: z27.enum(CHAIN_ACTIONS).describe(
14151
+ var chainCompoundSchema = z28.object({
14152
+ action: z28.enum(CHAIN_ACTIONS).describe(
14090
14153
  "Unnamespaced: 'create'/'get'/'list'/'edit' \u2014 process CRUD (the original `chain` tool). 'version.*' (commit/list/diff/revert/history) \u2014 versioning, absorbs `chain-version`. Branching and review live on the sibling `chain-review` tool."
14091
14154
  ),
14092
- chainEntryId: z27.string().max(200).optional().describe("Chain entry ID. Required for get/edit and all version.* actions."),
14093
- title: z27.string().max(500).optional().describe("For 'create': process title (required)."),
14094
- chainTypeId: z27.string().max(200).optional().default("strategy-coherence").describe("For 'create'/'list': process template slug."),
14095
- description: z27.string().max(2e4).optional().describe("For 'create': description."),
14096
- linkId: z27.string().max(200).optional().describe("For 'edit': link to edit (required)."),
14097
- content: z27.string().max(5e4).optional().describe("For 'edit': new content for the link (required)."),
14098
- status: z27.string().max(200).optional().describe("For 'list': filter by status."),
14099
- author: z27.string().max(200).optional().describe("Who is performing the action. Defaults to 'mcp'."),
14100
- commitMessage: z27.string().max(2e3).optional().describe("For 'version.commit': commit message (required)."),
14101
- versionA: z27.number().optional().describe("For 'version.diff': earlier version (required)."),
14102
- versionB: z27.number().optional().describe("For 'version.diff': later version (required)."),
14103
- toVersion: z27.number().optional().describe("For 'version.revert': version number to revert to (required)."),
14155
+ chainEntryId: z28.string().max(200).optional().describe("Chain entry ID. Required for get/edit and all version.* actions."),
14156
+ title: z28.string().max(500).optional().describe("For 'create': process title (required)."),
14157
+ chainTypeId: z28.string().max(200).optional().default("strategy-coherence").describe("For 'create'/'list': process template slug."),
14158
+ description: z28.string().max(2e4).optional().describe("For 'create': description."),
14159
+ linkId: z28.string().max(200).optional().describe("For 'edit': link to edit (required)."),
14160
+ content: z28.string().max(5e4).optional().describe("For 'edit': new content for the link (required)."),
14161
+ status: z28.string().max(200).optional().describe("For 'list': filter by status."),
14162
+ author: z28.string().max(200).optional().describe("Who is performing the action. Defaults to 'mcp'."),
14163
+ commitMessage: z28.string().max(2e3).optional().describe("For 'version.commit': commit message (required)."),
14164
+ versionA: z28.number().optional().describe("For 'version.diff': earlier version (required)."),
14165
+ versionB: z28.number().optional().describe("For 'version.diff': later version (required)."),
14166
+ toVersion: z28.number().optional().describe("For 'version.revert': version number to revert to (required)."),
14104
14167
  // WP-513 review round 3 (P1): team+role to create AS OWNER of (rung 2 only).
14105
- ownerTeamEntryId: z27.string().max(200).optional().describe("For 'create': owning team (rung-2 workspaces)."),
14106
- ownerRoleEntryId: z27.string().max(200).optional().describe("For 'create': owning role (rung-2 workspaces).")
14168
+ ownerTeamEntryId: z28.string().max(200).optional().describe("For 'create': owning team (rung-2 workspaces)."),
14169
+ ownerRoleEntryId: z28.string().max(200).optional().describe("For 'create': owning role (rung-2 workspaces).")
14107
14170
  });
14108
- var chainReviewCompoundSchema = z27.object({
14109
- action: z27.enum(CHAIN_REVIEW_ACTIONS).describe(
14171
+ var chainReviewCompoundSchema = z28.object({
14172
+ action: z28.enum(CHAIN_REVIEW_ACTIONS).describe(
14110
14173
  "'gate'/'comment'/'resolve-comment'/'list-comments' \u2014 quality gate + comments (the original `chain-review` tool, unchanged call shape). 'branch.*' (create/list/merge/conflicts) \u2014 branching, absorbs `chain-branch`. Process CRUD and versioning live on the sibling `chain` tool."
14111
14174
  ),
14112
- chainEntryId: z27.string().max(200).optional().describe("Chain entry ID. Required for every action except 'resolve-comment'."),
14113
- commitMessage: z27.string().max(2e3).optional().describe("For 'gate': commit message to lint."),
14114
- versionNumber: z27.number().optional().describe("For 'comment'/'list-comments': version to comment on or list comments for."),
14115
- linkId: z27.string().max(200).optional().describe("For 'comment': optional link this comment targets."),
14116
- body: z27.string().max(2e4).optional().describe("For 'comment': comment text (required)."),
14117
- commentId: z27.string().max(200).optional().describe("For 'resolve-comment': comment ID (required)."),
14118
- branchName: z27.string().max(200).optional().describe("For 'branch.merge'/'branch.conflicts': required. For 'branch.create': optional."),
14119
- strategy: z27.enum(["merge_commit", "squash"]).optional().describe("For 'branch.merge': merge strategy. Default 'merge_commit'."),
14120
- author: z27.string().max(200).optional().describe("Who is performing the action. Defaults to 'mcp'.")
14175
+ chainEntryId: z28.string().max(200).optional().describe("Chain entry ID. Required for every action except 'resolve-comment'."),
14176
+ commitMessage: z28.string().max(2e3).optional().describe("For 'gate': commit message to lint."),
14177
+ versionNumber: z28.number().optional().describe("For 'comment'/'list-comments': version to comment on or list comments for."),
14178
+ linkId: z28.string().max(200).optional().describe("For 'comment': optional link this comment targets."),
14179
+ body: z28.string().max(2e4).optional().describe("For 'comment': comment text (required)."),
14180
+ commentId: z28.string().max(200).optional().describe("For 'resolve-comment': comment ID (required)."),
14181
+ branchName: z28.string().max(200).optional().describe("For 'branch.merge'/'branch.conflicts': required. For 'branch.create': optional."),
14182
+ strategy: z28.enum(["merge_commit", "squash"]).optional().describe("For 'branch.merge': merge strategy. Default 'merge_commit'."),
14183
+ author: z28.string().max(200).optional().describe("Who is performing the action. Defaults to 'mcp'.")
14121
14184
  });
14122
- var chainCreateVariant = chainSchema.omit({ action: true }).extend({ action: z27.literal("create") });
14123
- var chainGetVariant = z27.object({ action: z27.literal("get"), chainEntryId: z27.string().max(200) });
14124
- var chainListVariant = z27.object({ action: z27.literal("list"), chainTypeId: z27.string().max(200).optional(), status: z27.string().max(200).optional() });
14125
- var chainEditVariant = z27.object({
14126
- action: z27.literal("edit"),
14127
- chainEntryId: z27.string().max(200),
14128
- linkId: z27.string().max(200),
14129
- content: z27.string().max(5e4),
14130
- author: z27.string().max(200).optional()
14185
+ var chainCreateVariant = chainSchema.omit({ action: true }).extend({ action: z28.literal("create") });
14186
+ var chainGetVariant = z28.object({ action: z28.literal("get"), chainEntryId: z28.string().max(200) });
14187
+ var chainListVariant = z28.object({ action: z28.literal("list"), chainTypeId: z28.string().max(200).optional(), status: z28.string().max(200).optional() });
14188
+ var chainEditVariant = z28.object({
14189
+ action: z28.literal("edit"),
14190
+ chainEntryId: z28.string().max(200),
14191
+ linkId: z28.string().max(200),
14192
+ content: z28.string().max(5e4),
14193
+ author: z28.string().max(200).optional()
14131
14194
  });
14132
14195
  var versionBase = chainVersionSchema.omit({ action: true });
14133
- var chainVersionCommitVariant = versionBase.extend({ action: z27.literal("version.commit"), commitMessage: z27.string().max(2e3) });
14134
- var chainVersionListVariant = versionBase.extend({ action: z27.literal("version.list") });
14135
- var chainVersionDiffVariant = versionBase.extend({ action: z27.literal("version.diff"), versionA: z27.number(), versionB: z27.number() });
14136
- var chainVersionRevertVariant = versionBase.extend({ action: z27.literal("version.revert"), toVersion: z27.number() });
14137
- var chainVersionHistoryVariant = versionBase.extend({ action: z27.literal("version.history") });
14138
- var chainActionUnion = z27.discriminatedUnion("action", [
14196
+ var chainVersionCommitVariant = versionBase.extend({ action: z28.literal("version.commit"), commitMessage: z28.string().max(2e3) });
14197
+ var chainVersionListVariant = versionBase.extend({ action: z28.literal("version.list") });
14198
+ var chainVersionDiffVariant = versionBase.extend({ action: z28.literal("version.diff"), versionA: z28.number(), versionB: z28.number() });
14199
+ var chainVersionRevertVariant = versionBase.extend({ action: z28.literal("version.revert"), toVersion: z28.number() });
14200
+ var chainVersionHistoryVariant = versionBase.extend({ action: z28.literal("version.history") });
14201
+ var chainActionUnion = z28.discriminatedUnion("action", [
14139
14202
  chainCreateVariant,
14140
14203
  chainGetVariant,
14141
14204
  chainListVariant,
@@ -14147,16 +14210,16 @@ var chainActionUnion = z27.discriminatedUnion("action", [
14147
14210
  chainVersionHistoryVariant
14148
14211
  ]);
14149
14212
  var reviewBase = chainReviewSchema.omit({ action: true });
14150
- var chainReviewGateVariant = reviewBase.extend({ action: z27.literal("gate"), chainEntryId: z27.string().max(200) });
14151
- var chainReviewCommentVariant = reviewBase.extend({ action: z27.literal("comment"), chainEntryId: z27.string().max(200), versionNumber: z27.number(), body: z27.string().max(2e4) });
14152
- var chainReviewResolveCommentVariant = reviewBase.extend({ action: z27.literal("resolve-comment"), commentId: z27.string().max(200) });
14153
- var chainReviewListCommentsVariant = reviewBase.extend({ action: z27.literal("list-comments"), chainEntryId: z27.string().max(200) });
14213
+ var chainReviewGateVariant = reviewBase.extend({ action: z28.literal("gate"), chainEntryId: z28.string().max(200) });
14214
+ var chainReviewCommentVariant = reviewBase.extend({ action: z28.literal("comment"), chainEntryId: z28.string().max(200), versionNumber: z28.number(), body: z28.string().max(2e4) });
14215
+ var chainReviewResolveCommentVariant = reviewBase.extend({ action: z28.literal("resolve-comment"), commentId: z28.string().max(200) });
14216
+ var chainReviewListCommentsVariant = reviewBase.extend({ action: z28.literal("list-comments"), chainEntryId: z28.string().max(200) });
14154
14217
  var branchBase = chainBranchSchema.omit({ action: true });
14155
- var chainBranchCreateVariant = branchBase.extend({ action: z27.literal("branch.create") });
14156
- var chainBranchListVariant = branchBase.extend({ action: z27.literal("branch.list") });
14157
- var chainBranchMergeVariant = branchBase.extend({ action: z27.literal("branch.merge"), branchName: z27.string().max(200) });
14158
- var chainBranchConflictsVariant = branchBase.extend({ action: z27.literal("branch.conflicts"), branchName: z27.string().max(200) });
14159
- var chainReviewActionUnion = z27.discriminatedUnion("action", [
14218
+ var chainBranchCreateVariant = branchBase.extend({ action: z28.literal("branch.create") });
14219
+ var chainBranchListVariant = branchBase.extend({ action: z28.literal("branch.list") });
14220
+ var chainBranchMergeVariant = branchBase.extend({ action: z28.literal("branch.merge"), branchName: z28.string().max(200) });
14221
+ var chainBranchConflictsVariant = branchBase.extend({ action: z28.literal("branch.conflicts"), branchName: z28.string().max(200) });
14222
+ var chainReviewActionUnion = z28.discriminatedUnion("action", [
14160
14223
  chainReviewGateVariant,
14161
14224
  chainReviewCommentVariant,
14162
14225
  chainReviewResolveCommentVariant,
@@ -14248,10 +14311,10 @@ function registerGitChainTools(server) {
14248
14311
  }
14249
14312
 
14250
14313
  // src/tools/workspace.ts
14251
- import { z as z30 } from "zod/v3";
14314
+ import { z as z31 } from "zod/v3";
14252
14315
 
14253
14316
  // src/tools/health.ts
14254
- import { z as z28 } from "zod/v3";
14317
+ import { z as z29 } from "zod/v3";
14255
14318
 
14256
14319
  // src/lib/auditView.ts
14257
14320
  async function buildTenantAuditView(limit) {
@@ -14615,65 +14678,65 @@ ${logLines.join("\n")}${seamSummaryText}` }],
14615
14678
  };
14616
14679
  }
14617
14680
  var HEALTH_ACTIONS = ["check", "whoami", "status", "audit", "self-test"];
14618
- var healthSchema = z28.object({
14619
- action: z28.enum(HEALTH_ACTIONS).describe(
14681
+ var healthSchema = z29.object({
14682
+ action: z29.enum(HEALTH_ACTIONS).describe(
14620
14683
  "'check': connectivity and workspace stats. 'whoami': session identity. 'status': workspace readiness. 'audit': session audit log. 'self-test': validate all tool schemas."
14621
14684
  ),
14622
- limit: z28.number().min(1).max(50).default(20).optional().describe("For audit: how many recent calls to show (max 50)")
14685
+ limit: z29.number().min(1).max(50).default(20).optional().describe("For audit: how many recent calls to show (max 50)")
14623
14686
  });
14624
- var healthCheckOutputSchema = z28.object({
14625
- healthy: z28.boolean(),
14626
- collections: z28.number(),
14627
- entries: z28.number(),
14628
- latencyMs: z28.number(),
14629
- workspace: z28.string()
14687
+ var healthCheckOutputSchema = z29.object({
14688
+ healthy: z29.boolean(),
14689
+ collections: z29.number(),
14690
+ entries: z29.number(),
14691
+ latencyMs: z29.number(),
14692
+ workspace: z29.string()
14630
14693
  });
14631
- var organisationHealthSchema = z28.object({
14632
- reviewed: z28.number(),
14633
- agreements: z28.number(),
14634
- disagreements: z28.number(),
14635
- abstentions: z28.number(),
14636
- agreementRate: z28.number(),
14637
- flags: z28.array(z28.object({
14638
- collection: z28.string(),
14639
- count: z28.number(),
14640
- suggestedCollection: z28.string()
14694
+ var organisationHealthSchema = z29.object({
14695
+ reviewed: z29.number(),
14696
+ agreements: z29.number(),
14697
+ disagreements: z29.number(),
14698
+ abstentions: z29.number(),
14699
+ agreementRate: z29.number(),
14700
+ flags: z29.array(z29.object({
14701
+ collection: z29.string(),
14702
+ count: z29.number(),
14703
+ suggestedCollection: z29.string()
14641
14704
  }))
14642
14705
  });
14643
- var healthStatusOutputSchema = z28.object({
14644
- stage: z28.enum(["blank", "seeded", "grounded", "connected"]).optional().default("seeded"),
14645
- scoringVersion: z28.enum(["v1", "v2"]).optional().default("v1"),
14646
- readinessScore: z28.number(),
14647
- activeEntries: z28.number(),
14648
- totalRelations: z28.number(),
14649
- orphanedEntries: z28.number(),
14650
- gaps: z28.array(z28.object({ id: z28.string(), label: z28.string(), guidance: z28.string() })),
14706
+ var healthStatusOutputSchema = z29.object({
14707
+ stage: z29.enum(["blank", "seeded", "grounded", "connected"]).optional().default("seeded"),
14708
+ scoringVersion: z29.enum(["v1", "v2"]).optional().default("v1"),
14709
+ readinessScore: z29.number(),
14710
+ activeEntries: z29.number(),
14711
+ totalRelations: z29.number(),
14712
+ orphanedEntries: z29.number(),
14713
+ gaps: z29.array(z29.object({ id: z29.string(), label: z29.string(), guidance: z29.string() })),
14651
14714
  organisationHealth: organisationHealthSchema.optional()
14652
14715
  });
14653
- var healthAuditOutputSchema = z28.object({
14654
- totalCalls: z28.number(),
14655
- calls: z28.array(z28.object({
14656
- tool: z28.string(),
14657
- action: z28.string().optional(),
14658
- timestamp: z28.string(),
14659
- durationMs: z28.number().optional()
14716
+ var healthAuditOutputSchema = z29.object({
14717
+ totalCalls: z29.number(),
14718
+ calls: z29.array(z29.object({
14719
+ tool: z29.string(),
14720
+ action: z29.string().optional(),
14721
+ timestamp: z29.string(),
14722
+ durationMs: z29.number().optional()
14660
14723
  }))
14661
14724
  });
14662
- var healthWhoamiOutputSchema = z28.object({
14663
- workspaceId: z28.string(),
14664
- workspaceName: z28.string(),
14665
- scope: z28.string(),
14666
- sessionId: z28.union([z28.string(), z28.null()]),
14667
- oriented: z28.boolean()
14725
+ var healthWhoamiOutputSchema = z29.object({
14726
+ workspaceId: z29.string(),
14727
+ workspaceName: z29.string(),
14728
+ scope: z29.string(),
14729
+ sessionId: z29.union([z29.string(), z29.null()]),
14730
+ oriented: z29.boolean()
14668
14731
  });
14669
- var selfTestOutputSchema = z28.object({
14670
- passed: z28.number(),
14671
- failed: z28.number(),
14672
- total: z28.number(),
14673
- results: z28.array(z28.object({
14674
- tool: z28.string(),
14675
- valid: z28.boolean(),
14676
- error: z28.string().optional()
14732
+ var selfTestOutputSchema = z29.object({
14733
+ passed: z29.number(),
14734
+ failed: z29.number(),
14735
+ total: z29.number(),
14736
+ results: z29.array(z29.object({
14737
+ tool: z29.string(),
14738
+ valid: z29.boolean(),
14739
+ error: z29.string().optional()
14677
14740
  }))
14678
14741
  });
14679
14742
  function handleSelfTest(server) {
@@ -14724,9 +14787,9 @@ function handleSelfTest(server) {
14724
14787
  }
14725
14788
 
14726
14789
  // src/tools/usage.ts
14727
- import { z as z29 } from "zod/v3";
14728
- var usageSummarySchema = z29.object({
14729
- periodDays: z29.number().min(1).max(90).optional().describe("Number of days to look back (default 30, max 90)")
14790
+ import { z as z30 } from "zod/v3";
14791
+ var usageSummarySchema = z30.object({
14792
+ periodDays: z30.number().min(1).max(90).optional().describe("Number of days to look back (default 30, max 90)")
14730
14793
  });
14731
14794
  async function handleUsageSummary(periodDays) {
14732
14795
  const ws = await getWorkspaceContext();
@@ -14898,35 +14961,35 @@ var WORKSPACE_ACTIONS = [
14898
14961
  "proposals-respond",
14899
14962
  "proposals-count"
14900
14963
  ];
14901
- var workspaceSchema = z30.object({
14902
- action: z30.enum(WORKSPACE_ACTIONS).describe(
14964
+ var workspaceSchema = z31.object({
14965
+ action: z31.enum(WORKSPACE_ACTIONS).describe(
14903
14966
  "'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). 'proposals-list': list open consent proposals (absorbs governance-proposals action=list). 'proposals-respond': approve/reject a consent proposal (absorbs governance-proposals action=respond). 'proposals-count': count open consent proposals (absorbs governance-proposals action=count)."
14904
14967
  ),
14905
- limit: z30.number().min(1).max(50).optional().describe("For 'audit': how many recent calls to show (max 50, default 20)."),
14906
- periodDays: z30.number().min(1).max(90).optional().describe("For 'usage': number of days to look back (default 30, max 90)."),
14907
- status: z30.enum(["open", "approved", "objected", "expired"]).optional().describe("For 'proposals-list': filter by status (default: open)."),
14908
- proposalId: z30.string().max(200).optional().describe("For 'proposals-respond': proposal ID."),
14909
- verdict: z30.enum(["approve", "reject"]).optional().describe("For 'proposals-respond': approve or reject."),
14910
- reason: z30.string().max(2e3).optional().describe("For 'proposals-respond': reason for the verdict (required when rejecting).")
14968
+ limit: z31.number().min(1).max(50).optional().describe("For 'audit': how many recent calls to show (max 50, default 20)."),
14969
+ periodDays: z31.number().min(1).max(90).optional().describe("For 'usage': number of days to look back (default 30, max 90)."),
14970
+ status: z31.enum(["open", "approved", "objected", "expired"]).optional().describe("For 'proposals-list': filter by status (default: open)."),
14971
+ proposalId: z31.string().max(200).optional().describe("For 'proposals-respond': proposal ID."),
14972
+ verdict: z31.enum(["approve", "reject"]).optional().describe("For 'proposals-respond': approve or reject."),
14973
+ reason: z31.string().max(2e3).optional().describe("For 'proposals-respond': reason for the verdict (required when rejecting).")
14911
14974
  });
14912
- var workspaceCheckVariant = z30.object({ action: z30.literal("check") });
14913
- var workspaceWhoamiVariant = z30.object({ action: z30.literal("whoami") });
14914
- var workspaceStatusVariant = z30.object({ action: z30.literal("status") });
14915
- var workspaceAuditVariant = z30.object({ action: z30.literal("audit"), limit: z30.number().min(1).max(50).optional().default(20) });
14916
- var workspaceSelfTestVariant = z30.object({ action: z30.literal("self-test") });
14917
- var workspaceUsageVariant = z30.object({ action: z30.literal("usage"), periodDays: z30.number().min(1).max(90).optional() });
14918
- var workspaceProposalsListVariant = z30.object({
14919
- action: z30.literal("proposals-list"),
14920
- status: z30.enum(["open", "approved", "objected", "expired"]).optional()
14975
+ var workspaceCheckVariant = z31.object({ action: z31.literal("check") });
14976
+ var workspaceWhoamiVariant = z31.object({ action: z31.literal("whoami") });
14977
+ var workspaceStatusVariant = z31.object({ action: z31.literal("status") });
14978
+ var workspaceAuditVariant = z31.object({ action: z31.literal("audit"), limit: z31.number().min(1).max(50).optional().default(20) });
14979
+ var workspaceSelfTestVariant = z31.object({ action: z31.literal("self-test") });
14980
+ var workspaceUsageVariant = z31.object({ action: z31.literal("usage"), periodDays: z31.number().min(1).max(90).optional() });
14981
+ var workspaceProposalsListVariant = z31.object({
14982
+ action: z31.literal("proposals-list"),
14983
+ status: z31.enum(["open", "approved", "objected", "expired"]).optional()
14921
14984
  });
14922
- var workspaceProposalsRespondVariant = z30.object({
14923
- action: z30.literal("proposals-respond"),
14924
- proposalId: z30.string().max(200),
14925
- verdict: z30.enum(["approve", "reject"]),
14926
- reason: z30.string().max(2e3).optional()
14985
+ var workspaceProposalsRespondVariant = z31.object({
14986
+ action: z31.literal("proposals-respond"),
14987
+ proposalId: z31.string().max(200),
14988
+ verdict: z31.enum(["approve", "reject"]),
14989
+ reason: z31.string().max(2e3).optional()
14927
14990
  });
14928
- var workspaceProposalsCountVariant = z30.object({ action: z30.literal("proposals-count") });
14929
- var workspaceActionUnion = z30.discriminatedUnion("action", [
14991
+ var workspaceProposalsCountVariant = z31.object({ action: z31.literal("proposals-count") });
14992
+ var workspaceActionUnion = z31.discriminatedUnion("action", [
14930
14993
  workspaceCheckVariant,
14931
14994
  workspaceWhoamiVariant,
14932
14995
  workspaceStatusVariant,
@@ -14982,7 +15045,7 @@ function registerWorkspaceTools(server) {
14982
15045
  }
14983
15046
 
14984
15047
  // src/tools/feedback.ts
14985
- import { z as z31 } from "zod/v3";
15048
+ import { z as z32 } from "zod/v3";
14986
15049
 
14987
15050
  // src/lib/productFeedbackConstants.ts
14988
15051
  var PRODUCT_FEEDBACK_CATEGORIES = ["bug", "friction", "idea", "praise", "other"];
@@ -14993,9 +15056,9 @@ var VENDOR_SETTABLE_STATUSES = PRODUCT_FEEDBACK_STATUSES.filter(
14993
15056
 
14994
15057
  // src/tools/feedback.ts
14995
15058
  var actions = ["submit", "list", "queue", "note", "group", "status"];
14996
- var category = z31.enum(PRODUCT_FEEDBACK_CATEGORIES);
14997
- var status = z31.enum(PRODUCT_FEEDBACK_STATUSES);
14998
- var vendorStatus = z31.enum(VENDOR_SETTABLE_STATUSES);
15059
+ var category = z32.enum(PRODUCT_FEEDBACK_CATEGORIES);
15060
+ var status = z32.enum(PRODUCT_FEEDBACK_STATUSES);
15061
+ var vendorStatus = z32.enum(VENDOR_SETTABLE_STATUSES);
14999
15062
  var GATEWAY_MAX_STRING_BYTES = 10240;
15000
15063
  var utf8Bytes = (value) => new TextEncoder().encode(value).length;
15001
15064
  var fitsGatewayBytes = (value) => utf8Bytes(value) <= GATEWAY_MAX_STRING_BYTES;
@@ -15004,32 +15067,32 @@ var byteLimitMessage = (field) => ({
15004
15067
  });
15005
15068
  var MESSAGE_DISPLAY_LIMIT = 1e3;
15006
15069
  var FULL_MESSAGE_MAX_LIMIT = 5;
15007
- var feedbackSchema = z31.object({
15008
- 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."),
15009
- message: z31.string().max(1e4).optional().describe("Required for submit: the product feedback text (max 10,000 chars and 10,240 UTF-8 bytes)."),
15070
+ var feedbackSchema = z32.object({
15071
+ 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."),
15072
+ message: z32.string().max(1e4).optional().describe("Required for submit: the product feedback text (max 10,000 chars and 10,240 UTF-8 bytes)."),
15010
15073
  category: category.optional().describe("Submit/queue category; submit defaults to other."),
15011
- command: z31.string().max(1e3).optional().describe("Optional submit command context; argument values are scrubbed server-side."),
15012
- route: z31.string().max(500).optional().describe("Optional submit route context."),
15013
- client: z31.string().max(100).optional().describe("Optional submit client label."),
15014
- feedbackId: z31.string().max(200).optional().describe("Required for note/status: target feedback ID."),
15015
- feedbackIds: z31.array(z31.string().max(200)).max(100).optional().describe("Required for group: 1\u2013100 target feedback IDs."),
15016
- note: z31.string().max(4e3).optional().describe("Required for note: replacement triage note (max 10,240 UTF-8 bytes)."),
15074
+ command: z32.string().max(1e3).optional().describe("Optional submit command context; argument values are scrubbed server-side."),
15075
+ route: z32.string().max(500).optional().describe("Optional submit route context."),
15076
+ client: z32.string().max(100).optional().describe("Optional submit client label."),
15077
+ feedbackId: z32.string().max(200).optional().describe("Required for note/status: target feedback ID."),
15078
+ feedbackIds: z32.array(z32.string().max(200)).max(100).optional().describe("Required for group: 1\u2013100 target feedback IDs."),
15079
+ note: z32.string().max(4e3).optional().describe("Required for note: replacement triage note (max 10,240 UTF-8 bytes)."),
15017
15080
  status: status.optional().describe("list/queue filter (any status, including 'screening'); the status action's required target value excludes 'screening' (system-only)."),
15018
- groupId: z31.string().min(1).max(200).nullable().optional().describe("Group filter, or required group destination; null explicitly clears grouping."),
15019
- 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."),
15020
- since: z31.number().optional().describe("Queue-only lower createdAt window bound (inclusive) in epoch milliseconds."),
15021
- 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."),
15022
- limit: z31.number().int().min(1).max(100).optional().describe("list/queue row limit, default 50, maximum 100."),
15023
- cursor: z31.string().max(2e3).optional().describe("Opaque pagination cursor from a previous list/queue response (continueCursor); omit for the first page."),
15024
- full: z31.boolean().optional().describe(`list/queue only: return untruncated messages; allowed only when limit <= ${FULL_MESSAGE_MAX_LIMIT}.`)
15081
+ groupId: z32.string().min(1).max(200).nullable().optional().describe("Group filter, or required group destination; null explicitly clears grouping."),
15082
+ 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."),
15083
+ since: z32.number().optional().describe("Queue-only lower createdAt window bound (inclusive) in epoch milliseconds."),
15084
+ 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."),
15085
+ limit: z32.number().int().min(1).max(100).optional().describe("list/queue row limit, default 50, maximum 100."),
15086
+ cursor: z32.string().max(2e3).optional().describe("Opaque pagination cursor from a previous list/queue response (continueCursor); omit for the first page."),
15087
+ full: z32.boolean().optional().describe(`list/queue only: return untruncated messages; allowed only when limit <= ${FULL_MESSAGE_MAX_LIMIT}.`)
15025
15088
  });
15026
- var union = z31.discriminatedUnion("action", [
15027
- z31.object({ action: z31.literal("submit"), message: z31.string().min(1).max(1e4).refine(fitsGatewayBytes, byteLimitMessage("message")), category: category.optional(), command: z31.string().max(1e3).optional(), route: z31.string().max(500).optional(), client: z31.string().max(100).optional() }),
15028
- 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() }),
15029
- 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() }),
15030
- z31.object({ action: z31.literal("note"), feedbackId: z31.string().min(1).max(200), note: z31.string().max(4e3).refine(fitsGatewayBytes, byteLimitMessage("note")) }),
15031
- 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() }),
15032
- z31.object({ action: z31.literal("status"), feedbackId: z31.string().min(1).max(200), status: vendorStatus })
15089
+ var union = z32.discriminatedUnion("action", [
15090
+ z32.object({ action: z32.literal("submit"), message: z32.string().min(1).max(1e4).refine(fitsGatewayBytes, byteLimitMessage("message")), category: category.optional(), command: z32.string().max(1e3).optional(), route: z32.string().max(500).optional(), client: z32.string().max(100).optional() }),
15091
+ 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() }),
15092
+ 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() }),
15093
+ z32.object({ action: z32.literal("note"), feedbackId: z32.string().min(1).max(200), note: z32.string().max(4e3).refine(fitsGatewayBytes, byteLimitMessage("note")) }),
15094
+ 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() }),
15095
+ z32.object({ action: z32.literal("status"), feedbackId: z32.string().min(1).max(200), status: vendorStatus })
15033
15096
  ]);
15034
15097
  var specs = {
15035
15098
  submit: { params: ["message", "category", "command", "route", "client"], description: "message is required; category defaults to other." },
@@ -15156,34 +15219,34 @@ function registerFeedbackTool(server) {
15156
15219
  }
15157
15220
 
15158
15221
  // src/tools/shape.ts
15159
- import { z as z32 } from "zod/v3";
15222
+ import { z as z33 } from "zod/v3";
15160
15223
  var SHAPE_ACTIONS = ["list", "show", "agree", "dismiss"];
15161
15224
  var LIST_DISPOSITIONS = ["pending", "agreed", "dismissed", "expired"];
15162
15225
  var LIST_OUTCOMES = ["not_candidate", "atomic", "compound", "unavailable"];
15163
- var shapeSchema = z32.object({
15164
- action: z32.enum(SHAPE_ACTIONS).describe(
15226
+ var shapeSchema = z33.object({
15227
+ action: z33.enum(SHAPE_ACTIONS).describe(
15165
15228
  "'list': list shape advisories for this workspace, latest per subject. 'show': show one shape advisory by id. 'agree': agree with a compound advisory's split verdict. 'dismiss': dismiss a compound advisory's split verdict."
15166
15229
  ),
15167
- disposition: z32.enum(LIST_DISPOSITIONS).optional().describe(
15230
+ disposition: z33.enum(LIST_DISPOSITIONS).optional().describe(
15168
15231
  "For 'list': filter by disposition. Omitting both disposition and outcome defaults to the actionable set (disposition:pending, outcome:compound)."
15169
15232
  ),
15170
- outcome: z32.enum(LIST_OUTCOMES).optional().describe(
15233
+ outcome: z33.enum(LIST_OUTCOMES).optional().describe(
15171
15234
  "For 'list': filter by outcome. Omitting both disposition and outcome defaults to the actionable set (disposition:pending, outcome:compound)."
15172
15235
  ),
15173
- limit: z32.number().min(1).max(200).optional().describe("For 'list': max rows (default 50, max 200)."),
15174
- rowId: z32.string().max(200).optional().describe("For 'show'/'agree'/'dismiss': the advisory row id."),
15175
- reason: z32.string().max(1e3).optional().describe("For 'agree'/'dismiss': optional reason (capped at 1000 chars).")
15236
+ limit: z33.number().min(1).max(200).optional().describe("For 'list': max rows (default 50, max 200)."),
15237
+ rowId: z33.string().max(200).optional().describe("For 'show'/'agree'/'dismiss': the advisory row id."),
15238
+ reason: z33.string().max(1e3).optional().describe("For 'agree'/'dismiss': optional reason (capped at 1000 chars).")
15176
15239
  });
15177
- var shapeListVariant = z32.object({
15178
- action: z32.literal("list"),
15179
- disposition: z32.enum(LIST_DISPOSITIONS).optional(),
15180
- outcome: z32.enum(LIST_OUTCOMES).optional(),
15181
- limit: z32.number().min(1).max(200).optional()
15240
+ var shapeListVariant = z33.object({
15241
+ action: z33.literal("list"),
15242
+ disposition: z33.enum(LIST_DISPOSITIONS).optional(),
15243
+ outcome: z33.enum(LIST_OUTCOMES).optional(),
15244
+ limit: z33.number().min(1).max(200).optional()
15182
15245
  });
15183
- var shapeShowVariant = z32.object({ action: z32.literal("show"), rowId: z32.string().max(200) });
15184
- var shapeAgreeVariant = z32.object({ action: z32.literal("agree"), rowId: z32.string().max(200), reason: z32.string().max(1e3).optional() });
15185
- var shapeDismissVariant = z32.object({ action: z32.literal("dismiss"), rowId: z32.string().max(200), reason: z32.string().max(1e3).optional() });
15186
- var shapeActionUnion = z32.discriminatedUnion("action", [
15246
+ var shapeShowVariant = z33.object({ action: z33.literal("show"), rowId: z33.string().max(200) });
15247
+ var shapeAgreeVariant = z33.object({ action: z33.literal("agree"), rowId: z33.string().max(200), reason: z33.string().max(1e3).optional() });
15248
+ var shapeDismissVariant = z33.object({ action: z33.literal("dismiss"), rowId: z33.string().max(200), reason: z33.string().max(1e3).optional() });
15249
+ var shapeActionUnion = z33.discriminatedUnion("action", [
15187
15250
  shapeListVariant,
15188
15251
  shapeShowVariant,
15189
15252
  shapeAgreeVariant,
@@ -15330,7 +15393,7 @@ function registerShapeTools(server) {
15330
15393
  }
15331
15394
 
15332
15395
  // src/tools/question.ts
15333
- import { z as z33 } from "zod/v3";
15396
+ import { z as z34 } from "zod/v3";
15334
15397
 
15335
15398
  // src/lib/strip.ts
15336
15399
  var ANSI_AND_CONTROL_RE2 = /\x1b\[[0-9;]*[A-Za-z]|\x1b\][^\x07]*\x07|\x1b[^[\]0-9;A-Za-z]?|[\x00-\x08\x0b-\x1f\x7f]/g;
@@ -15344,29 +15407,29 @@ function sanitizeSingleLineField(str) {
15344
15407
 
15345
15408
  // src/tools/question.ts
15346
15409
  var QUESTION_ACTIONS = ["create", "adopt", "assign", "snooze", "decline", "answer", "force-close", "list"];
15347
- var questionSchema = z33.object({
15348
- action: z33.enum(QUESTION_ACTIONS).describe(
15410
+ var questionSchema = z34.object({
15411
+ action: z34.enum(QUESTION_ACTIONS).describe(
15349
15412
  "'create': create a new routed question from text (domains come from `pb question --help` / this tool's own refusal \u2014 never hardcode a slug). 'adopt': attach routing to a tension already captured (e.g. via `pb capture \"TEN: ...\"`) \u2014 the pilot's real birth path; without adopt, captured tensions stay invisible to routing forever. 'assign': confirm ('take it', omit toRole/toPerson) or reassign (supply toRole and/or toPerson) ownership. 'snooze': defer a routed/escalated question (max 2, then it escalates). 'decline': pass on a suggested question, or (as owner/lead) decline an owned one \u2014 reason required. 'answer': close the loop \u2014 creates the answering entry itself unless --entry is given. '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)."
15350
15413
  ),
15351
- 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'."),
15352
- text: z33.string().max(5e3).optional().describe("'create': the question text. 'answer': the answer text (mutually exclusive with answerEntryId, max 2000 chars)."),
15353
- domain: z33.string().max(200).optional().describe("'create'/'adopt': the domain slug (see this tool's refusal for the live list)."),
15354
- blocks: z33.array(z33.string().max(200)).max(50).optional().describe("'create'/'adopt': entry ids this question is blocking (repeatable)."),
15355
- toRole: z33.string().max(200).optional().describe("'assign': reassign to this role (human ROL-nnn form or a raw entry id)."),
15356
- toPerson: z33.string().max(200).optional().describe("'assign': reassign to this person (a raw person id)."),
15357
- reason: z33.string().max(2e3).optional().describe("'decline'/'force-close': required reason."),
15358
- answerEntryId: z33.string().max(200).optional().describe("'answer': point at an already-written entry instead of supplying text (mutually exclusive with text)."),
15359
- 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).")
15414
+ 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'."),
15415
+ text: z34.string().max(5e3).optional().describe("'create': the question text. 'answer': the answer text (mutually exclusive with answerEntryId, max 2000 chars)."),
15416
+ domain: z34.string().max(200).optional().describe("'create'/'adopt': the domain slug (see this tool's refusal for the live list)."),
15417
+ blocks: z34.array(z34.string().max(200)).max(50).optional().describe("'create'/'adopt': entry ids this question is blocking (repeatable)."),
15418
+ toRole: z34.string().max(200).optional().describe("'assign': reassign to this role (human ROL-nnn form or a raw entry id)."),
15419
+ toPerson: z34.string().max(200).optional().describe("'assign': reassign to this person (a raw person id)."),
15420
+ reason: z34.string().max(2e3).optional().describe("'decline'/'force-close': required reason."),
15421
+ answerEntryId: z34.string().max(200).optional().describe("'answer': point at an already-written entry instead of supplying text (mutually exclusive with text)."),
15422
+ 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).")
15360
15423
  });
15361
- var createVariant = z33.object({ action: z33.literal("create"), text: z33.string().min(1).max(5e3), domain: z33.string().max(200).optional(), blocks: z33.array(z33.string().max(200)).max(50).optional() });
15362
- var adoptVariant = z33.object({ action: z33.literal("adopt"), entryId: z33.string().max(200), domain: z33.string().max(200).optional(), blocks: z33.array(z33.string().max(200)).max(50).optional() });
15363
- var assignVariant = z33.object({ action: z33.literal("assign"), entryId: z33.string().max(200), toRole: z33.string().max(200).optional(), toPerson: z33.string().max(200).optional() });
15364
- var snoozeVariant = z33.object({ action: z33.literal("snooze"), entryId: z33.string().max(200) });
15365
- var declineVariant = z33.object({ action: z33.literal("decline"), entryId: z33.string().max(200), reason: z33.string().min(1).max(2e3) });
15366
- 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() });
15367
- var forceCloseVariant = z33.object({ action: z33.literal("force-close"), entryId: z33.string().max(200), reason: z33.string().min(1).max(2e3) });
15368
- var listVariant = z33.object({ action: z33.literal("list"), mine: z33.boolean().optional() });
15369
- var questionActionUnion = z33.discriminatedUnion("action", [
15424
+ var createVariant = z34.object({ action: z34.literal("create"), text: z34.string().min(1).max(5e3), domain: z34.string().max(200).optional(), blocks: z34.array(z34.string().max(200)).max(50).optional() });
15425
+ var adoptVariant = z34.object({ action: z34.literal("adopt"), entryId: z34.string().max(200), domain: z34.string().max(200).optional(), blocks: z34.array(z34.string().max(200)).max(50).optional() });
15426
+ var assignVariant = z34.object({ action: z34.literal("assign"), entryId: z34.string().max(200), toRole: z34.string().max(200).optional(), toPerson: z34.string().max(200).optional() });
15427
+ var snoozeVariant = z34.object({ action: z34.literal("snooze"), entryId: z34.string().max(200) });
15428
+ var declineVariant = z34.object({ action: z34.literal("decline"), entryId: z34.string().max(200), reason: z34.string().min(1).max(2e3) });
15429
+ 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() });
15430
+ var forceCloseVariant = z34.object({ action: z34.literal("force-close"), entryId: z34.string().max(200), reason: z34.string().min(1).max(2e3) });
15431
+ var listVariant = z34.object({ action: z34.literal("list"), mine: z34.boolean().optional() });
15432
+ var questionActionUnion = z34.discriminatedUnion("action", [
15370
15433
  createVariant,
15371
15434
  adoptVariant,
15372
15435
  assignVariant,
@@ -15606,23 +15669,23 @@ function registerQuestionTools(server) {
15606
15669
  }
15607
15670
 
15608
15671
  // src/tools/role.ts
15609
- import { z as z34 } from "zod/v3";
15672
+ import { z as z35 } from "zod/v3";
15610
15673
  var ROLE_ACTIONS = ["accountable"];
15611
- var roleSchema = z34.object({
15612
- action: z34.enum(ROLE_ACTIONS).describe("'accountable': what this role owns (explicit), reports on (reporting), and \u2014 not yet computed \u2014 inherits via Team-Lead vacancy coverage."),
15613
- roleId: z34.string().max(200).optional().describe("The role, by the human chain id `chain.getEntry` or `pb get` would print for it, or a raw entry id. Required for 'accountable'."),
15614
- canonicalKey: z34.string().max(200).optional().describe("'accountable': narrow to one kind (e.g. objective, key_result, tension)."),
15615
- limit: z34.number().int().positive().max(200).optional().describe("'accountable': max explicit-list rows per page (default and maximum 200)."),
15616
- cursor: z34.number().optional().describe("'accountable': continue the explicit list from an earlier truncated page's nextCursor.")
15674
+ var roleSchema = z35.object({
15675
+ action: z35.enum(ROLE_ACTIONS).describe("'accountable': what this role owns (explicit), reports on (reporting), and \u2014 not yet computed \u2014 inherits via Team-Lead vacancy coverage."),
15676
+ roleId: z35.string().max(200).optional().describe("The role, by the human chain id `chain.getEntry` or `pb get` would print for it, or a raw entry id. Required for 'accountable'."),
15677
+ canonicalKey: z35.string().max(200).optional().describe("'accountable': narrow to one kind (e.g. objective, key_result, tension)."),
15678
+ limit: z35.number().int().positive().max(200).optional().describe("'accountable': max explicit-list rows per page (default and maximum 200)."),
15679
+ cursor: z35.number().optional().describe("'accountable': continue the explicit list from an earlier truncated page's nextCursor.")
15617
15680
  });
15618
- var accountableVariant = z34.object({
15619
- action: z34.literal("accountable"),
15620
- roleId: z34.string().max(200),
15621
- canonicalKey: z34.string().max(200).optional(),
15622
- limit: z34.number().int().positive().max(200).optional(),
15623
- cursor: z34.number().optional()
15681
+ var accountableVariant = z35.object({
15682
+ action: z35.literal("accountable"),
15683
+ roleId: z35.string().max(200),
15684
+ canonicalKey: z35.string().max(200).optional(),
15685
+ limit: z35.number().int().positive().max(200).optional(),
15686
+ cursor: z35.number().optional()
15624
15687
  });
15625
- var roleActionUnion = z34.discriminatedUnion("action", [accountableVariant]);
15688
+ var roleActionUnion = z35.discriminatedUnion("action", [accountableVariant]);
15626
15689
  var ROLE_ACTION_SPECS = {
15627
15690
  accountable: { params: ["roleId", "canonicalKey", "limit", "cursor"], description: "roleId is required; canonicalKey/limit/cursor are optional." }
15628
15691
  };
@@ -15695,49 +15758,49 @@ function registerRoleTools(server) {
15695
15758
  }
15696
15759
 
15697
15760
  // src/tools/outcome.ts
15698
- import { z as z35 } from "zod/v3";
15761
+ import { z as z36 } from "zod/v3";
15699
15762
  var OUTCOME_ACTIONS = ["record", "list", "show"];
15700
15763
  var READING_KINDS = ["measurement", "estimate", "correction"];
15701
- var outcomeSchema = z35.object({
15702
- action: z35.enum(OUTCOME_ACTIONS).describe(
15764
+ var outcomeSchema = z36.object({
15765
+ action: z36.enum(OUTCOME_ACTIONS).describe(
15703
15766
  "'record': record a reading (evidence, not a verdict). 'list': list readings, newest first. 'show': the derived view \u2014 current, progress, pace, staleness, recorded completion."
15704
15767
  ),
15705
- entryId: z35.string().max(200).optional().describe("The key result (or other outcome-bearing) entry, by its chain id. Required for all three actions."),
15768
+ entryId: z36.string().max(200).optional().describe("The key result (or other outcome-bearing) entry, by its chain id. Required for all three actions."),
15706
15769
  // PR #858 review round 3 (Codex P2, PRRT_kwDORS4ils6gXHj9): a JSON number that overflows to
15707
15770
  // `Infinity` (e.g. `1e400`) parses fine in JS and passes a plain `z.number()`, but
15708
15771
  // `callGateway()` serializes it with `JSON.stringify`, which turns `Infinity` into `null` —
15709
15772
  // the backend's `v.number()` validator then rejects a call this tool's own schema accepted.
15710
15773
  // `.finite()` rejects it here, matching the explicit finite-value checks the CLI/other outcome
15711
15774
  // entry surfaces already use.
15712
- value: z35.number().finite().optional().describe("'record': the measured value. Required for 'record'."),
15713
- valueText: z35.string().max(500).optional().describe("'record': verbatim as-reported form when the source was not clean, e.g. '~62%'. Display only."),
15714
- asOf: z35.string().max(64).optional().describe("'record': when the world was in this state, as a parseable date (default: now). Back-dating a backfill is legitimate \u2014 it shows up as asOf earlier than recordedAt."),
15715
- kind: z35.enum(READING_KINDS).optional().describe("'record': measurement | estimate | correction (default: measurement)."),
15716
- correctsReadingId: z35.string().max(200).optional().describe("'record': required with kind='correction' \u2014 the reading id this replaces. Refused if that row is already superseded."),
15717
- recordedByRoleId: z35.string().max(200).optional().describe("'record': the accountable role (default: the entry's reporterRoleId, then ownerRoleId)."),
15718
- note: z35.string().max(2e3).optional().describe("'record': free-text note recorded with the reading."),
15719
- source: z35.string().max(500).optional().describe("'record': where the number came from \u2014 a dashboard name, a query, a URL."),
15720
- limit: z35.number().int().positive().max(200).optional().describe("'list': max rows to return (default and maximum 200).")
15775
+ value: z36.number().finite().optional().describe("'record': the measured value. Required for 'record'."),
15776
+ valueText: z36.string().max(500).optional().describe("'record': verbatim as-reported form when the source was not clean, e.g. '~62%'. Display only."),
15777
+ asOf: z36.string().max(64).optional().describe("'record': when the world was in this state, as a parseable date (default: now). Back-dating a backfill is legitimate \u2014 it shows up as asOf earlier than recordedAt."),
15778
+ kind: z36.enum(READING_KINDS).optional().describe("'record': measurement | estimate | correction (default: measurement)."),
15779
+ correctsReadingId: z36.string().max(200).optional().describe("'record': required with kind='correction' \u2014 the reading id this replaces. Refused if that row is already superseded."),
15780
+ recordedByRoleId: z36.string().max(200).optional().describe("'record': the accountable role (default: the entry's reporterRoleId, then ownerRoleId)."),
15781
+ note: z36.string().max(2e3).optional().describe("'record': free-text note recorded with the reading."),
15782
+ source: z36.string().max(500).optional().describe("'record': where the number came from \u2014 a dashboard name, a query, a URL."),
15783
+ limit: z36.number().int().positive().max(200).optional().describe("'list': max rows to return (default and maximum 200).")
15721
15784
  });
15722
- var recordVariant = z35.object({
15723
- action: z35.literal("record"),
15724
- entryId: z35.string().max(200),
15725
- value: z35.number().finite(),
15726
- valueText: z35.string().max(500).optional(),
15727
- asOf: z35.string().max(64).optional(),
15728
- kind: z35.enum(READING_KINDS).optional(),
15729
- correctsReadingId: z35.string().max(200).optional(),
15730
- recordedByRoleId: z35.string().max(200).optional(),
15731
- note: z35.string().max(2e3).optional(),
15732
- source: z35.string().max(500).optional()
15785
+ var recordVariant = z36.object({
15786
+ action: z36.literal("record"),
15787
+ entryId: z36.string().max(200),
15788
+ value: z36.number().finite(),
15789
+ valueText: z36.string().max(500).optional(),
15790
+ asOf: z36.string().max(64).optional(),
15791
+ kind: z36.enum(READING_KINDS).optional(),
15792
+ correctsReadingId: z36.string().max(200).optional(),
15793
+ recordedByRoleId: z36.string().max(200).optional(),
15794
+ note: z36.string().max(2e3).optional(),
15795
+ source: z36.string().max(500).optional()
15733
15796
  });
15734
- var listVariant2 = z35.object({
15735
- action: z35.literal("list"),
15736
- entryId: z35.string().max(200),
15737
- limit: z35.number().int().positive().max(200).optional()
15797
+ var listVariant2 = z36.object({
15798
+ action: z36.literal("list"),
15799
+ entryId: z36.string().max(200),
15800
+ limit: z36.number().int().positive().max(200).optional()
15738
15801
  });
15739
- var showVariant = z35.object({ action: z35.literal("show"), entryId: z35.string().max(200) });
15740
- var outcomeActionUnion = z35.discriminatedUnion("action", [recordVariant, listVariant2, showVariant]);
15802
+ var showVariant = z36.object({ action: z36.literal("show"), entryId: z36.string().max(200) });
15803
+ var outcomeActionUnion = z36.discriminatedUnion("action", [recordVariant, listVariant2, showVariant]);
15741
15804
  var OUTCOME_ACTION_SPECS = {
15742
15805
  record: {
15743
15806
  params: ["entryId", "value", "valueText", "asOf", "kind", "correctsReadingId", "recordedByRoleId", "note", "source"],
@@ -16445,12 +16508,12 @@ ${entry.labels.map((l) => `- ${l.name ?? l.slug}`).join("\n")}`);
16445
16508
  }
16446
16509
 
16447
16510
  // src/prompts/index.ts
16448
- import { z as z36 } from "zod/v3";
16511
+ import { z as z37 } from "zod/v3";
16449
16512
  function registerPrompts(server) {
16450
16513
  server.prompt(
16451
16514
  "review-against-rules",
16452
16515
  "Review code or a design decision against all business rules for a given domain. Fetches the rules and asks you to do a structured compliance review.",
16453
- { domain: z36.string().describe("Business rule domain (e.g. 'Identity & Access', 'Governance & Decision-Making')") },
16516
+ { domain: z37.string().describe("Business rule domain (e.g. 'Identity & Access', 'Governance & Decision-Making')") },
16454
16517
  async ({ domain }) => {
16455
16518
  const entries = await kernelQuery("chain.listEntries", { collectionSlug: "business-rules" });
16456
16519
  const rules = entries.filter((e) => e.data?.domain === domain);
@@ -16503,7 +16566,7 @@ Provide a structured review with a compliance status for each rule (COMPLIANT /
16503
16566
  server.prompt(
16504
16567
  "name-check",
16505
16568
  "Check variable names, field names, or API names against the glossary for terminology alignment. Flags drift from canonical terms.",
16506
- { names: z36.string().describe("Comma-separated list of names to check (e.g. 'vendor_id, compliance_level, formulator_type')") },
16569
+ { names: z37.string().describe("Comma-separated list of names to check (e.g. 'vendor_id, compliance_level, formulator_type')") },
16507
16570
  async ({ names }) => {
16508
16571
  const terms = await kernelQuery("chain.listEntries", { collectionSlug: "glossary" });
16509
16572
  const glossaryContext = terms.map(
@@ -16539,7 +16602,7 @@ Format as a table: Name | Status | Canonical Form | Action Needed`
16539
16602
  server.prompt(
16540
16603
  "draft-decision-record",
16541
16604
  "Draft a structured decision record from a description of what was decided. Includes context from recent decisions and relevant rules.",
16542
- { context: z36.string().describe("Description of the decision (e.g. 'We decided to use MRSL v3.1 as the conformance baseline because...')") },
16605
+ { context: z37.string().describe("Description of the decision (e.g. 'We decided to use MRSL v3.1 as the conformance baseline because...')") },
16543
16606
  async ({ context }) => {
16544
16607
  const recentDecisions = await kernelQuery("chain.listEntries", { collectionSlug: "decisions" });
16545
16608
  const sorted = [...recentDecisions].sort((a, b) => (b.data?.date ?? "") > (a.data?.date ?? "") ? 1 : -1).slice(0, 5);
@@ -16577,8 +16640,8 @@ After drafting, I can log it using the capture tool with collection "decisions".
16577
16640
  "draft-rule-from-context",
16578
16641
  "Draft a new business rule from an observation or discovery made while coding. Fetches existing rules for the domain to ensure consistency.",
16579
16642
  {
16580
- observation: z36.string().describe("What you observed or discovered (e.g. 'Suppliers can have multiple org types in Gateway')"),
16581
- domain: z36.string().describe("Which domain this rule belongs to (e.g. 'Governance & Decision-Making')")
16643
+ observation: z37.string().describe("What you observed or discovered (e.g. 'Suppliers can have multiple org types in Gateway')"),
16644
+ domain: z37.string().describe("Which domain this rule belongs to (e.g. 'Governance & Decision-Making')")
16582
16645
  },
16583
16646
  async ({ observation, domain }) => {
16584
16647
  const allRules = await kernelQuery("chain.listEntries", { collectionSlug: "business-rules" });
@@ -16857,4 +16920,4 @@ export {
16857
16920
  createProductBrainServer,
16858
16921
  initFeatureFlags
16859
16922
  };
16860
- //# sourceMappingURL=chunk-A4WEYWDI.js.map
16923
+ //# sourceMappingURL=chunk-NCVHDVO2.js.map