@productbrain/mcp 0.0.1-beta.9534 → 0.0.1-beta.9550

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.
@@ -43,11 +43,11 @@ import {
43
43
  trackQualityVerdict,
44
44
  trackSessionCaptureRate,
45
45
  trackZeroCaptureAuditFired
46
- } from "./chunk-HOSGKIO6.js";
46
+ } from "./chunk-J2ZAJCHH.js";
47
47
 
48
48
  // src/server.ts
49
49
  import { McpServer as McpServer2 } from "@modelcontextprotocol/sdk/server/mcp.js";
50
- import { z as z34 } from "zod/v3";
50
+ import { z as z35 } from "zod/v3";
51
51
 
52
52
  // src/lib/mcpGatewayClientMessages.ts
53
53
  function agentSessionNotActiveMessage(status2) {
@@ -390,7 +390,7 @@ function extractPreview(data, maxLen) {
390
390
  var TOOL_NAME_MIGRATIONS = /* @__PURE__ */ new Map([
391
391
  // ─── Pre-WP-484 atomic names (retargeted where the old RHS also retired) ──
392
392
  ["list-entries", 'entries action="list"'],
393
- ["get-entry", 'entries action="get"'],
393
+ ["get-entry", 'context action="get"'],
394
394
  ["batch-get", 'entries action="batch"'],
395
395
  ["search", 'entries action="search"'],
396
396
  ["relate-entries", 'relations action="create"'],
@@ -1793,14 +1793,14 @@ No DB writes \u2014 call without \`preview:true\` to capture for real.${result2.
1793
1793
 
1794
1794
  ${msg}
1795
1795
 
1796
- Use \`entries action=get\` to inspect the existing entry, or \`entries action=update\` to modify it.`
1796
+ Use \`context action=get\` to inspect the existing entry, or \`entries action=update\` to modify it.`
1797
1797
  }],
1798
1798
  structuredContent: failure(
1799
1799
  "DUPLICATE",
1800
1800
  msg,
1801
- "Use entries action=get to inspect the existing entry.",
1801
+ "Use context action=get to inspect the existing entry.",
1802
1802
  [
1803
- { tool: "entries", description: "Get existing entry", parameters: { action: "get", entryId: name } },
1803
+ { tool: "context", description: "Get existing entry", parameters: { action: "get", entryId: name } },
1804
1804
  { tool: "entries", description: "Update existing entry", parameters: { action: "update", entryId: "" } }
1805
1805
  ]
1806
1806
  )
@@ -2056,7 +2056,7 @@ Use \`entries action=get\` to inspect the existing entry, or \`entries action=up
2056
2056
  if (finalStatus === "committed") {
2057
2057
  next.push({ tool: "relations", description: "See its connections", parameters: { action: "find", entryId: finalEntryId } });
2058
2058
  } else {
2059
- next.push({ tool: "entries", description: "Review the draft alternative", parameters: { action: "get", entryId: finalEntryId } });
2059
+ next.push({ tool: "context", description: "Review the draft alternative", parameters: { action: "get", entryId: finalEntryId } });
2060
2060
  next.push({ tool: "entries", description: "Accept onto Chain", parameters: { action: "commit", entryId: finalEntryId } });
2061
2061
  }
2062
2062
  const qualityPhrase = verdictQualityPhrase(verdictResult);
@@ -2416,7 +2416,8 @@ async function handleUpdateEntry({ entryId, name, status: rawStatus, workflowSta
2416
2416
  }
2417
2417
  const summary = `Updated ${entryId} \u2014 ${versionMode}. Fields: ${appliedFields.join(", ") || "none"}.`;
2418
2418
  const next = [
2419
- { tool: toolName, description: "View updated entry", parameters: { action: "get", entryId } },
2419
+ { tool: "context", description: "View updated entry", parameters: { action: "get", entryId } },
2420
+ // DEC-1894: reads live on context
2420
2421
  { tool: toolName, description: "Accept onto Chain", parameters: { action: "commit", entryId } }
2421
2422
  ];
2422
2423
  return {
@@ -2653,7 +2654,7 @@ No DB writes \u2014 call without \`preview:true\` to accept for real.` }],
2653
2654
  }
2654
2655
  const next = [
2655
2656
  { tool: "relations", description: "See its connections", parameters: { action: "find", entryId } },
2656
- { tool: "entries", description: "View accepted entry", parameters: { action: "get", entryId } }
2657
+ { tool: "context", description: "View accepted entry", parameters: { action: "get", entryId } }
2657
2658
  ];
2658
2659
  const summary = `Accepted ${entryId} (${entry.name}) onto the Chain.`;
2659
2660
  const commitSuccessEnvelope = success(
@@ -3129,7 +3130,7 @@ ${recovery}`,
3129
3130
  `Moved ${result2.entryId} from ${result2.fromCollection} to ${result2.toCollection}.`,
3130
3131
  result2,
3131
3132
  [
3132
- { tool: "entries", description: "View updated entry", parameters: { action: "get", entryId } },
3133
+ { tool: "context", description: "View updated entry", parameters: { action: "get", entryId } },
3133
3134
  { tool: "quality", description: "Re-check quality", parameters: { action: "check", entryId } }
3134
3135
  ]
3135
3136
  )
@@ -3182,7 +3183,6 @@ function platformGlossarySearch(query, collection, status2) {
3182
3183
  import { z as z10 } from "zod/v3";
3183
3184
  var ENTRIES_ACTIONS = [
3184
3185
  "list",
3185
- "get",
3186
3186
  "batch",
3187
3187
  "search",
3188
3188
  "update",
@@ -3203,10 +3203,10 @@ var preflightLinks = z10.array(z10.object({ type: z10.string().max(200), entryId
3203
3203
  var entriesSchema = z10.object({
3204
3204
  links: preflightLinks.describe("For preflight: proposed context links; saves nothing."),
3205
3205
  action: z10.enum(ENTRIES_ACTIONS).describe(
3206
- "'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). 'still-true': confirm accuracy (the holder of the owning role, else the nearest seated Team Lead) \u2014 distinct from 'verify'; no content, version, or updatedAt change."
3206
+ "'preflight': inspect structural requirements before composing (requires collection). 'list': browse entries with filters. '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). 'still-true': confirm accuracy (the holder of the owning role, else the nearest seated Team Lead) \u2014 distinct from 'verify'; no content, version, or updatedAt change."
3207
3207
  ),
3208
3208
  entryId: z10.string().max(200).optional().describe(
3209
- "Entry ID, e.g. '<PREFIX>-<n>'. Required for: get, update, commit, history, move, verify, still-true."
3209
+ "Entry ID, e.g. '<PREFIX>-<n>'. Required for: update, commit, history, move, verify, still-true."
3210
3210
  ),
3211
3211
  entryIds: z10.array(z10.string().max(200)).min(1).max(20).optional().describe("Entry IDs for 'batch', e.g. ['TYPE-strategy', 'STR-jljeg7']"),
3212
3212
  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)."),
@@ -3259,10 +3259,6 @@ var entriesListVariant = z10.object({
3259
3259
  tag: z10.string().max(200).optional(),
3260
3260
  label: z10.string().max(200).optional()
3261
3261
  });
3262
- var entriesGetVariant = z10.object({
3263
- action: z10.literal("get"),
3264
- entryId: z10.string().max(200)
3265
- });
3266
3262
  var entriesBatchVariant = z10.object({
3267
3263
  action: z10.literal("batch"),
3268
3264
  entryIds: z10.array(z10.string().max(200)).min(1).max(20)
@@ -3289,7 +3285,6 @@ var entriesStillTrueVariant = stillTrueEntrySchema.extend({ action: z10.literal(
3289
3285
  var entriesActionUnion = z10.discriminatedUnion("action", [
3290
3286
  z10.object({ action: z10.literal("preflight"), collection: z10.string().max(200), canonicalKey: z10.string().max(200).optional(), links: preflightLinks }),
3291
3287
  entriesListVariant,
3292
- entriesGetVariant,
3293
3288
  entriesBatchVariant,
3294
3289
  entriesSearchVariant,
3295
3290
  entriesUpdateVariant,
@@ -3302,7 +3297,6 @@ var entriesActionUnion = z10.discriminatedUnion("action", [
3302
3297
  var ENTRIES_ACTION_SPECS = {
3303
3298
  preflight: { params: ["collection", "canonicalKey", "links"], description: "Inspect structure before composition; no writes or permission grant." },
3304
3299
  list: { params: ["collection", "status", "tag", "label"], description: "Browse accepted entries by default; status='draft' lists drafts. All params optional." },
3305
- get: { params: ["entryId"], description: "Fetch one entry by ID." },
3306
3300
  batch: { params: ["entryIds"], description: "Fetch up to 20 entries by ID." },
3307
3301
  search: { params: ["query", "collection", "status"], description: "Full-text search; query is required (min 2 chars)." },
3308
3302
  update: { params: ["entryId", "name", "status", "workflowStatus", "data", "order", "canonicalKey", "autoPublish", "changeNote", "changeReason", "sourceRef", "sourceExcerpt", "steeringOverrideReason", "coherencyAcknowledgement"], description: "entryId is required; every other field is optional." },
@@ -3460,7 +3454,6 @@ function registerEntriesTools(server) {
3460
3454
  return { content: [{ type: "text", text: renderEntryPreflight(result2).join("\n") }], structuredContent: success("Structural requirements checked; nothing saved.", result2) };
3461
3455
  },
3462
3456
  list: (data) => handleList(data.collection, data.status, data.tag, data.label),
3463
- get: (data) => handleGet(data.entryId),
3464
3457
  batch: (data) => handleBatch(data.entryIds),
3465
3458
  search: (data) => handleSearch(server, data.query, data.collection, data.status),
3466
3459
  // update/commit reuse knowledge.ts's extracted handlers — "entries" routes
@@ -3476,7 +3469,7 @@ function registerEntriesTools(server) {
3476
3469
  "entries",
3477
3470
  {
3478
3471
  title: "Entries",
3479
- 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 (publishes whenever the entry is not draft \u2014 includes archived, not just accepted/active; autoPublish is accepted but ignored).\n- **commit**: Accept a draft entry onto the Chain (SSOT). Runs the contradiction preflight first.\n- **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 verified (lightweight, no scan \u2014 see `quality action=verify-chain`).\n- **still-true**: confirm accuracy (the holder of the owning role; if that role is empty, the nearest seated Team Lead up the team tree).\n\nUse `entries action=get entryId="..."` to fetch one. Use `entries action=search query="..."` to discover.',
3472
+ 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- **batch**: Fetch multiple entries (max 20) in one call. Same shape as context action=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 (publishes whenever the entry is not draft \u2014 includes archived, not just accepted/active; autoPublish is accepted but ignored).\n- **commit**: Accept a draft entry onto the Chain (SSOT). Runs the contradiction preflight first.\n- **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 verified (lightweight, no scan \u2014 see `quality action=verify-chain`).\n- **still-true**: confirm accuracy (the holder of the owning role; if that role is empty, the nearest seated Team Lead up the team tree).\n\nOpen one entry with the read-only `context` tool: `context action=get entryId="..."`. Use `entries action=search query="..."` to discover.',
3480
3473
  inputSchema: entriesSchema,
3481
3474
  // Mixed read/write noun (§3 R3): can't be marked read-only once update/commit/move
3482
3475
  // live here too — accepted for the 11-tool default (§9 R3).
@@ -3805,7 +3798,7 @@ async function handleSearch(server, query, collection, status2) {
3805
3798
  # Search Results for "${query}"${scope} (${matches} match${matches === 1 ? "" : "es"})
3806
3799
 
3807
3800
  **By collection:** ${collSummary}`;
3808
- const footer = `_Tip: Use \`collection\` param to scope search. Use entries action=get with an entry ID for full details._`;
3801
+ const footer = `_Tip: Use \`collection\` param to scope search. Use context action=get with an entry ID for full details._`;
3809
3802
  const structuredResults = results.map((e) => ({
3810
3803
  entryId: String(e.entryId ?? ""),
3811
3804
  name: String(e.name ?? ""),
@@ -3927,7 +3920,7 @@ async function handleFind(entryId, direction) {
3927
3920
  lines.push(`No ${direction} relations found for \`${entryId}\`.`);
3928
3921
  }
3929
3922
  if (truncated) {
3930
- lines.push(`_Showing first ${MAX_RELATIONS} of ${relations.length} relations. Use entries action=get for the full picture._`);
3923
+ lines.push(`_Showing first ${MAX_RELATIONS} of ${relations.length} relations. Use context action=get for the full picture._`);
3931
3924
  }
3932
3925
  const structuredRelations = shown.map((r) => ({
3933
3926
  entryId: r.otherEntryId,
@@ -3953,7 +3946,7 @@ async function handleFind(entryId, direction) {
3953
3946
  structuredContent: success(
3954
3947
  `Found ${relations.length} relations for ${entryId}.`,
3955
3948
  { entryId, relations: structuredRelations, nodes, edges, total: relations.length },
3956
- [{ tool: "entries", description: "View entry details", parameters: { action: "get", entryId } }]
3949
+ [{ tool: "context", description: "View entry details", parameters: { action: "get", entryId } }]
3957
3950
  )
3958
3951
  };
3959
3952
  }
@@ -4225,7 +4218,7 @@ async function handleDelete(from, to, type) {
4225
4218
  }
4226
4219
 
4227
4220
  // src/tools/context.ts
4228
- import { z as z15 } from "zod/v3";
4221
+ import { z as z16 } from "zod/v3";
4229
4222
 
4230
4223
  // src/tools/documents.ts
4231
4224
  import { z as z14 } from "zod/v3";
@@ -4305,6 +4298,20 @@ This row pre-dates snapshot capture (legacy backfill), so no summary is availabl
4305
4298
  };
4306
4299
  }
4307
4300
 
4301
+ // src/tools/contextLookups.ts
4302
+ import { z as z15 } from "zod/v3";
4303
+ var LOOKUP_ACTION_DESCRIBE = "'get': one entry in full by ID. ";
4304
+ var LOOKUP_TOOL_LINES = "- **get**: Fetch a single entry by ID \u2014 full record with data, labels, relations, history.\n";
4305
+ var lookupVariants = [
4306
+ z15.object({ action: z15.literal("get"), entryId: z15.string().max(200) })
4307
+ ];
4308
+ var LOOKUP_ACTION_SPECS = {
4309
+ get: { params: ["entryId"], description: "entryId is required." }
4310
+ };
4311
+ var lookupHandlers = {
4312
+ get: (data) => handleGet(data.entryId)
4313
+ };
4314
+
4308
4315
  // src/tools/context.ts
4309
4316
  function annotateStaleNames(text) {
4310
4317
  const footnote = translateStaleToolNames(text);
@@ -4312,94 +4319,95 @@ function annotateStaleNames(text) {
4312
4319
  }
4313
4320
  function epistemicCollectionHint(collectionName) {
4314
4321
  const lc = collectionName.toLowerCase();
4315
- if (lc === "insights") return " \u2014 _verify confidence with `entries action=get`_";
4316
- if (lc === "assumptions") return " \u2014 _check evidence strength with `entries action=get`_";
4322
+ if (lc === "insights") return " \u2014 _verify confidence with `context action=get`_";
4323
+ if (lc === "assumptions") return " \u2014 _check evidence strength with `context action=get`_";
4317
4324
  return "";
4318
4325
  }
4319
- var CONTEXT_ACTIONS = ["gather", "build", "neighborhood", "changes", "chain", "cross-cut", "incremental", "brief", "last-verified-brief"];
4320
- var contextSchema = z15.object({
4326
+ var CONTEXT_ACTIONS = ["get", "gather", "build", "neighborhood", "changes", "chain", "cross-cut", "incremental", "brief", "last-verified-brief"];
4327
+ var contextSchema = z16.object({
4321
4328
  // provenance: neighborhood BET-142; changes/chain/cross-cut/incremental/brief BET-239 (E4, E6)
4322
- action: z15.enum(CONTEXT_ACTIONS).describe(
4323
- "'gather': assemble knowledge context (entry graph, task auto-load, journey mode, or graph mode). 'build': structured build spec for an entry. 'neighborhood': typed graph neighborhood for an entry \u2014 blocking chain, dependencies, parent context, tensions, staleness. 'changes': entries modified and relations created since a timestamp. Requires 'since' parameter. 'chain': directed traversal along one relation type to depth 4. Requires entryId. Optional: direction, relationType, maxHops (1-4). 'cross-cut': structural aggregation \u2014 all relations of a given type grouped by source collection. Requires 'relationType' parameter. 'incremental': delta since last brief run for a skill. Requires 'skill' parameter. Returns only entries changed since the skill's last brief. 'brief': compound intelligence query. Requires 'briefType' parameter: 'steering' (changes + structure + delta + readiness), 'confidence' (changes + active bets \u2014 use the pb CLI's `tensions list` for tensions), or 'delta' (changes + relations since timestamp). Optional 'since' for delta type. 'last-verified-brief': fetch the most recent verified brief snapshot for a (templateId, scopeKey) pair (absorbs documents action=get-last-verified-brief). Requires templateId and scopeKey."
4329
+ action: z16.enum(CONTEXT_ACTIONS).describe(
4330
+ LOOKUP_ACTION_DESCRIBE + "'gather': assemble knowledge context (entry graph, task auto-load, journey mode, or graph mode). 'build': structured build spec for an entry. 'neighborhood': typed graph neighborhood for an entry \u2014 blocking chain, dependencies, parent context, tensions, staleness. 'changes': entries modified and relations created since a timestamp. Requires 'since' parameter. 'chain': directed traversal along one relation type to depth 4. Requires entryId. Optional: direction, relationType, maxHops (1-4). 'cross-cut': structural aggregation \u2014 all relations of a given type grouped by source collection. Requires 'relationType' parameter. 'incremental': delta since last brief run for a skill. Requires 'skill' parameter. Returns only entries changed since the skill's last brief. 'brief': compound intelligence query. Requires 'briefType' parameter: 'steering' (changes + structure + delta + readiness), 'confidence' (changes + active bets \u2014 use the pb CLI's `tensions list` for tensions), or 'delta' (changes + relations since timestamp). Optional 'since' for delta type. 'last-verified-brief': fetch the most recent verified brief snapshot for a (templateId, scopeKey) pair (absorbs documents action=get-last-verified-brief). Requires templateId and scopeKey."
4324
4331
  ),
4325
- 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."),
4326
- mapEntryId: z15.string().max(200).optional().describe(
4332
+ entryId: z16.string().max(200).optional().describe("For 'get'/'build'/'neighborhood'/'chain': entry ID, e.g. '<PREFIX>-<n>'. For 'gather': optional entry ID for entry-graph mode."),
4333
+ mapEntryId: z16.string().max(200).optional().describe(
4327
4334
  "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>'."
4328
4335
  ),
4329
- task: z15.string().max(2e3).optional().describe("For 'gather': natural-language task description for loading task-relevant governance, binding constraints, and supporting context."),
4330
- since: z15.string().max(200).optional().describe(
4336
+ task: z16.string().max(2e3).optional().describe("For 'gather': natural-language task description for loading task-relevant governance, binding constraints, and supporting context."),
4337
+ since: z16.string().max(200).optional().describe(
4331
4338
  "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'."
4332
4339
  ),
4333
- 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."),
4334
- relationType: z15.string().max(200).optional().describe(
4340
+ direction: z16.enum(["outgoing", "incoming"]).default("outgoing").optional().describe("For 'chain' action: traversal direction. 'outgoing' follows relations from source, 'incoming' follows relations to source. Default: outgoing."),
4341
+ relationType: z16.string().max(200).optional().describe(
4335
4342
  "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', 'depends_on'."
4336
4343
  ),
4337
- mode: z15.enum(["search", "graph"]).default("search").optional().describe("For gather: 'search' (default) or 'graph' (enhanced with provenance paths). Ignored when mapEntryId is provided."),
4338
- 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)"),
4339
- maxResults: z15.number().min(1).max(25).default(10).optional().describe("Max entries to return in gather task mode (default 10)"),
4340
- 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."),
4341
- skill: z15.string().max(200).optional().describe(
4344
+ mode: z16.enum(["search", "graph"]).default("search").optional().describe("For gather: 'search' (default) or 'graph' (enhanced with provenance paths). Ignored when mapEntryId is provided."),
4345
+ maxHops: z16.number().min(1).max(4).default(2).describe("Relation traversal depth (1=direct only, 2=default, 3=wide net, 4=deep chain walk)"),
4346
+ maxResults: z16.number().min(1).max(25).default(10).optional().describe("Max entries to return in gather task mode (default 10)"),
4347
+ strategy: z16.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."),
4348
+ skill: z16.string().max(200).optional().describe(
4342
4349
  "Skill name for 'incremental' action \u2014 identifies which skill's brief history to compare against. Examples: 'preflight', 'shaping', 'review'. Required when action is 'incremental'."
4343
4350
  ),
4344
- briefType: z15.enum(["steering", "confidence", "delta"]).optional().describe(
4351
+ briefType: z16.enum(["steering", "confidence", "delta"]).optional().describe(
4345
4352
  "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 (tensions: use the pb CLI's `tensions list`, not this action). 'delta': changes + relations since a custom timestamp (use 'since' param). Required when action is 'brief'."
4346
4353
  ),
4347
- templateId: z15.string().max(200).optional().describe(
4354
+ templateId: z16.string().max(200).optional().describe(
4348
4355
  "For 'last-verified-brief': brief template identifier \u2014 currently 'steering-brief' is the only registered template."
4349
4356
  ),
4350
- scopeKey: z15.string().max(200).optional().describe(
4357
+ scopeKey: z16.string().max(200).optional().describe(
4351
4358
  "For 'last-verified-brief': canonical scope key \u2014 'workspace:<workspaceId>' or 'initiative:<INI-ID>'."
4352
4359
  )
4353
4360
  });
4354
- var contextGatherVariant = z15.object({
4355
- action: z15.literal("gather"),
4356
- entryId: z15.string().max(200).optional(),
4357
- mapEntryId: z15.string().max(200).optional(),
4358
- task: z15.string().max(2e3).optional(),
4359
- mode: z15.enum(["search", "graph"]).optional().default("search"),
4360
- maxHops: z15.number().min(1).max(4).optional().default(2),
4361
- maxResults: z15.number().min(1).max(25).optional().default(10),
4362
- strategy: z15.enum(["hybrid", "keyword"]).optional().default("keyword")
4361
+ var contextGatherVariant = z16.object({
4362
+ action: z16.literal("gather"),
4363
+ entryId: z16.string().max(200).optional(),
4364
+ mapEntryId: z16.string().max(200).optional(),
4365
+ task: z16.string().max(2e3).optional(),
4366
+ mode: z16.enum(["search", "graph"]).optional().default("search"),
4367
+ maxHops: z16.number().min(1).max(4).optional().default(2),
4368
+ maxResults: z16.number().min(1).max(25).optional().default(10),
4369
+ strategy: z16.enum(["hybrid", "keyword"]).optional().default("keyword")
4363
4370
  });
4364
- var contextBuildVariant = z15.object({
4365
- action: z15.literal("build"),
4366
- entryId: z15.string().max(200),
4367
- maxHops: z15.number().min(1).max(4).optional().default(2)
4371
+ var contextBuildVariant = z16.object({
4372
+ action: z16.literal("build"),
4373
+ entryId: z16.string().max(200),
4374
+ maxHops: z16.number().min(1).max(4).optional().default(2)
4368
4375
  });
4369
- var contextNeighborhoodVariant = z15.object({
4370
- action: z15.literal("neighborhood"),
4371
- entryId: z15.string().max(200)
4376
+ var contextNeighborhoodVariant = z16.object({
4377
+ action: z16.literal("neighborhood"),
4378
+ entryId: z16.string().max(200)
4372
4379
  });
4373
- var contextChangesVariant = z15.object({
4374
- action: z15.literal("changes"),
4375
- since: z15.string().max(200)
4380
+ var contextChangesVariant = z16.object({
4381
+ action: z16.literal("changes"),
4382
+ since: z16.string().max(200)
4376
4383
  });
4377
- var contextChainVariant = z15.object({
4378
- action: z15.literal("chain"),
4379
- entryId: z15.string().max(200),
4380
- direction: z15.enum(["outgoing", "incoming"]).optional().default("outgoing"),
4381
- maxHops: z15.number().min(1).max(4).optional().default(2),
4382
- relationType: z15.string().max(200).optional()
4384
+ var contextChainVariant = z16.object({
4385
+ action: z16.literal("chain"),
4386
+ entryId: z16.string().max(200),
4387
+ direction: z16.enum(["outgoing", "incoming"]).optional().default("outgoing"),
4388
+ maxHops: z16.number().min(1).max(4).optional().default(2),
4389
+ relationType: z16.string().max(200).optional()
4383
4390
  });
4384
- var contextCrossCutVariant = z15.object({
4385
- action: z15.literal("cross-cut"),
4386
- relationType: z15.string().max(200)
4391
+ var contextCrossCutVariant = z16.object({
4392
+ action: z16.literal("cross-cut"),
4393
+ relationType: z16.string().max(200)
4387
4394
  });
4388
- var contextIncrementalVariant = z15.object({
4389
- action: z15.literal("incremental"),
4390
- skill: z15.string().max(200)
4395
+ var contextIncrementalVariant = z16.object({
4396
+ action: z16.literal("incremental"),
4397
+ skill: z16.string().max(200)
4391
4398
  });
4392
- var contextBriefVariant = z15.object({
4393
- action: z15.literal("brief"),
4394
- briefType: z15.enum(["steering", "confidence", "delta"]),
4395
- since: z15.string().max(200).optional()
4399
+ var contextBriefVariant = z16.object({
4400
+ action: z16.literal("brief"),
4401
+ briefType: z16.enum(["steering", "confidence", "delta"]),
4402
+ since: z16.string().max(200).optional()
4396
4403
  });
4397
- var contextLastVerifiedBriefVariant = z15.object({
4398
- action: z15.literal("last-verified-brief"),
4399
- templateId: z15.string().max(200),
4400
- scopeKey: z15.string().max(200)
4404
+ var contextLastVerifiedBriefVariant = z16.object({
4405
+ action: z16.literal("last-verified-brief"),
4406
+ templateId: z16.string().max(200),
4407
+ scopeKey: z16.string().max(200)
4401
4408
  });
4402
- var contextActionUnion = z15.discriminatedUnion("action", [
4409
+ var contextActionUnion = z16.discriminatedUnion("action", [
4410
+ ...lookupVariants,
4403
4411
  contextGatherVariant,
4404
4412
  contextBuildVariant,
4405
4413
  contextNeighborhoodVariant,
@@ -4411,6 +4419,7 @@ var contextActionUnion = z15.discriminatedUnion("action", [
4411
4419
  contextLastVerifiedBriefVariant
4412
4420
  ]);
4413
4421
  var CONTEXT_ACTION_SPECS = {
4422
+ ...LOOKUP_ACTION_SPECS,
4414
4423
  gather: { params: ["entryId", "mapEntryId", "task", "mode", "maxHops", "maxResults", "strategy"], description: "All params optional; entryId/mapEntryId/task select the mode." },
4415
4424
  build: { params: ["entryId", "maxHops"], description: "entryId is required." },
4416
4425
  neighborhood: { params: ["entryId"], description: "entryId is required." },
@@ -4423,6 +4432,7 @@ var CONTEXT_ACTION_SPECS = {
4423
4432
  };
4424
4433
  function registerContextTools(server) {
4425
4434
  const contextHandlers = {
4435
+ ...lookupHandlers,
4426
4436
  gather: (data) => data.mapEntryId ? handleJourneyGather(server, data.mapEntryId, data.maxHops ?? 2, data.maxResults ?? 20) : handleGather(server, data.entryId, data.task, data.mode ?? "search", data.maxHops ?? 2, data.maxResults ?? 10, data.strategy ?? "keyword"),
4427
4437
  build: (data) => handleBuild(server, data.entryId, data.maxHops ?? 2),
4428
4438
  neighborhood: (data) => handleNeighborhood(data.entryId),
@@ -4446,7 +4456,7 @@ function registerContextTools(server) {
4446
4456
  "context",
4447
4457
  {
4448
4458
  title: "Context",
4449
- description: "Assemble knowledge context in one call. Nine actions:\n\n- **gather**: Three modes \u2014 (1) By entry: traverse the graph around a specific entry. (2) By task: load task-relevant governance, binding constraints, and supporting domain knowledge for a natural-language task. (3) Graph mode (entryId + mode='graph'): enhanced traversal with provenance paths.\n- **build**: Structured build spec for any entry \u2014 data, related entries, business rules, glossary terms, chain refs. Use when starting a build. Requires active session.\n- **neighborhood**: Typed graph neighborhood \u2014 blocking chain (what this blocks, 3 hops), dependency chain (what blocks this), parent context (sibling count), related tensions, staleness signal, isolation signal. Fast indexed lookups. Requires entryId.\n- **changes**: Detect entries modified and relations created since a timestamp. Use for incremental updates instead of full traversal. Requires 'since' (ISO 8601). Returns grouped counts by collection. Cap: 200 entries.\n- **chain**: Directed deep traversal along one relation type to depth 4. Use for dependency analysis, governance chains, strategic alignment. Requires entryId. Optional: direction (outgoing/incoming), relationType, maxHops (1-4). Cycle detection, fan-out cap 10/hop, total cap 100 nodes. Returns tree + edges.\n- **cross-cut**: Structural aggregation \u2014 all relations of a given type across the workspace, grouped by source collection. Use to answer 'show me everything connected by part_of'. Requires 'relationType'. Cap: 500 entries.\n- **incremental**: Delta since last brief run for a skill. Returns only entries changed since the skill's last brief, filtering out previously surfaced entries. Requires 'skill' parameter. Use for steering briefs that need incremental awareness.\n- **brief**: Compound intelligence query composing multiple primitives. Requires 'briefType': 'steering' (7d changes + structure + delta + readiness), 'confidence' (7d changes + active work packages \u2014 tensions: use the pb CLI's `tensions list`), or 'delta' (changes since custom timestamp). Auto-records brief run for steering.\n- **last-verified-brief**: Fetch the most recent verified brief snapshot for a (templateId, scopeKey) pair (absorbs `documents`). Use to build delta narratives.",
4459
+ description: "Read the Chain. Every action is a read except incremental, which records the brief run it steers.\n\n" + LOOKUP_TOOL_LINES + "- **gather**: Three modes \u2014 (1) By entry: traverse the graph around a specific entry. (2) By task: load task-relevant governance, binding constraints, and supporting domain knowledge for a natural-language task. (3) Graph mode (entryId + mode='graph'): enhanced traversal with provenance paths.\n- **build**: Structured build spec for any entry \u2014 data, related entries, business rules, glossary terms, chain refs. Use when starting a build. Requires active session.\n- **neighborhood**: Typed graph neighborhood \u2014 blocking chain (what this blocks, 3 hops), dependency chain (what blocks this), parent context (sibling count), related tensions, staleness signal, isolation signal. Fast indexed lookups. Requires entryId.\n- **changes**: Detect entries modified and relations created since a timestamp. Use for incremental updates instead of full traversal. Requires 'since' (ISO 8601). Returns grouped counts by collection. Cap: 200 entries.\n- **chain**: Directed deep traversal along one relation type to depth 4. Use for dependency analysis, governance chains, strategic alignment. Requires entryId. Optional: direction (outgoing/incoming), relationType, maxHops (1-4). Cycle detection, fan-out cap 10/hop, total cap 100 nodes. Returns tree + edges.\n- **cross-cut**: Structural aggregation \u2014 all relations of a given type across the workspace, grouped by source collection. Use to answer 'show me everything connected by part_of'. Requires 'relationType'. Cap: 500 entries.\n- **incremental**: Delta since last brief run for a skill. Returns only entries changed since the skill's last brief, filtering out previously surfaced entries. Requires 'skill' parameter. Use for steering briefs that need incremental awareness.\n- **brief**: Compound intelligence query composing multiple primitives. Requires 'briefType': 'steering' (7d changes + structure + delta + readiness), 'confidence' (7d changes + active work packages \u2014 tensions: use the pb CLI's `tensions list`), or 'delta' (changes since custom timestamp). Auto-records brief run for steering.\n- **last-verified-brief**: Fetch the most recent verified brief snapshot for a (templateId, scopeKey) pair (absorbs `documents`). Use to build delta narratives.",
4450
4460
  inputSchema: contextSchema,
4451
4461
  annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false }
4452
4462
  },
@@ -4657,7 +4667,7 @@ _This helps future sessions start with better constraints and context._`
4657
4667
  lines2.push("");
4658
4668
  }
4659
4669
  }
4660
- lines2.push(`_Use \`entries action=get\` for full details on any entry._`);
4670
+ lines2.push(`_Use \`context action=get\` for full details on any entry._`);
4661
4671
  const taskEntries = [...result3.steeringContext, ...result3.supportingContext].map((e) => ({
4662
4672
  entryId: e.entryId ?? String(Math.random()),
4663
4673
  name: e.name,
@@ -4845,7 +4855,7 @@ No editing path is currently available \u2014 the \`map\` MCP tool and the Corte
4845
4855
  lines.push("");
4846
4856
  }
4847
4857
  }
4848
- lines.push(`_Use \`entries action=get\` for full details. Link governance to steps: \`relations action=create\`._`);
4858
+ lines.push(`_Use \`context action=get\` for full details. Link governance to steps: \`relations action=create\`._`);
4849
4859
  return {
4850
4860
  content: [{ type: "text", text: lines.join("\n") }],
4851
4861
  structuredContent: success(
@@ -4987,7 +4997,7 @@ async function handleBuild(server, entryId, maxHops) {
4987
4997
  lines.push(chainRefs.slice(0, 15).map((r) => `- ${r}`).join("\n"));
4988
4998
  if (contextTruncated) {
4989
4999
  lines.push("");
4990
- lines.push("_Context was truncated (limits: 50 related, 20 rules, 30 glossary). Use entries action=get for full details._");
5000
+ lines.push("_Context was truncated (limits: 50 related, 20 rules, 30 glossary). Use context action=get for full details._");
4991
5001
  }
4992
5002
  return {
4993
5003
  content: [{ type: "text", text: annotateStaleNames(lines.join("\n")) }],
@@ -5329,7 +5339,7 @@ function formatConfidencePass(result2) {
5329
5339
  lines.push("_Tensions: see `pb tensions list` on the CLI \u2014 this pass no longer carries a tension count._");
5330
5340
  lines.push("");
5331
5341
  lines.push("## Trust");
5332
- lines.push("_Trust-weighted scoring active: agent-origin and unverified entries receive lower confidence scores (human=1.0, agent+verified=0.7, agent+unverified=0.56). Use `entries action=get` to inspect individual entry origin/verification. Use `orient -b` for workspace trust metrics._");
5342
+ lines.push("_Trust-weighted scoring active: agent-origin and unverified entries receive lower confidence scores (human=1.0, agent+verified=0.7, agent+unverified=0.56). Use `context action=get` to inspect individual entry origin/verification. Use `orient -b` for workspace trust metrics._");
5333
5343
  lines.push("");
5334
5344
  if (result2.snapshotWarning) {
5335
5345
  lines.push("_Note: Compound query spans multiple reads. Data consistency is not guaranteed across components (TEN-1029)._");
@@ -5394,7 +5404,7 @@ function formatTimeAgo(ms) {
5394
5404
  }
5395
5405
 
5396
5406
  // src/tools/collections.ts
5397
- import { z as z17 } from "zod/v3";
5407
+ import { z as z18 } from "zod/v3";
5398
5408
 
5399
5409
  // src/lib/bodyTemplate.ts
5400
5410
  function readBodyTemplateGuidance(bodyTemplate) {
@@ -5404,17 +5414,17 @@ ${entry.guidance}`).join("\n\n");
5404
5414
  }
5405
5415
 
5406
5416
  // src/tools/labels.ts
5407
- import { z as z16 } from "zod/v3";
5408
- var labelsSchema = z16.object({
5409
- 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"),
5410
- slug: z16.string().max(200).optional().describe("Label slug (required for create/update/delete/apply/remove)"),
5411
- name: z16.string().max(ENTRY_NAME_MAX_CHARS).optional().describe("Display name (required for create)"),
5412
- color: z16.string().max(50).optional().describe("Hex color, e.g. '#ef4444'"),
5413
- description: z16.string().max(LABEL_DESCRIPTION_MAX_CHARS).optional().describe("What this label means"),
5414
- parentSlug: z16.string().max(200).optional().describe("Parent group slug for label hierarchy"),
5415
- isGroup: z16.boolean().optional().describe("True if this is a group container, not a taggable label"),
5416
- order: z16.number().optional().describe("Sort order within its group"),
5417
- entryId: z16.string().max(200).optional().describe("Entry ID for apply/remove actions")
5417
+ import { z as z17 } from "zod/v3";
5418
+ var labelsSchema = z17.object({
5419
+ action: z17.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"),
5420
+ slug: z17.string().max(200).optional().describe("Label slug (required for create/update/delete/apply/remove)"),
5421
+ name: z17.string().max(ENTRY_NAME_MAX_CHARS).optional().describe("Display name (required for create)"),
5422
+ color: z17.string().max(50).optional().describe("Hex color, e.g. '#ef4444'"),
5423
+ description: z17.string().max(LABEL_DESCRIPTION_MAX_CHARS).optional().describe("What this label means"),
5424
+ parentSlug: z17.string().max(200).optional().describe("Parent group slug for label hierarchy"),
5425
+ isGroup: z17.boolean().optional().describe("True if this is a group container, not a taggable label"),
5426
+ order: z17.number().optional().describe("Sort order within its group"),
5427
+ entryId: z17.string().max(200).optional().describe("Entry ID for apply/remove actions")
5418
5428
  });
5419
5429
  async function handleLabelsList() {
5420
5430
  const labels = await kernelQuery("chain.listLabels");
@@ -5519,108 +5529,108 @@ var COLLECTIONS_ACTIONS = [
5519
5529
  "label-remove"
5520
5530
  ];
5521
5531
  var STATUS_CATEGORIES2 = ["draft", "current", "past", "discarded"];
5522
- var statusListEntrySchema = z17.object({ label: z17.string().max(200), category: z17.enum(STATUS_CATEGORIES2), archiveDefault: z17.boolean().optional(), resolveDefault: z17.boolean().optional() });
5523
- var qualityCriterionSchema = z17.object({
5524
- field: z17.string().max(200).describe("Entry data field key this criterion applies to, e.g. 'description', 'owner'"),
5532
+ var statusListEntrySchema = z18.object({ label: z18.string().max(200), category: z18.enum(STATUS_CATEGORIES2), archiveDefault: z18.boolean().optional(), resolveDefault: z18.boolean().optional() });
5533
+ var qualityCriterionSchema = z18.object({
5534
+ field: z18.string().max(200).describe("Entry data field key this criterion applies to, e.g. 'description', 'owner'"),
5525
5535
  // WP-480 S1: `max_length` — must mirror the Convex rule union, or the tool rejects a
5526
5536
  // valid criterion before the request ever reaches the server.
5527
- 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)."),
5528
- 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'.")
5537
+ rule: z18.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)."),
5538
+ value: z18.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'.")
5529
5539
  });
5530
- var fieldSchema = z17.object({
5531
- key: z17.string().max(200).describe("Field key, e.g. 'description', 'severity', 'status'"),
5532
- label: z17.string().max(200).describe("Display label, e.g. 'Description', 'Severity'"),
5533
- type: z17.string().max(50).describe("Field type: 'string', 'select', 'array', 'number', 'boolean'"),
5534
- required: z17.boolean().optional().describe("Whether this field is required"),
5535
- options: z17.array(z17.string().max(200)).max(200).optional().describe("Options for 'select' type fields"),
5536
- searchable: z17.boolean().optional().describe("Whether this field is included in full-text search"),
5537
- displayHint: z17.enum(["hero", "badge", "meta", "section", "hidden", "inline-meta"]).optional().describe("V2 rendering hint: how the field should be displayed in Cortex"),
5538
- zone: z17.enum(["header", "body", "meta"]).optional().describe("V2 layout zone: where the field appears in the entry view"),
5539
- colorMap: z17.record(z17.string().max(50)).optional().describe("V2 value-to-semantic-color mapping, e.g. { critical: 'danger', low: 'success' }"),
5540
- accentSource: z17.boolean().optional().describe("When true, this field's colorMap value drives the card-level accent styling"),
5541
- iconMap: z17.record(z17.string(), z17.string().max(50)).optional().describe("Maps field values to icons (emoji/symbol), prepended to badge text"),
5542
- helpText: z17.string().max(2e3).optional().describe("Help text shown in admin field editors"),
5543
- optionDescriptions: z17.record(z17.string().max(500)).optional().describe("Per-option guidance for select fields"),
5544
- 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"),
5545
- maxLength: z17.number().optional().describe("Maximum character length for field values. Three-tier resolution: explicit > displayHint > type fallback."),
5546
- minLength: z17.number().optional().describe("Minimum character length for field values. Only explicit \u2014 no defaults.")
5540
+ var fieldSchema = z18.object({
5541
+ key: z18.string().max(200).describe("Field key, e.g. 'description', 'severity', 'status'"),
5542
+ label: z18.string().max(200).describe("Display label, e.g. 'Description', 'Severity'"),
5543
+ type: z18.string().max(50).describe("Field type: 'string', 'select', 'array', 'number', 'boolean'"),
5544
+ required: z18.boolean().optional().describe("Whether this field is required"),
5545
+ options: z18.array(z18.string().max(200)).max(200).optional().describe("Options for 'select' type fields"),
5546
+ searchable: z18.boolean().optional().describe("Whether this field is included in full-text search"),
5547
+ displayHint: z18.enum(["hero", "badge", "meta", "section", "hidden", "inline-meta"]).optional().describe("V2 rendering hint: how the field should be displayed in Cortex"),
5548
+ zone: z18.enum(["header", "body", "meta"]).optional().describe("V2 layout zone: where the field appears in the entry view"),
5549
+ colorMap: z18.record(z18.string().max(50)).optional().describe("V2 value-to-semantic-color mapping, e.g. { critical: 'danger', low: 'success' }"),
5550
+ accentSource: z18.boolean().optional().describe("When true, this field's colorMap value drives the card-level accent styling"),
5551
+ iconMap: z18.record(z18.string(), z18.string().max(50)).optional().describe("Maps field values to icons (emoji/symbol), prepended to badge text"),
5552
+ helpText: z18.string().max(2e3).optional().describe("Help text shown in admin field editors"),
5553
+ optionDescriptions: z18.record(z18.string().max(500)).optional().describe("Per-option guidance for select fields"),
5554
+ semanticRole: z18.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"),
5555
+ maxLength: z18.number().optional().describe("Maximum character length for field values. Three-tier resolution: explicit > displayHint > type fallback."),
5556
+ minLength: z18.number().optional().describe("Minimum character length for field values. Only explicit \u2014 no defaults.")
5547
5557
  });
5548
- var collectionsSchema = z17.object({
5549
- action: z17.enum(COLLECTIONS_ACTIONS).describe(
5558
+ var collectionsSchema = z18.object({
5559
+ action: z18.enum(COLLECTIONS_ACTIONS).describe(
5550
5560
  "'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, 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."
5551
5561
  ),
5552
- slug: z17.string().max(200).optional().describe("URL-safe identifier for create/update, e.g. 'glossary', 'tech-debt'. For label-*: label slug."),
5553
- name: z17.string().max(ENTRY_NAME_MAX_CHARS).optional().describe("For label-*: the label's name. For update: refused (the catalog's)."),
5554
- description: z17.string().max(2e4).optional().describe("For label-*: what the label means (max 2,000 chars). For update: refused (the catalog's)."),
5555
- purpose: z17.string().max(2e3).optional().describe("Why this collection exists \u2014 strategic reason"),
5556
- icon: z17.string().max(50).optional().describe("For update: always refused \u2014 a collection's icon comes from the platform catalog."),
5557
- navGroup: z17.enum(["daily", "strategic", "governance", "reference", "collections"]).optional().describe("Sidebar placement: 'daily', 'strategic', 'governance', 'reference', 'collections'"),
5558
- fields: z17.array(fieldSchema).max(200).optional().describe("Field definitions for create, or replacement schema for update (replaces all fields)"),
5559
- axis: z17.enum(["work", "none", "pending"]).optional().describe("REQUIRED for create: 'work' (needs stageLabelMap + validWorkflowStatuses), 'none', or 'pending'. For update: always refused \u2014 a collection's axis comes from the platform catalog."),
5560
- 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."),
5561
- 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."),
5562
- defaultWorkflowStatus: z17.string().max(200).optional().describe("Default workflowStatus for new entries. For update: always refused \u2014 the status words come from the platform catalog."),
5563
- validWorkflowStatuses: z17.array(z17.string().max(200)).max(50).optional().describe("The allowed workflowStatus values for entries in this collection. For update: always refused \u2014 the status words come from the platform catalog."),
5562
+ slug: z18.string().max(200).optional().describe("URL-safe identifier for create/update, e.g. 'glossary', 'tech-debt'. For label-*: label slug."),
5563
+ name: z18.string().max(ENTRY_NAME_MAX_CHARS).optional().describe("For label-*: the label's name. For update: refused (the catalog's)."),
5564
+ description: z18.string().max(2e4).optional().describe("For label-*: what the label means (max 2,000 chars). For update: refused (the catalog's)."),
5565
+ purpose: z18.string().max(2e3).optional().describe("Why this collection exists \u2014 strategic reason"),
5566
+ icon: z18.string().max(50).optional().describe("For update: always refused \u2014 a collection's icon comes from the platform catalog."),
5567
+ navGroup: z18.enum(["daily", "strategic", "governance", "reference", "collections"]).optional().describe("Sidebar placement: 'daily', 'strategic', 'governance', 'reference', 'collections'"),
5568
+ fields: z18.array(fieldSchema).max(200).optional().describe("Field definitions for create, or replacement schema for update (replaces all fields)"),
5569
+ axis: z18.enum(["work", "none", "pending"]).optional().describe("REQUIRED for create: 'work' (needs stageLabelMap + validWorkflowStatuses), 'none', or 'pending'. For update: always refused \u2014 a collection's axis comes from the platform catalog."),
5570
+ stageLabelMap: z18.record(z18.string(), z18.enum(["open", "in_progress", "done", "stopped", "tag"])).optional().describe("Required when axis is 'work': maps each valid workflowStatus to a canonical stage."),
5571
+ defaultCanonicalKey: z18.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."),
5572
+ defaultWorkflowStatus: z18.string().max(200).optional().describe("Default workflowStatus for new entries. For update: always refused \u2014 the status words come from the platform catalog."),
5573
+ validWorkflowStatuses: z18.array(z18.string().max(200)).max(50).optional().describe("The allowed workflowStatus values for entries in this collection. For update: always refused \u2014 the status words come from the platform catalog."),
5564
5574
  // ENT-65, FEAT-200
5565
- classificationCheck: z17.string().max(500).optional().describe("LLM decision-tree check for this collection (3\u2013500 chars). Guides the classifier in routing entries here."),
5566
- classificationPriority: z17.number().optional().describe("Classifier priority (1\u20139, lower = higher priority). Used with classificationCheck to order the decision tree."),
5567
- 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."),
5568
- statusList: z17.array(statusListEntrySchema).max(50).optional().describe("Ordered status vocabulary: {label, category, archiveDefault?}[]. For update: always refused \u2014 the status words come from the platform catalog."),
5575
+ classificationCheck: z18.string().max(500).optional().describe("LLM decision-tree check for this collection (3\u2013500 chars). Guides the classifier in routing entries here."),
5576
+ classificationPriority: z18.number().optional().describe("Classifier priority (1\u20139, lower = higher priority). Used with classificationCheck to order the decision tree."),
5577
+ qualityCriteria: z18.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."),
5578
+ statusList: z18.array(statusListEntrySchema).max(50).optional().describe("Ordered status vocabulary: {label, category, archiveDefault?}[]. For update: always refused \u2014 the status words come from the platform catalog."),
5569
5579
  // For label-*
5570
- color: z17.string().max(50).optional().describe("For label-create/label-update: hex color, e.g. '#ef4444'."),
5571
- parentSlug: z17.string().max(200).optional().describe("For label-create: parent group slug for label hierarchy."),
5572
- isGroup: z17.boolean().optional().describe("For label-create/label-update: true if this is a group container, not a taggable label."),
5573
- order: z17.number().optional().describe("For label-create/label-update: sort order within its group."),
5574
- entryId: z17.string().max(200).optional().describe("For label-apply/label-remove: entry ID.")
5580
+ color: z18.string().max(50).optional().describe("For label-create/label-update: hex color, e.g. '#ef4444'."),
5581
+ parentSlug: z18.string().max(200).optional().describe("For label-create: parent group slug for label hierarchy."),
5582
+ isGroup: z18.boolean().optional().describe("For label-create/label-update: true if this is a group container, not a taggable label."),
5583
+ order: z18.number().optional().describe("For label-create/label-update: sort order within its group."),
5584
+ entryId: z18.string().max(200).optional().describe("For label-apply/label-remove: entry ID.")
5575
5585
  });
5576
- var collectionsListVariant = z17.object({ action: z17.literal("list") });
5577
- var collectionsDescribeVariant = z17.object({ action: z17.literal("describe"), slug: z17.string().max(200) });
5578
- var collectionsUpdateVariant = z17.object({
5579
- action: z17.literal("update"),
5580
- slug: z17.string().max(200),
5581
- name: z17.string().max(ENTRY_NAME_MAX_CHARS).optional(),
5582
- description: z17.string().max(2e4).optional(),
5583
- purpose: z17.string().max(2e3).optional(),
5584
- icon: z17.string().max(50).optional(),
5585
- navGroup: z17.enum(["daily", "strategic", "governance", "reference", "collections"]).optional(),
5586
- fields: z17.array(fieldSchema).optional(),
5587
- axis: z17.enum(["work", "none", "pending"]).optional(),
5588
- stageLabelMap: z17.record(z17.string(), z17.enum(["open", "in_progress", "done", "stopped", "tag"])).optional(),
5586
+ var collectionsListVariant = z18.object({ action: z18.literal("list") });
5587
+ var collectionsDescribeVariant = z18.object({ action: z18.literal("describe"), slug: z18.string().max(200) });
5588
+ var collectionsUpdateVariant = z18.object({
5589
+ action: z18.literal("update"),
5590
+ slug: z18.string().max(200),
5591
+ name: z18.string().max(ENTRY_NAME_MAX_CHARS).optional(),
5592
+ description: z18.string().max(2e4).optional(),
5593
+ purpose: z18.string().max(2e3).optional(),
5594
+ icon: z18.string().max(50).optional(),
5595
+ navGroup: z18.enum(["daily", "strategic", "governance", "reference", "collections"]).optional(),
5596
+ fields: z18.array(fieldSchema).optional(),
5597
+ axis: z18.enum(["work", "none", "pending"]).optional(),
5598
+ stageLabelMap: z18.record(z18.string(), z18.enum(["open", "in_progress", "done", "stopped", "tag"])).optional(),
5589
5599
  // WP-640 SWEEP (P1): axis/stageLabelMap repair legacy custom collections — see collections.ts's updateCollection.
5590
- defaultCanonicalKey: z17.string().max(200).optional(),
5591
- defaultWorkflowStatus: z17.string().max(200).optional(),
5592
- validWorkflowStatuses: z17.array(z17.string().max(200)).optional(),
5593
- classificationCheck: z17.string().max(500).optional(),
5594
- classificationPriority: z17.number().optional(),
5595
- qualityCriteria: z17.array(qualityCriterionSchema).optional(),
5596
- statusList: z17.array(statusListEntrySchema).optional()
5600
+ defaultCanonicalKey: z18.string().max(200).optional(),
5601
+ defaultWorkflowStatus: z18.string().max(200).optional(),
5602
+ validWorkflowStatuses: z18.array(z18.string().max(200)).optional(),
5603
+ classificationCheck: z18.string().max(500).optional(),
5604
+ classificationPriority: z18.number().optional(),
5605
+ qualityCriteria: z18.array(qualityCriterionSchema).optional(),
5606
+ statusList: z18.array(statusListEntrySchema).optional()
5597
5607
  });
5598
- var collectionsAuditVariant = z17.object({ action: z17.literal("audit") });
5599
- var collectionsExportVariant = z17.object({ action: z17.literal("export") });
5600
- var collectionsLabelListVariant = z17.object({ action: z17.literal("label-list") });
5601
- var collectionsLabelCreateVariant = z17.object({
5602
- action: z17.literal("label-create"),
5603
- slug: z17.string().max(200),
5604
- name: z17.string().max(ENTRY_NAME_MAX_CHARS),
5605
- color: z17.string().max(50).optional(),
5606
- description: z17.string().max(LABEL_DESCRIPTION_MAX_CHARS).optional(),
5607
- parentSlug: z17.string().max(200).optional(),
5608
- isGroup: z17.boolean().optional(),
5609
- order: z17.number().optional()
5608
+ var collectionsAuditVariant = z18.object({ action: z18.literal("audit") });
5609
+ var collectionsExportVariant = z18.object({ action: z18.literal("export") });
5610
+ var collectionsLabelListVariant = z18.object({ action: z18.literal("label-list") });
5611
+ var collectionsLabelCreateVariant = z18.object({
5612
+ action: z18.literal("label-create"),
5613
+ slug: z18.string().max(200),
5614
+ name: z18.string().max(ENTRY_NAME_MAX_CHARS),
5615
+ color: z18.string().max(50).optional(),
5616
+ description: z18.string().max(LABEL_DESCRIPTION_MAX_CHARS).optional(),
5617
+ parentSlug: z18.string().max(200).optional(),
5618
+ isGroup: z18.boolean().optional(),
5619
+ order: z18.number().optional()
5610
5620
  });
5611
- var collectionsLabelUpdateVariant = z17.object({
5612
- action: z17.literal("label-update"),
5613
- slug: z17.string().max(200),
5614
- name: z17.string().max(ENTRY_NAME_MAX_CHARS).optional(),
5615
- color: z17.string().max(50).optional(),
5616
- description: z17.string().max(LABEL_DESCRIPTION_MAX_CHARS).optional(),
5617
- isGroup: z17.boolean().optional(),
5618
- order: z17.number().optional()
5621
+ var collectionsLabelUpdateVariant = z18.object({
5622
+ action: z18.literal("label-update"),
5623
+ slug: z18.string().max(200),
5624
+ name: z18.string().max(ENTRY_NAME_MAX_CHARS).optional(),
5625
+ color: z18.string().max(50).optional(),
5626
+ description: z18.string().max(LABEL_DESCRIPTION_MAX_CHARS).optional(),
5627
+ isGroup: z18.boolean().optional(),
5628
+ order: z18.number().optional()
5619
5629
  });
5620
- var collectionsLabelDeleteVariant = z17.object({ action: z17.literal("label-delete"), slug: z17.string().max(200) });
5621
- var collectionsLabelApplyVariant = z17.object({ action: z17.literal("label-apply"), slug: z17.string().max(200), entryId: z17.string().max(200) });
5622
- var collectionsLabelRemoveVariant = z17.object({ action: z17.literal("label-remove"), slug: z17.string().max(200), entryId: z17.string().max(200) });
5623
- var collectionsActionUnion = z17.discriminatedUnion("action", [
5630
+ var collectionsLabelDeleteVariant = z18.object({ action: z18.literal("label-delete"), slug: z18.string().max(200) });
5631
+ var collectionsLabelApplyVariant = z18.object({ action: z18.literal("label-apply"), slug: z18.string().max(200), entryId: z18.string().max(200) });
5632
+ var collectionsLabelRemoveVariant = z18.object({ action: z18.literal("label-remove"), slug: z18.string().max(200), entryId: z18.string().max(200) });
5633
+ var collectionsActionUnion = z18.discriminatedUnion("action", [
5624
5634
  collectionsListVariant,
5625
5635
  collectionsDescribeVariant,
5626
5636
  collectionsUpdateVariant,
@@ -5928,7 +5938,7 @@ async function handleExport() {
5928
5938
  }
5929
5939
 
5930
5940
  // src/tools/orient.ts
5931
- import { z as z19 } from "zod/v3";
5941
+ import { z as z20 } from "zod/v3";
5932
5942
 
5933
5943
  // src/tools/planned-work.ts
5934
5944
  var MORE_DRAFTS_LINE = "_More drafts exist than shown. `entries action=list status=draft` lists more, but that list is capped as well; page with limit/cursor once entries list supports it._";
@@ -6781,7 +6791,7 @@ var GOVERNANCE_HERE_LINES = [
6781
6791
  ];
6782
6792
  var BRIEFING_PULL_COMMANDS = {
6783
6793
  cli: 'pb orient --task "<what you are doing>" \xB7 pb get <ID> \xB7 pb search <query>',
6784
- mcp: 'orient task="<what you are doing>" \xB7 entries action=get entryId=<ID> \xB7 entries action=search query=<query>'
6794
+ mcp: 'orient task="<what you are doing>" \xB7 context action=get entryId=<ID> \xB7 entries action=search query=<query>'
6785
6795
  };
6786
6796
  var BRIEFING_ANSWER_COMMANDS = {
6787
6797
  cli: 'pb question answer <ID> "<answer>"',
@@ -6986,7 +6996,7 @@ function getCollectionLabel(canonicalKey, form, workspaceCtx, collectionCtx) {
6986
6996
  }
6987
6997
 
6988
6998
  // src/tools/start_pb.ts
6989
- import { z as z18 } from "zod/v3";
6999
+ import { z as z19 } from "zod/v3";
6990
7000
 
6991
7001
  // src/lib/sessionNotices.ts
6992
7002
  var ANSI_AND_CONTROL_RE2 = /\x1b\[[0-9;]*[A-Za-z]|\x1b\][^\x07]*\x07|\x1b[^[\]0-9;A-Za-z]?|[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g;
@@ -7113,8 +7123,8 @@ function rankActiveBets(entries) {
7113
7123
  }
7114
7124
 
7115
7125
  // src/tools/start_pb.ts
7116
- var startPbSchema = z18.object({
7117
- task: z18.string().max(2e3).optional().describe(
7126
+ var startPbSchema = z19.object({
7127
+ task: z19.string().max(2e3).optional().describe(
7118
7128
  "What you're about to work on (e.g. 'implementing auth middleware'). Shapes the opener to the task \u2014 for every workspace state, including a fresh one."
7119
7129
  )
7120
7130
  });
@@ -7384,46 +7394,46 @@ async function markOrientedWithSnapshotFallback(agentSessionId, coherenceSnapsho
7384
7394
  }
7385
7395
  }
7386
7396
  var ORIENT_ACTIONS = ["start", "task"];
7387
- var orientSchema = z19.object({
7388
- action: z19.enum(ORIENT_ACTIONS).optional().default("task").describe(
7397
+ var orientSchema = z20.object({
7398
+ action: z20.enum(ORIENT_ACTIONS).optional().default("task").describe(
7389
7399
  "'start': universal session opener (absorbs start_pb) \u2014 a standup briefing for every workspace state, fresh or active. 'task': task-grounded context loader \u2014 the original orient behavior."
7390
7400
  ),
7391
- mode: z19.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."),
7392
- tier: z19.enum(["summary", "standard", "full"]).optional().describe(
7401
+ 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."),
7402
+ tier: z20.enum(["summary", "standard", "full"]).optional().describe(
7393
7403
  "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."
7394
7404
  ),
7395
- task: z19.string().max(2e3).optional().describe(
7405
+ task: z20.string().max(2e3).optional().describe(
7396
7406
  "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."
7397
7407
  ),
7398
7408
  // D1d (WP-754/TASK-204): matches the server's StartupResolutionSignals shape; domain resolution (original purpose) is deleted, sole survivor is `context.served` telemetry.
7399
- startupSignals: z19.object({
7400
- changedPaths: z19.array(z19.string()).max(25).optional().describe("Paths changed in the current working tree, if known (e.g. from a prior git status/diff tool call)."),
7401
- reviewedArtifactRefs: z19.array(z19.string()).max(25).optional().describe("Chain entry IDs the caller has already reviewed this session, if tracked."),
7402
- branchName: z19.string().max(120).optional().describe("Current git branch name, if known."),
7403
- worktreeName: z19.string().max(120).optional().describe("Current worktree/directory name, if known.")
7409
+ startupSignals: z20.object({
7410
+ 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)."),
7411
+ reviewedArtifactRefs: z20.array(z20.string()).max(25).optional().describe("Chain entry IDs the caller has already reviewed this session, if tracked."),
7412
+ branchName: z20.string().max(120).optional().describe("Current git branch name, if known."),
7413
+ worktreeName: z20.string().max(120).optional().describe("Current worktree/directory name, if known.")
7404
7414
  }).optional().describe("For 'task': best-effort startup signals \u2014 changedPaths/reviewedArtifactRefs/branchName/worktreeName. All optional; omit fields you don't know."),
7405
- invocationPath: z19.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.")
7415
+ 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.")
7406
7416
  });
7407
- var orientStartVariant = z19.object({
7408
- action: z19.literal("start"),
7409
- task: z19.string().max(2e3).optional()
7417
+ var orientStartVariant = z20.object({
7418
+ action: z20.literal("start"),
7419
+ task: z20.string().max(2e3).optional()
7410
7420
  });
7411
- var orientTaskVariant = z19.object({
7412
- action: z19.literal("task"),
7413
- mode: z19.enum(["full", "brief"]).optional().default("full"),
7414
- tier: z19.enum(["summary", "standard", "full"]).optional(),
7415
- task: z19.string().max(2e3).optional(),
7421
+ var orientTaskVariant = z20.object({
7422
+ action: z20.literal("task"),
7423
+ mode: z20.enum(["full", "brief"]).optional().default("full"),
7424
+ tier: z20.enum(["summary", "standard", "full"]).optional(),
7425
+ task: z20.string().max(2e3).optional(),
7416
7426
  // WP-486 Slice 1 (FEAT-1371) — mirrors orientSchema's top-level declaration above; see its
7417
7427
  // doc comment for the shape rationale.
7418
- startupSignals: z19.object({
7419
- changedPaths: z19.array(z19.string()).max(25).optional(),
7420
- reviewedArtifactRefs: z19.array(z19.string()).max(25).optional(),
7421
- branchName: z19.string().max(120).optional(),
7422
- worktreeName: z19.string().max(120).optional()
7428
+ startupSignals: z20.object({
7429
+ changedPaths: z20.array(z20.string()).max(25).optional(),
7430
+ reviewedArtifactRefs: z20.array(z20.string()).max(25).optional(),
7431
+ branchName: z20.string().max(120).optional(),
7432
+ worktreeName: z20.string().max(120).optional()
7423
7433
  }).optional(),
7424
- invocationPath: z19.enum(["session-start", "session-close", "manual-orient", "handshake", "unknown"]).optional()
7434
+ invocationPath: z20.enum(["session-start", "session-close", "manual-orient", "handshake", "unknown"]).optional()
7425
7435
  });
7426
- var orientActionUnion = z19.discriminatedUnion("action", [
7436
+ var orientActionUnion = z20.discriminatedUnion("action", [
7427
7437
  orientStartVariant,
7428
7438
  orientTaskVariant
7429
7439
  ]);
@@ -7802,7 +7812,7 @@ async function _handleOrient({ mode = "full", tier, task, startupSignals, invoca
7802
7812
  if (e.reasoning) lines.push(` _${e.reasoning}_`);
7803
7813
  if ("primer" in e && typeof e.primer === "string" && e.primer.length > 0) {
7804
7814
  const PRIMER_MAX = 1200;
7805
- const primerText = e.primer.length > PRIMER_MAX ? e.primer.slice(0, PRIMER_MAX) + "\n\u2026 (truncated \u2014 use entries action=get for full primer)" : e.primer;
7815
+ const primerText = e.primer.length > PRIMER_MAX ? e.primer.slice(0, PRIMER_MAX) + "\n\u2026 (truncated \u2014 use context action=get for full primer)" : e.primer;
7806
7816
  lines.push("");
7807
7817
  lines.push(" **Primer (paste when starting implementation):**");
7808
7818
  lines.push(" ```");
@@ -7824,7 +7834,7 @@ async function _handleOrient({ mode = "full", tier, task, startupSignals, invoca
7824
7834
  lines.push(`- \`${id}\` [${type}]${coll} \u2014 ${e.name}`);
7825
7835
  if ("primer" in e && typeof e.primer === "string" && e.primer.length > 0) {
7826
7836
  const PRIMER_MAX = 1200;
7827
- const primerText = e.primer.length > PRIMER_MAX ? e.primer.slice(0, PRIMER_MAX) + "\n\u2026 (truncated \u2014 use entries action=get for full primer)" : e.primer;
7837
+ const primerText = e.primer.length > PRIMER_MAX ? e.primer.slice(0, PRIMER_MAX) + "\n\u2026 (truncated \u2014 use context action=get for full primer)" : e.primer;
7828
7838
  lines.push("");
7829
7839
  lines.push(" **Primer:**");
7830
7840
  lines.push(" ```");
@@ -8122,7 +8132,7 @@ async function _handleOrient({ mode = "full", tier, task, startupSignals, invoca
8122
8132
  }
8123
8133
 
8124
8134
  // src/tools/workflows.ts
8125
- import { z as z20 } from "zod/v3";
8135
+ import { z as z21 } from "zod/v3";
8126
8136
 
8127
8137
  // src/workflows/descriptor.ts
8128
8138
  function cloneWorkflowQuestion(question) {
@@ -8967,73 +8977,73 @@ function workflowRunOutputToText(output) {
8967
8977
 
8968
8978
  // src/tools/workflows.ts
8969
8979
  var WORKFLOWS_ACTIONS = ["list", "start", "checkpoint", "get-run"];
8970
- var jsonValueSchema = z20.lazy(
8971
- () => z20.union([
8972
- z20.string(),
8973
- z20.number(),
8974
- z20.boolean(),
8975
- z20.null(),
8976
- z20.array(jsonValueSchema),
8977
- z20.record(jsonValueSchema)
8980
+ var jsonValueSchema = z21.lazy(
8981
+ () => z21.union([
8982
+ z21.string(),
8983
+ z21.number(),
8984
+ z21.boolean(),
8985
+ z21.null(),
8986
+ z21.array(jsonValueSchema),
8987
+ z21.record(jsonValueSchema)
8978
8988
  ])
8979
8989
  );
8980
- var workflowRunOutputInputSchema = z20.union([
8981
- z20.object({
8982
- format: z20.literal("freetext"),
8983
- value: z20.string()
8990
+ var workflowRunOutputInputSchema = z21.union([
8991
+ z21.object({
8992
+ format: z21.literal("freetext"),
8993
+ value: z21.string()
8984
8994
  }),
8985
- z20.object({
8986
- format: z20.literal("list"),
8987
- value: z20.array(z20.string())
8995
+ z21.object({
8996
+ format: z21.literal("list"),
8997
+ value: z21.array(z21.string())
8988
8998
  }),
8989
- z20.object({
8990
- format: z20.literal("choice"),
8991
- value: z20.union([z20.string(), z20.array(z20.string())])
8999
+ z21.object({
9000
+ format: z21.literal("choice"),
9001
+ value: z21.union([z21.string(), z21.array(z21.string())])
8992
9002
  }),
8993
- z20.object({
8994
- format: z20.literal("structured"),
9003
+ z21.object({
9004
+ format: z21.literal("structured"),
8995
9005
  value: jsonValueSchema
8996
9006
  })
8997
9007
  ]);
8998
- var workflowsSchema = z20.object({
8999
- action: z20.enum(WORKFLOWS_ACTIONS).describe(
9008
+ var workflowsSchema = z21.object({
9009
+ action: z21.enum(WORKFLOWS_ACTIONS).describe(
9000
9010
  "'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."
9001
9011
  ),
9002
- workflowId: z20.string().max(200).optional().describe("Workflow ID for start, checkpoint, or get-run, e.g. 'retro', 'implementation-review'"),
9003
- runId: z20.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)."),
9004
- roundId: z20.string().max(200).optional().describe("Round ID for checkpoint, e.g. 'what-went-well'"),
9005
- output: z20.union([z20.string(), workflowRunOutputInputSchema]).optional().describe("The round's output \u2014 either legacy synthesized text or a typed workflow run payload."),
9006
- isFinal: z20.boolean().optional().describe("If true, finalize an existing durable workflow run from its terminal round and create the summary chain entry."),
9007
- restart: z20.boolean().optional().describe("If true, start a new durable run from the workflow's first round in the current session."),
9008
- summaryName: z20.string().max(ENTRY_NAME_MAX_CHARS).optional().describe("Optional name for final chain entry. If omitted, the workflow summary template is used."),
9009
- summaryDescription: z20.string().max(ENTRY_BODY_MAX_CHARS).optional().describe("Optional override for the final chain entry description. Defaults to the final round output text."),
9010
- summaryEntryId: z20.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."),
9012
+ workflowId: z21.string().max(200).optional().describe("Workflow ID for start, checkpoint, or get-run, e.g. 'retro', 'implementation-review'"),
9013
+ 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)."),
9014
+ roundId: z21.string().max(200).optional().describe("Round ID for checkpoint, e.g. 'what-went-well'"),
9015
+ output: z21.union([z21.string(), workflowRunOutputInputSchema]).optional().describe("The round's output \u2014 either legacy synthesized text or a typed workflow run payload."),
9016
+ isFinal: z21.boolean().optional().describe("If true, finalize an existing durable workflow run from its terminal round and create the summary chain entry."),
9017
+ restart: z21.boolean().optional().describe("If true, start a new durable run from the workflow's first round in the current session."),
9018
+ summaryName: z21.string().max(ENTRY_NAME_MAX_CHARS).optional().describe("Optional name for final chain entry. If omitted, the workflow summary template is used."),
9019
+ summaryDescription: z21.string().max(ENTRY_BODY_MAX_CHARS).optional().describe("Optional override for the final chain entry description. Defaults to the final round output text."),
9020
+ 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."),
9011
9021
  // WP-513: team+role to create the finalize summary AS OWNER of (rung 2 only).
9012
- ownerTeamEntryId: z20.string().max(200).optional().describe("For 'checkpoint' (isFinal): owning team (rung-2)."),
9013
- ownerRoleEntryId: z20.string().max(200).optional().describe("For 'checkpoint' (isFinal): owning role (rung-2).")
9022
+ ownerTeamEntryId: z21.string().max(200).optional().describe("For 'checkpoint' (isFinal): owning team (rung-2)."),
9023
+ ownerRoleEntryId: z21.string().max(200).optional().describe("For 'checkpoint' (isFinal): owning role (rung-2).")
9014
9024
  });
9015
- var workflowsListVariant = z20.object({ action: z20.literal("list") });
9016
- var workflowsGetRunVariant = z20.object({
9017
- action: z20.literal("get-run"),
9018
- runId: z20.string().max(200).optional(),
9019
- workflowId: z20.string().max(200).optional()
9025
+ var workflowsListVariant = z21.object({ action: z21.literal("list") });
9026
+ var workflowsGetRunVariant = z21.object({
9027
+ action: z21.literal("get-run"),
9028
+ runId: z21.string().max(200).optional(),
9029
+ workflowId: z21.string().max(200).optional()
9020
9030
  });
9021
- var workflowsStartVariant = z20.object({ action: z20.literal("start"), workflowId: z20.string().max(200) });
9022
- var workflowsCheckpointVariant = z20.object({
9023
- action: z20.literal("checkpoint"),
9024
- workflowId: z20.string().max(200),
9025
- roundId: z20.string().max(200),
9026
- output: z20.union([z20.string(), workflowRunOutputInputSchema]),
9027
- isFinal: z20.boolean().optional(),
9028
- restart: z20.boolean().optional(),
9029
- summaryName: z20.string().max(ENTRY_NAME_MAX_CHARS).optional(),
9030
- summaryDescription: z20.string().max(ENTRY_BODY_MAX_CHARS).optional(),
9031
- summaryEntryId: z20.string().max(200).optional(),
9032
- runId: z20.string().max(200).optional(),
9033
- ownerTeamEntryId: z20.string().max(200).optional(),
9034
- ownerRoleEntryId: z20.string().max(200).optional()
9031
+ var workflowsStartVariant = z21.object({ action: z21.literal("start"), workflowId: z21.string().max(200) });
9032
+ var workflowsCheckpointVariant = z21.object({
9033
+ action: z21.literal("checkpoint"),
9034
+ workflowId: z21.string().max(200),
9035
+ roundId: z21.string().max(200),
9036
+ output: z21.union([z21.string(), workflowRunOutputInputSchema]),
9037
+ isFinal: z21.boolean().optional(),
9038
+ restart: z21.boolean().optional(),
9039
+ summaryName: z21.string().max(ENTRY_NAME_MAX_CHARS).optional(),
9040
+ summaryDescription: z21.string().max(ENTRY_BODY_MAX_CHARS).optional(),
9041
+ summaryEntryId: z21.string().max(200).optional(),
9042
+ runId: z21.string().max(200).optional(),
9043
+ ownerTeamEntryId: z21.string().max(200).optional(),
9044
+ ownerRoleEntryId: z21.string().max(200).optional()
9035
9045
  });
9036
- var workflowsActionUnion = z20.discriminatedUnion("action", [
9046
+ var workflowsActionUnion = z21.discriminatedUnion("action", [
9037
9047
  workflowsListVariant,
9038
9048
  workflowsGetRunVariant,
9039
9049
  workflowsStartVariant,
@@ -9762,7 +9772,7 @@ function parseListOutput(output) {
9762
9772
  }
9763
9773
 
9764
9774
  // src/tools/quality.ts
9765
- import { z as z21 } from "zod/v3";
9775
+ import { z as z22 } from "zod/v3";
9766
9776
 
9767
9777
  // src/lib/spineVerdictRead.ts
9768
9778
  function isRecord(value) {
@@ -9927,36 +9937,36 @@ async function handleSpineCheck(story, refresh = false) {
9927
9937
 
9928
9938
  // src/tools/quality.ts
9929
9939
  var QUALITY_ACTIONS = ["check", "re-evaluate", "verify-chain", "spine-check"];
9930
- var qualitySchema = z21.object({
9931
- action: z21.enum(QUALITY_ACTIONS).describe(
9940
+ var qualitySchema = z22.object({
9941
+ action: z22.enum(QUALITY_ACTIONS).describe(
9932
9942
  "'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`. 'spine-check': structural completeness of the purpose+vision+strategy spine \u2014 story:true also runs the on-demand one-story judgment."
9933
9943
  ),
9934
- entryId: z21.string().max(200).optional().describe("For 'check'/'re-evaluate': entry ID, e.g. 'TEN-graph-db', '<PREFIX>-<n>'."),
9935
- context: z21.enum(["capture", "commit", "review"]).default("review").optional().describe("For re-evaluate: evaluation context"),
9936
- collection: z21.string().max(200).optional().describe("For 'verify-chain': collection slug to verify (default: glossary)."),
9937
- mode: z21.enum(["report", "fix"]).optional().describe("For 'verify-chain': 'report' = read-only trust report (default). 'fix' = also update drifted codeMapping statuses."),
9938
- story: z21.boolean().optional().describe("For 'spine-check': also run the on-demand one-story LLM judgment (never scheduled; result labelled [unvalidated])."),
9939
- refresh: z21.boolean().optional().describe(
9944
+ entryId: z22.string().max(200).optional().describe("For 'check'/'re-evaluate': entry ID, e.g. 'TEN-graph-db', '<PREFIX>-<n>'."),
9945
+ context: z22.enum(["capture", "commit", "review"]).default("review").optional().describe("For re-evaluate: evaluation context"),
9946
+ collection: z22.string().max(200).optional().describe("For 'verify-chain': collection slug to verify (default: glossary)."),
9947
+ mode: z22.enum(["report", "fix"]).optional().describe("For 'verify-chain': 'report' = read-only trust report (default). 'fix' = also update drifted codeMapping statuses."),
9948
+ story: z22.boolean().optional().describe("For 'spine-check': also run the on-demand one-story LLM judgment (never scheduled; result labelled [unvalidated])."),
9949
+ refresh: z22.boolean().optional().describe(
9940
9950
  "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."
9941
9951
  )
9942
9952
  });
9943
- var qualityCheckVariant = z21.object({ action: z21.literal("check"), entryId: z21.string().max(200) });
9944
- var qualityReEvaluateVariant = z21.object({
9945
- action: z21.literal("re-evaluate"),
9946
- entryId: z21.string().max(200),
9947
- context: z21.enum(["capture", "commit", "review"]).optional().default("review")
9953
+ var qualityCheckVariant = z22.object({ action: z22.literal("check"), entryId: z22.string().max(200) });
9954
+ var qualityReEvaluateVariant = z22.object({
9955
+ action: z22.literal("re-evaluate"),
9956
+ entryId: z22.string().max(200),
9957
+ context: z22.enum(["capture", "commit", "review"]).optional().default("review")
9948
9958
  });
9949
- var qualityVerifyChainVariant = z21.object({
9950
- action: z21.literal("verify-chain"),
9951
- collection: z21.string().max(200).optional().default("glossary"),
9952
- mode: z21.enum(["report", "fix"]).optional().default("report")
9959
+ var qualityVerifyChainVariant = z22.object({
9960
+ action: z22.literal("verify-chain"),
9961
+ collection: z22.string().max(200).optional().default("glossary"),
9962
+ mode: z22.enum(["report", "fix"]).optional().default("report")
9953
9963
  });
9954
- var qualitySpineCheckVariant = z21.object({
9955
- action: z21.literal("spine-check"),
9956
- story: z21.boolean().optional().default(false),
9957
- refresh: z21.boolean().optional().default(false)
9964
+ var qualitySpineCheckVariant = z22.object({
9965
+ action: z22.literal("spine-check"),
9966
+ story: z22.boolean().optional().default(false),
9967
+ refresh: z22.boolean().optional().default(false)
9958
9968
  });
9959
- var qualityActionUnion = z21.discriminatedUnion("action", [
9969
+ var qualityActionUnion = z22.discriminatedUnion("action", [
9960
9970
  qualityCheckVariant,
9961
9971
  qualityReEvaluateVariant,
9962
9972
  qualityVerifyChainVariant,
@@ -9968,43 +9978,43 @@ var QUALITY_ACTION_SPECS = {
9968
9978
  "verify-chain": { params: ["collection", "mode"], description: "All params optional; collection defaults to 'glossary'." },
9969
9979
  "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)." }
9970
9980
  };
9971
- var qualityCheckOutputSchema = z21.object({
9972
- entryId: z21.string(),
9981
+ var qualityCheckOutputSchema = z22.object({
9982
+ entryId: z22.string(),
9973
9983
  /** WP-480 S1: false = the ID does not resolve to an entry (typo/deleted) — distinct from "no verdict yet". */
9974
- entryFound: z21.boolean().optional(),
9975
- hasVerdict: z21.boolean(),
9984
+ entryFound: z22.boolean().optional(),
9985
+ hasVerdict: z22.boolean(),
9976
9986
  /** WP-480 S1: the verdict was judged against content the entry no longer has — re-evaluate for a current one. */
9977
- stale: z21.boolean().optional(),
9978
- tier: z21.string().optional(),
9979
- passed: z21.boolean().optional(),
9980
- criteria: z21.array(z21.object({
9981
- id: z21.string(),
9982
- passed: z21.boolean(),
9983
- hint: z21.string().optional()
9987
+ stale: z22.boolean().optional(),
9988
+ tier: z22.string().optional(),
9989
+ passed: z22.boolean().optional(),
9990
+ criteria: z22.array(z22.object({
9991
+ id: z22.string(),
9992
+ passed: z22.boolean(),
9993
+ hint: z22.string().optional()
9984
9994
  }))
9985
9995
  });
9986
- var qualityReevaluateOutputSchema = z21.object({
9987
- entryId: z21.string(),
9988
- context: z21.string(),
9989
- score: z21.number(),
9990
- maxScore: z21.number(),
9991
- improved: z21.boolean()
9996
+ var qualityReevaluateOutputSchema = z22.object({
9997
+ entryId: z22.string(),
9998
+ context: z22.string(),
9999
+ score: z22.number(),
10000
+ maxScore: z22.number(),
10001
+ improved: z22.boolean()
9992
10002
  });
9993
- var qualitySpineCheckOutputSchema = z21.object({
9994
- hasVerdict: z21.boolean(),
9995
- noSpineEntries: z21.boolean().optional(),
9996
- structuralPassed: z21.boolean().optional(),
9997
- storyPassed: z21.boolean().nullable().optional(),
9998
- stale: z21.boolean().optional(),
10003
+ var qualitySpineCheckOutputSchema = z22.object({
10004
+ hasVerdict: z22.boolean(),
10005
+ noSpineEntries: z22.boolean().optional(),
10006
+ structuralPassed: z22.boolean().optional(),
10007
+ storyPassed: z22.boolean().nullable().optional(),
10008
+ stale: z22.boolean().optional(),
9999
10009
  // TASK-156: a capped membership scan must stay distinguishable from a complete one, and a
10000
10010
  // malformed verdict needs its own discriminator — both were silently stripped before this.
10001
- staleMemberIds: z21.array(z21.string()).optional(),
10002
- membershipTruncated: z21.boolean().optional(),
10011
+ staleMemberIds: z22.array(z22.string()).optional(),
10012
+ membershipTruncated: z22.boolean().optional(),
10003
10013
  // PRRT_kwDORS4ils6i_PVS: a KNOWN relations-fingerprint mismatch, distinct from "unknown" —
10004
10014
  // without this, a detected topology change and an unverifiable legacy fingerprint were
10005
10015
  // indistinguishable in structured output.
10006
- relationsChanged: z21.boolean().optional(),
10007
- malformed: z21.boolean().optional()
10016
+ relationsChanged: z22.boolean().optional(),
10017
+ malformed: z22.boolean().optional()
10008
10018
  });
10009
10019
  function registerQualityTools(server) {
10010
10020
  const qualityHandlers = {
@@ -10160,10 +10170,10 @@ async function handleReEvaluate(entryId, context) {
10160
10170
  }
10161
10171
 
10162
10172
  // src/tools/session.ts
10163
- import { z as z24 } from "zod/v3";
10173
+ import { z as z25 } from "zod/v3";
10164
10174
 
10165
10175
  // src/tools/wrapup.ts
10166
- import { z as z22 } from "zod/v3";
10176
+ import { z as z23 } from "zod/v3";
10167
10177
 
10168
10178
  // src/lib/compose-wrapup-view.ts
10169
10179
  function toComposed(e) {
@@ -10451,8 +10461,8 @@ async function runWrapupCommitAll(data) {
10451
10461
  overflowUnscanned
10452
10462
  };
10453
10463
  }
10454
- var wrapupSchema = z22.object({
10455
- action: z22.enum(["review", "commit-all"]).optional().describe(
10464
+ var wrapupSchema = z23.object({
10465
+ action: z23.enum(["review", "commit-all"]).optional().describe(
10456
10466
  "Action to perform. 'review' (default) shows the wrapup summary. 'commit-all' accepts all uncommitted drafts; it writes no relations."
10457
10467
  )
10458
10468
  });
@@ -10545,26 +10555,26 @@ ${text}` : text;
10545
10555
  }
10546
10556
 
10547
10557
  // src/tools/facilitate.ts
10548
- import { z as z23 } from "zod/v3";
10558
+ import { z as z24 } from "zod/v3";
10549
10559
  var FACILITATE_ACTIONS = ["resume", "commit-constellation"];
10550
- var coherencyAcknowledgementSchema = z23.object({
10551
- response: z23.string().max(200).describe("Acknowledgement response per offender: 'linked' | 'accepted-fix' | 'diverged'."),
10552
- entryId: z23.string().max(200).optional().describe("Entry the acknowledgement links to (e.g. the strategic spine entry)."),
10553
- reason: z23.string().max(2e3).optional().describe("Free-text justification, required for a 'diverged' response."),
10554
- subjectEntryId: z23.string().max(200).optional().describe("The refused entry this acknowledgement answers.")
10560
+ var coherencyAcknowledgementSchema = z24.object({
10561
+ response: z24.string().max(200).describe("Acknowledgement response per offender: 'linked' | 'accepted-fix' | 'diverged'."),
10562
+ entryId: z24.string().max(200).optional().describe("Entry the acknowledgement links to (e.g. the strategic spine entry)."),
10563
+ reason: z24.string().max(2e3).optional().describe("Free-text justification, required for a 'diverged' response."),
10564
+ subjectEntryId: z24.string().max(200).optional().describe("The refused entry this acknowledgement answers.")
10555
10565
  });
10556
- var facilitateSchema = z23.object({
10557
- action: z23.enum(FACILITATE_ACTIONS).describe(
10566
+ var facilitateSchema = z24.object({
10567
+ action: z24.enum(FACILITATE_ACTIONS).describe(
10558
10568
  "'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."
10559
10569
  ),
10560
- betEntryId: z23.string().max(200).optional().describe("Bet entry ID. Required for both actions."),
10561
- operationId: z23.string().max(200).optional().describe("Optional idempotency key for commit-constellation retries."),
10570
+ betEntryId: z24.string().max(200).optional().describe("Bet entry ID. Required for both actions."),
10571
+ operationId: z24.string().max(200).optional().describe("Optional idempotency key for commit-constellation retries."),
10562
10572
  // WP-465 slice ⑤: coherency retry controls for a COHERENCY_REFUSED constellation hold.
10563
10573
  // Forwarded verbatim to agentKnowledge.facilitateEnvelope (validation lives at the gate).
10564
- coherencyAcknowledgements: z23.array(coherencyAcknowledgementSchema).max(20).optional().describe(
10574
+ coherencyAcknowledgements: z24.array(coherencyAcknowledgementSchema).max(20).optional().describe(
10565
10575
  "Per-offender acknowledgements to retry a constellation held under standard/strict coherency mode. Each: {subjectEntryId, response: 'linked' | 'accepted-fix' | 'diverged', entryId?, reason?}."
10566
10576
  ),
10567
- steeringOverrideReason: z23.string().max(2e3).optional().describe(
10577
+ steeringOverrideReason: z24.string().max(2e3).optional().describe(
10568
10578
  "Typed override reason (>= 12 chars) to push a constellation past a coherency hold instead of acknowledging."
10569
10579
  )
10570
10580
  });
@@ -10820,44 +10830,44 @@ var SESSION_ACTIONS = [
10820
10830
  "resume",
10821
10831
  "commit-constellation"
10822
10832
  ];
10823
- var coherencyAcknowledgementFlatSchema2 = z24.object({
10824
- response: z24.string().max(200).describe("Acknowledgement response per offender: 'linked' | 'accepted-fix' | 'diverged'."),
10825
- entryId: z24.string().max(200).optional().describe("Entry the acknowledgement links to."),
10826
- reason: z24.string().max(2e3).optional().describe("Free-text justification, required for a 'diverged' response."),
10827
- subjectEntryId: z24.string().max(200).optional().describe("The refused entry this acknowledgement answers.")
10833
+ var coherencyAcknowledgementFlatSchema2 = z25.object({
10834
+ response: z25.string().max(200).describe("Acknowledgement response per offender: 'linked' | 'accepted-fix' | 'diverged'."),
10835
+ entryId: z25.string().max(200).optional().describe("Entry the acknowledgement links to."),
10836
+ reason: z25.string().max(2e3).optional().describe("Free-text justification, required for a 'diverged' response."),
10837
+ subjectEntryId: z25.string().max(200).optional().describe("The refused entry this acknowledgement answers.")
10828
10838
  });
10829
- var sessionSchema = z24.object({
10830
- action: z24.enum(SESSION_ACTIONS).describe(
10839
+ var sessionSchema = z25.object({
10840
+ action: z25.enum(SESSION_ACTIONS).describe(
10831
10841
  "'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)."
10832
10842
  ),
10833
- betEntryId: z24.string().max(200).optional().describe("For 'resume'/'commit-constellation': bet entry ID. Required for both."),
10834
- operationId: z24.string().max(200).optional().describe("For 'commit-constellation': optional idempotency key for retries."),
10835
- coherencyAcknowledgements: z24.array(coherencyAcknowledgementFlatSchema2).max(20).optional().describe(
10843
+ betEntryId: z25.string().max(200).optional().describe("For 'resume'/'commit-constellation': bet entry ID. Required for both."),
10844
+ operationId: z25.string().max(200).optional().describe("For 'commit-constellation': optional idempotency key for retries."),
10845
+ coherencyAcknowledgements: z25.array(coherencyAcknowledgementFlatSchema2).max(20).optional().describe(
10836
10846
  "For 'commit-constellation': per-offender acknowledgements to retry a constellation held under standard/strict coherency mode."
10837
10847
  ),
10838
- steeringOverrideReason: z24.string().max(2e3).optional().describe(
10848
+ steeringOverrideReason: z25.string().max(2e3).optional().describe(
10839
10849
  "For 'commit-constellation': typed override reason (>= 12 chars) to push past a coherency hold instead of acknowledging."
10840
10850
  ),
10841
10851
  // DEC-1715 (WP-753 O1a)
10842
- role: z24.string().max(200).optional().describe(
10852
+ role: z25.string().max(200).optional().describe(
10843
10853
  "For 'start': role to act as this session, by the '<PREFIX>-<n>' id a start reply prints beside the role name \u2014 only needed if you hold more than one; the error lists your roles if omitted."
10844
10854
  )
10845
10855
  });
10846
- var sessionStartVariant = z24.object({
10847
- action: z24.literal("start"),
10856
+ var sessionStartVariant = z25.object({
10857
+ action: z25.literal("start"),
10848
10858
  // DEC-1715 (WP-753 O1a): the role to act as this session — only needed when the person holds
10849
10859
  // more than one role; the server refuses and lists the choices when it's required and omitted.
10850
- role: z24.string().max(200).optional().describe(
10860
+ role: z25.string().max(200).optional().describe(
10851
10861
  "Role to act as this session, by the '<PREFIX>-<n>' id a start reply prints beside the role name \u2014 only needed if you hold more than one; the error lists your roles if omitted."
10852
10862
  )
10853
10863
  });
10854
- var sessionCloseVariant = z24.object({ action: z24.literal("close") });
10855
- var sessionStatusVariant = z24.object({ action: z24.literal("status") });
10856
- var sessionWrapupReviewVariant = z24.object({ action: z24.literal("wrapup-review") });
10857
- var sessionWrapupCommitVariant = z24.object({ action: z24.literal("wrapup-commit") });
10858
- var sessionResumeVariant = facilitateSchema.omit({ action: true }).extend({ action: z24.literal("resume") });
10859
- var sessionCommitConstellationVariant = facilitateSchema.omit({ action: true }).extend({ action: z24.literal("commit-constellation") });
10860
- var sessionActionUnion = z24.discriminatedUnion("action", [
10864
+ var sessionCloseVariant = z25.object({ action: z25.literal("close") });
10865
+ var sessionStatusVariant = z25.object({ action: z25.literal("status") });
10866
+ var sessionWrapupReviewVariant = z25.object({ action: z25.literal("wrapup-review") });
10867
+ var sessionWrapupCommitVariant = z25.object({ action: z25.literal("wrapup-commit") });
10868
+ var sessionResumeVariant = facilitateSchema.omit({ action: true }).extend({ action: z25.literal("resume") });
10869
+ var sessionCommitConstellationVariant = facilitateSchema.omit({ action: true }).extend({ action: z25.literal("commit-constellation") });
10870
+ var sessionActionUnion = z25.discriminatedUnion("action", [
10861
10871
  sessionStartVariant,
10862
10872
  sessionCloseVariant,
10863
10873
  sessionStatusVariant,
@@ -11111,10 +11121,10 @@ async function handleStatus() {
11111
11121
  }
11112
11122
 
11113
11123
  // src/tools/workspace.ts
11114
- import { z as z27 } from "zod/v3";
11124
+ import { z as z28 } from "zod/v3";
11115
11125
 
11116
11126
  // src/tools/health.ts
11117
- import { z as z25 } from "zod/v3";
11127
+ import { z as z26 } from "zod/v3";
11118
11128
 
11119
11129
  // src/lib/auditView.ts
11120
11130
  async function buildTenantAuditView(limit) {
@@ -11458,60 +11468,60 @@ ${logLines.join("\n")}${seamSummaryText}` }],
11458
11468
  };
11459
11469
  }
11460
11470
  var HEALTH_ACTIONS = ["check", "whoami", "status", "audit", "self-test"];
11461
- var healthSchema = z25.object({
11462
- action: z25.enum(HEALTH_ACTIONS).describe(
11471
+ var healthSchema = z26.object({
11472
+ action: z26.enum(HEALTH_ACTIONS).describe(
11463
11473
  "'check': connectivity and workspace stats. 'whoami': session identity. 'status': workspace readiness. 'audit': session audit log. 'self-test': validate all tool schemas."
11464
11474
  ),
11465
- limit: z25.number().min(1).max(50).default(20).optional().describe("For audit: how many recent calls to show (max 50)")
11475
+ limit: z26.number().min(1).max(50).default(20).optional().describe("For audit: how many recent calls to show (max 50)")
11466
11476
  });
11467
- var healthCheckOutputSchema = z25.object({
11468
- healthy: z25.boolean(),
11469
- collections: z25.number(),
11470
- entries: z25.number(),
11471
- latencyMs: z25.number(),
11472
- workspace: z25.string()
11477
+ var healthCheckOutputSchema = z26.object({
11478
+ healthy: z26.boolean(),
11479
+ collections: z26.number(),
11480
+ entries: z26.number(),
11481
+ latencyMs: z26.number(),
11482
+ workspace: z26.string()
11473
11483
  });
11474
- var organisationHealthSchema = z25.object({
11475
- reviewed: z25.number(),
11476
- agreements: z25.number(),
11477
- disagreements: z25.number(),
11478
- abstentions: z25.number(),
11479
- agreementRate: z25.number(),
11480
- flags: z25.array(z25.object({ collection: z25.string(), count: z25.number(), suggestedCollection: z25.string() }))
11484
+ var organisationHealthSchema = z26.object({
11485
+ reviewed: z26.number(),
11486
+ agreements: z26.number(),
11487
+ disagreements: z26.number(),
11488
+ abstentions: z26.number(),
11489
+ agreementRate: z26.number(),
11490
+ flags: z26.array(z26.object({ collection: z26.string(), count: z26.number(), suggestedCollection: z26.string() }))
11481
11491
  });
11482
- var healthStatusOutputSchema = z25.object({
11483
- sampleTruncated: z25.boolean().nullable().optional(),
11484
- activeEntries: z25.number(),
11485
- totalRelations: z25.number(),
11486
- orphanedEntries: z25.number(),
11487
- checks: z25.array(z25.object({ label: z25.string(), passed: z25.boolean(), current: z25.number(), required: z25.number() })),
11488
- gaps: z25.array(z25.object({ id: z25.string(), label: z25.string(), guidance: z25.string() })),
11492
+ var healthStatusOutputSchema = z26.object({
11493
+ sampleTruncated: z26.boolean().nullable().optional(),
11494
+ activeEntries: z26.number(),
11495
+ totalRelations: z26.number(),
11496
+ orphanedEntries: z26.number(),
11497
+ checks: z26.array(z26.object({ label: z26.string(), passed: z26.boolean(), current: z26.number(), required: z26.number() })),
11498
+ gaps: z26.array(z26.object({ id: z26.string(), label: z26.string(), guidance: z26.string() })),
11489
11499
  organisationHealth: organisationHealthSchema.optional()
11490
11500
  });
11491
- var healthAuditOutputSchema = z25.object({
11492
- totalCalls: z25.number(),
11493
- calls: z25.array(z25.object({
11494
- tool: z25.string(),
11495
- action: z25.string().optional(),
11496
- timestamp: z25.string(),
11497
- durationMs: z25.number().optional()
11501
+ var healthAuditOutputSchema = z26.object({
11502
+ totalCalls: z26.number(),
11503
+ calls: z26.array(z26.object({
11504
+ tool: z26.string(),
11505
+ action: z26.string().optional(),
11506
+ timestamp: z26.string(),
11507
+ durationMs: z26.number().optional()
11498
11508
  }))
11499
11509
  });
11500
- var healthWhoamiOutputSchema = z25.object({
11501
- workspaceId: z25.string(),
11502
- workspaceName: z25.string(),
11503
- scope: z25.string(),
11504
- sessionId: z25.union([z25.string(), z25.null()]),
11505
- oriented: z25.boolean()
11510
+ var healthWhoamiOutputSchema = z26.object({
11511
+ workspaceId: z26.string(),
11512
+ workspaceName: z26.string(),
11513
+ scope: z26.string(),
11514
+ sessionId: z26.union([z26.string(), z26.null()]),
11515
+ oriented: z26.boolean()
11506
11516
  });
11507
- var selfTestOutputSchema = z25.object({
11508
- passed: z25.number(),
11509
- failed: z25.number(),
11510
- total: z25.number(),
11511
- results: z25.array(z25.object({
11512
- tool: z25.string(),
11513
- valid: z25.boolean(),
11514
- error: z25.string().optional()
11517
+ var selfTestOutputSchema = z26.object({
11518
+ passed: z26.number(),
11519
+ failed: z26.number(),
11520
+ total: z26.number(),
11521
+ results: z26.array(z26.object({
11522
+ tool: z26.string(),
11523
+ valid: z26.boolean(),
11524
+ error: z26.string().optional()
11515
11525
  }))
11516
11526
  });
11517
11527
  function handleSelfTest(server) {
@@ -11562,9 +11572,9 @@ function handleSelfTest(server) {
11562
11572
  }
11563
11573
 
11564
11574
  // src/tools/usage.ts
11565
- import { z as z26 } from "zod/v3";
11566
- var usageSummarySchema = z26.object({
11567
- periodDays: z26.number().min(1).max(90).optional().describe("Number of days to look back (default 30, max 90)")
11575
+ import { z as z27 } from "zod/v3";
11576
+ var usageSummarySchema = z27.object({
11577
+ periodDays: z27.number().min(1).max(90).optional().describe("Number of days to look back (default 30, max 90)")
11568
11578
  });
11569
11579
  async function handleUsageSummary(periodDays) {
11570
11580
  const ws = await getWorkspaceContext();
@@ -11634,20 +11644,20 @@ var WORKSPACE_ACTIONS = [
11634
11644
  "self-test",
11635
11645
  "usage"
11636
11646
  ];
11637
- var workspaceSchema = z27.object({
11638
- action: z27.enum(WORKSPACE_ACTIONS).describe(
11647
+ var workspaceSchema = z28.object({
11648
+ action: z28.enum(WORKSPACE_ACTIONS).describe(
11639
11649
  "'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)."
11640
11650
  ),
11641
- limit: z27.number().min(1).max(50).optional().describe("For 'audit': how many recent calls to show (max 50, default 20)."),
11642
- periodDays: z27.number().min(1).max(90).optional().describe("For 'usage': number of days to look back (default 30, max 90).")
11651
+ limit: z28.number().min(1).max(50).optional().describe("For 'audit': how many recent calls to show (max 50, default 20)."),
11652
+ periodDays: z28.number().min(1).max(90).optional().describe("For 'usage': number of days to look back (default 30, max 90).")
11643
11653
  });
11644
- var workspaceCheckVariant = z27.object({ action: z27.literal("check") });
11645
- var workspaceWhoamiVariant = z27.object({ action: z27.literal("whoami") });
11646
- var workspaceStatusVariant = z27.object({ action: z27.literal("status") });
11647
- var workspaceAuditVariant = z27.object({ action: z27.literal("audit"), limit: z27.number().min(1).max(50).optional().default(20) });
11648
- var workspaceSelfTestVariant = z27.object({ action: z27.literal("self-test") });
11649
- var workspaceUsageVariant = z27.object({ action: z27.literal("usage"), periodDays: z27.number().min(1).max(90).optional() });
11650
- var workspaceActionUnion = z27.discriminatedUnion("action", [
11654
+ var workspaceCheckVariant = z28.object({ action: z28.literal("check") });
11655
+ var workspaceWhoamiVariant = z28.object({ action: z28.literal("whoami") });
11656
+ var workspaceStatusVariant = z28.object({ action: z28.literal("status") });
11657
+ var workspaceAuditVariant = z28.object({ action: z28.literal("audit"), limit: z28.number().min(1).max(50).optional().default(20) });
11658
+ var workspaceSelfTestVariant = z28.object({ action: z28.literal("self-test") });
11659
+ var workspaceUsageVariant = z28.object({ action: z28.literal("usage"), periodDays: z28.number().min(1).max(90).optional() });
11660
+ var workspaceActionUnion = z28.discriminatedUnion("action", [
11651
11661
  workspaceCheckVariant,
11652
11662
  workspaceWhoamiVariant,
11653
11663
  workspaceStatusVariant,
@@ -11693,7 +11703,7 @@ function registerWorkspaceTools(server) {
11693
11703
  }
11694
11704
 
11695
11705
  // src/tools/feedback.ts
11696
- import { z as z28 } from "zod/v3";
11706
+ import { z as z29 } from "zod/v3";
11697
11707
 
11698
11708
  // src/lib/productFeedbackConstants.ts
11699
11709
  var PRODUCT_FEEDBACK_CATEGORIES = ["bug", "friction", "idea", "praise", "other"];
@@ -11704,37 +11714,37 @@ var VENDOR_SETTABLE_STATUSES = PRODUCT_FEEDBACK_STATUSES.filter(
11704
11714
 
11705
11715
  // src/tools/feedback.ts
11706
11716
  var actions = ["submit", "list", "queue", "note", "group", "status"];
11707
- var category = z28.enum(PRODUCT_FEEDBACK_CATEGORIES);
11708
- var status = z28.enum(PRODUCT_FEEDBACK_STATUSES);
11709
- var vendorStatus = z28.enum(VENDOR_SETTABLE_STATUSES);
11717
+ var category = z29.enum(PRODUCT_FEEDBACK_CATEGORIES);
11718
+ var status = z29.enum(PRODUCT_FEEDBACK_STATUSES);
11719
+ var vendorStatus = z29.enum(VENDOR_SETTABLE_STATUSES);
11710
11720
  var MESSAGE_DISPLAY_LIMIT = 1e3;
11711
11721
  var FULL_MESSAGE_MAX_LIMIT = 5;
11712
- var feedbackSchema = z28.object({
11713
- action: z28.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."),
11714
- message: z28.string().max(1e4).optional().describe("Required for submit: the product feedback text (max 10,000 characters)."),
11722
+ var feedbackSchema = z29.object({
11723
+ action: z29.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."),
11724
+ message: z29.string().max(1e4).optional().describe("Required for submit: the product feedback text (max 10,000 characters)."),
11715
11725
  category: category.optional().describe("Submit/queue category; submit defaults to other."),
11716
- command: z28.string().max(1e3).optional().describe("Optional submit command context; argument values are scrubbed server-side."),
11717
- route: z28.string().max(500).optional().describe("Optional submit route context."),
11718
- client: z28.string().max(100).optional().describe("Optional submit client label."),
11719
- feedbackId: z28.string().max(200).optional().describe("Required for note/status: target feedback ID."),
11720
- feedbackIds: z28.array(z28.string().max(200)).max(100).optional().describe("Required for group: 1\u2013100 target feedback IDs."),
11721
- note: z28.string().max(4e3).optional().describe("Required for note: replacement triage note (max 4,000 characters)."),
11726
+ command: z29.string().max(1e3).optional().describe("Optional submit command context; argument values are scrubbed server-side."),
11727
+ route: z29.string().max(500).optional().describe("Optional submit route context."),
11728
+ client: z29.string().max(100).optional().describe("Optional submit client label."),
11729
+ feedbackId: z29.string().max(200).optional().describe("Required for note/status: target feedback ID."),
11730
+ feedbackIds: z29.array(z29.string().max(200)).max(100).optional().describe("Required for group: 1\u2013100 target feedback IDs."),
11731
+ note: z29.string().max(4e3).optional().describe("Required for note: replacement triage note (max 4,000 characters)."),
11722
11732
  status: status.optional().describe("list/queue filter (any status, including 'screening'); the status action's required target value excludes 'screening' (system-only)."),
11723
- groupId: z28.string().min(1).max(200).nullable().optional().describe("Group filter, or required group destination; null explicitly clears grouping."),
11724
- workspaceId: z28.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."),
11725
- since: z28.number().optional().describe("Queue-only lower createdAt window bound (inclusive) in epoch milliseconds."),
11726
- before: z28.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."),
11727
- limit: z28.number().int().min(1).max(100).optional().describe("list/queue row limit, default 50, maximum 100."),
11728
- cursor: z28.string().max(2e3).optional().describe("Opaque pagination cursor from a previous list/queue response (continueCursor); omit for the first page."),
11729
- full: z28.boolean().optional().describe(`list/queue only: return untruncated messages; allowed only when limit <= ${FULL_MESSAGE_MAX_LIMIT}.`)
11733
+ groupId: z29.string().min(1).max(200).nullable().optional().describe("Group filter, or required group destination; null explicitly clears grouping."),
11734
+ workspaceId: z29.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."),
11735
+ since: z29.number().optional().describe("Queue-only lower createdAt window bound (inclusive) in epoch milliseconds."),
11736
+ before: z29.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."),
11737
+ limit: z29.number().int().min(1).max(100).optional().describe("list/queue row limit, default 50, maximum 100."),
11738
+ cursor: z29.string().max(2e3).optional().describe("Opaque pagination cursor from a previous list/queue response (continueCursor); omit for the first page."),
11739
+ full: z29.boolean().optional().describe(`list/queue only: return untruncated messages; allowed only when limit <= ${FULL_MESSAGE_MAX_LIMIT}.`)
11730
11740
  });
11731
- var union = z28.discriminatedUnion("action", [
11732
- z28.object({ action: z28.literal("submit"), message: z28.string().min(1).max(1e4), category: category.optional(), command: z28.string().max(1e3).optional(), route: z28.string().max(500).optional(), client: z28.string().max(100).optional() }),
11733
- z28.object({ action: z28.literal("list"), status: status.optional(), limit: z28.number().int().min(1).max(100).optional(), cursor: z28.string().max(2e3).optional(), full: z28.boolean().optional() }),
11734
- z28.object({ action: z28.literal("queue"), status: status.optional(), category: category.optional(), groupId: z28.string().min(1).max(200).optional(), workspaceId: z28.string().max(200).optional(), since: z28.number().optional(), before: z28.number().optional(), limit: z28.number().int().min(1).max(100).optional(), cursor: z28.string().max(2e3).optional(), full: z28.boolean().optional() }),
11735
- z28.object({ action: z28.literal("note"), feedbackId: z28.string().min(1).max(200), note: z28.string().max(4e3) }),
11736
- z28.object({ action: z28.literal("group"), feedbackIds: z28.array(z28.string().min(1).max(200)).min(1).max(100), groupId: z28.string().min(1).max(200).nullable() }),
11737
- z28.object({ action: z28.literal("status"), feedbackId: z28.string().min(1).max(200), status: vendorStatus })
11741
+ var union = z29.discriminatedUnion("action", [
11742
+ z29.object({ action: z29.literal("submit"), message: z29.string().min(1).max(1e4), category: category.optional(), command: z29.string().max(1e3).optional(), route: z29.string().max(500).optional(), client: z29.string().max(100).optional() }),
11743
+ z29.object({ action: z29.literal("list"), status: status.optional(), limit: z29.number().int().min(1).max(100).optional(), cursor: z29.string().max(2e3).optional(), full: z29.boolean().optional() }),
11744
+ z29.object({ action: z29.literal("queue"), status: status.optional(), category: category.optional(), groupId: z29.string().min(1).max(200).optional(), workspaceId: z29.string().max(200).optional(), since: z29.number().optional(), before: z29.number().optional(), limit: z29.number().int().min(1).max(100).optional(), cursor: z29.string().max(2e3).optional(), full: z29.boolean().optional() }),
11745
+ z29.object({ action: z29.literal("note"), feedbackId: z29.string().min(1).max(200), note: z29.string().max(4e3) }),
11746
+ z29.object({ action: z29.literal("group"), feedbackIds: z29.array(z29.string().min(1).max(200)).min(1).max(100), groupId: z29.string().min(1).max(200).nullable() }),
11747
+ z29.object({ action: z29.literal("status"), feedbackId: z29.string().min(1).max(200), status: vendorStatus })
11738
11748
  ]);
11739
11749
  var specs = {
11740
11750
  submit: { params: ["message", "category", "command", "route", "client"], description: "message is required; category defaults to other." },
@@ -11861,34 +11871,34 @@ function registerFeedbackTool(server) {
11861
11871
  }
11862
11872
 
11863
11873
  // src/tools/shape.ts
11864
- import { z as z29 } from "zod/v3";
11874
+ import { z as z30 } from "zod/v3";
11865
11875
  var SHAPE_ACTIONS = ["list", "show", "agree", "dismiss"];
11866
11876
  var LIST_DISPOSITIONS = ["pending", "agreed", "dismissed", "expired"];
11867
11877
  var LIST_OUTCOMES = ["not_candidate", "atomic", "compound", "unavailable"];
11868
- var shapeSchema = z29.object({
11869
- action: z29.enum(SHAPE_ACTIONS).describe(
11878
+ var shapeSchema = z30.object({
11879
+ action: z30.enum(SHAPE_ACTIONS).describe(
11870
11880
  "'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."
11871
11881
  ),
11872
- disposition: z29.enum(LIST_DISPOSITIONS).optional().describe(
11882
+ disposition: z30.enum(LIST_DISPOSITIONS).optional().describe(
11873
11883
  "For 'list': filter by disposition. Omitting both disposition and outcome defaults to the actionable set (disposition:pending, outcome:compound)."
11874
11884
  ),
11875
- outcome: z29.enum(LIST_OUTCOMES).optional().describe(
11885
+ outcome: z30.enum(LIST_OUTCOMES).optional().describe(
11876
11886
  "For 'list': filter by outcome. Omitting both disposition and outcome defaults to the actionable set (disposition:pending, outcome:compound)."
11877
11887
  ),
11878
- limit: z29.number().min(1).max(200).optional().describe("For 'list': max rows (default 50, max 200)."),
11879
- rowId: z29.string().max(200).optional().describe("For 'show'/'agree'/'dismiss': the advisory row id."),
11880
- reason: z29.string().max(1e3).optional().describe("For 'agree'/'dismiss': optional reason (capped at 1000 chars).")
11888
+ limit: z30.number().min(1).max(200).optional().describe("For 'list': max rows (default 50, max 200)."),
11889
+ rowId: z30.string().max(200).optional().describe("For 'show'/'agree'/'dismiss': the advisory row id."),
11890
+ reason: z30.string().max(1e3).optional().describe("For 'agree'/'dismiss': optional reason (capped at 1000 chars).")
11881
11891
  });
11882
- var shapeListVariant = z29.object({
11883
- action: z29.literal("list"),
11884
- disposition: z29.enum(LIST_DISPOSITIONS).optional(),
11885
- outcome: z29.enum(LIST_OUTCOMES).optional(),
11886
- limit: z29.number().min(1).max(200).optional()
11892
+ var shapeListVariant = z30.object({
11893
+ action: z30.literal("list"),
11894
+ disposition: z30.enum(LIST_DISPOSITIONS).optional(),
11895
+ outcome: z30.enum(LIST_OUTCOMES).optional(),
11896
+ limit: z30.number().min(1).max(200).optional()
11887
11897
  });
11888
- var shapeShowVariant = z29.object({ action: z29.literal("show"), rowId: z29.string().max(200) });
11889
- var shapeAgreeVariant = z29.object({ action: z29.literal("agree"), rowId: z29.string().max(200), reason: z29.string().max(1e3).optional() });
11890
- var shapeDismissVariant = z29.object({ action: z29.literal("dismiss"), rowId: z29.string().max(200), reason: z29.string().max(1e3).optional() });
11891
- var shapeActionUnion = z29.discriminatedUnion("action", [
11898
+ var shapeShowVariant = z30.object({ action: z30.literal("show"), rowId: z30.string().max(200) });
11899
+ var shapeAgreeVariant = z30.object({ action: z30.literal("agree"), rowId: z30.string().max(200), reason: z30.string().max(1e3).optional() });
11900
+ var shapeDismissVariant = z30.object({ action: z30.literal("dismiss"), rowId: z30.string().max(200), reason: z30.string().max(1e3).optional() });
11901
+ var shapeActionUnion = z30.discriminatedUnion("action", [
11892
11902
  shapeListVariant,
11893
11903
  shapeShowVariant,
11894
11904
  shapeAgreeVariant,
@@ -12034,26 +12044,26 @@ function registerShapeTools(server) {
12034
12044
  }
12035
12045
 
12036
12046
  // src/tools/question.ts
12037
- import { z as z30 } from "zod/v3";
12047
+ import { z as z31 } from "zod/v3";
12038
12048
  var QUESTION_ACTIONS = ["create", "assign", "answer", "force-close", "list"];
12039
- var questionSchema = z30.object({
12040
- action: z30.enum(QUESTION_ACTIONS).describe(
12049
+ var questionSchema = z31.object({
12050
+ action: z31.enum(QUESTION_ACTIONS).describe(
12041
12051
  "'create': create a new routed question from text \u2014 the dedicated birth action; every question is born escalated to the team lead (generic entry creation and move-and-retype also pair a routing facet). 'assign': reassign ownership to a role (toRole required \u2014 no bare self-confirm, no toPerson). 'answer': close the loop \u2014 writes the answer on the question and moves it to answered; --entry links an existing decision instead. 'force-close': Team-Lead-only escape hatch \u2014 reason required. 'list': the ack-gate read model \u2014 what you owe (or, with mine:true, every question you asked, including closed ones)."
12042
12052
  ),
12043
- entryId: z30.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'."),
12044
- text: z30.string().max(5e3).optional().describe("'create': the question text. 'answer': the answer text (mutually exclusive with answerEntryId, max 2000 chars)."),
12045
- blocks: z30.array(z30.string().max(200)).max(50).optional().describe("'create': entry ids this question is blocking (repeatable)."),
12046
- toRole: z30.string().max(200).optional().describe("'assign': reassign to this role (human ROL-nnn form or a raw entry id) \u2014 required."),
12047
- reason: z30.string().max(2e3).optional().describe("'force-close': required reason."),
12048
- answerEntryId: z30.string().max(200).optional().describe("'answer': point at an already-written entry instead of supplying text (mutually exclusive with text)."),
12049
- mine: z30.boolean().optional().describe("'list': true for arm C (every question YOU asked, every status). Omit/false for the ack-gate view (what you owe).")
12053
+ entryId: z31.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'."),
12054
+ text: z31.string().max(5e3).optional().describe("'create': the question text. 'answer': the answer text (mutually exclusive with answerEntryId, max 2000 chars)."),
12055
+ blocks: z31.array(z31.string().max(200)).max(50).optional().describe("'create': entry ids this question is blocking (repeatable)."),
12056
+ toRole: z31.string().max(200).optional().describe("'assign': reassign to this role (human ROL-nnn form or a raw entry id) \u2014 required."),
12057
+ reason: z31.string().max(2e3).optional().describe("'force-close': required reason."),
12058
+ answerEntryId: z31.string().max(200).optional().describe("'answer': point at an already-written entry instead of supplying text (mutually exclusive with text)."),
12059
+ mine: z31.boolean().optional().describe("'list': true for arm C (every question YOU asked, every status). Omit/false for the ack-gate view (what you owe).")
12050
12060
  });
12051
- var createVariant = z30.object({ action: z30.literal("create"), text: z30.string().min(1).max(5e3), blocks: z30.array(z30.string().max(200)).max(50).optional() });
12052
- var assignVariant = z30.object({ action: z30.literal("assign"), entryId: z30.string().max(200), toRole: z30.string().max(200).min(1) });
12053
- var answerVariant = z30.object({ action: z30.literal("answer"), entryId: z30.string().max(200), text: z30.string().max(2e3).optional(), answerEntryId: z30.string().max(200).optional() });
12054
- var forceCloseVariant = z30.object({ action: z30.literal("force-close"), entryId: z30.string().max(200), reason: z30.string().min(1).max(2e3) });
12055
- var listVariant = z30.object({ action: z30.literal("list"), mine: z30.boolean().optional() });
12056
- var questionActionUnion = z30.discriminatedUnion("action", [
12061
+ var createVariant = z31.object({ action: z31.literal("create"), text: z31.string().min(1).max(5e3), blocks: z31.array(z31.string().max(200)).max(50).optional() });
12062
+ var assignVariant = z31.object({ action: z31.literal("assign"), entryId: z31.string().max(200), toRole: z31.string().max(200).min(1) });
12063
+ var answerVariant = z31.object({ action: z31.literal("answer"), entryId: z31.string().max(200), text: z31.string().max(2e3).optional(), answerEntryId: z31.string().max(200).optional() });
12064
+ var forceCloseVariant = z31.object({ action: z31.literal("force-close"), entryId: z31.string().max(200), reason: z31.string().min(1).max(2e3) });
12065
+ var listVariant = z31.object({ action: z31.literal("list"), mine: z31.boolean().optional() });
12066
+ var questionActionUnion = z31.discriminatedUnion("action", [
12057
12067
  createVariant,
12058
12068
  assignVariant,
12059
12069
  answerVariant,
@@ -12207,7 +12217,7 @@ function registerQuestionTools(server) {
12207
12217
  }
12208
12218
 
12209
12219
  // src/tools/role.ts
12210
- import { z as z31 } from "zod/v3";
12220
+ import { z as z32 } from "zod/v3";
12211
12221
 
12212
12222
  // src/lib/seatSentence.ts
12213
12223
  function formatSeatSentence(action, reply, clean) {
@@ -12230,52 +12240,52 @@ function formatInviteSentence(reply, clean) {
12230
12240
 
12231
12241
  // src/tools/role.ts
12232
12242
  var ROLE_ACTIONS = ["accountable", "seat", "unseat", "invite"];
12233
- var roleSchema = z31.object({
12234
- action: z31.enum(ROLE_ACTIONS).describe(
12243
+ var roleSchema = z32.object({
12244
+ action: z32.enum(ROLE_ACTIONS).describe(
12235
12245
  "'accountable': what this role owns (explicit), reports on (reporting), and \u2014 not yet computed \u2014 inherits via Team-Lead vacancy coverage. 'seat': put a person in this role. 'unseat': take this role from a person. 'invite': send a login link by email; a placeholder person (seated by name) is invited in place and keeps every role it holds."
12236
12246
  ),
12237
- roleId: z31.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 every action except 'invite'."),
12238
- canonicalKey: z31.string().max(200).optional().describe("'accountable': narrow to one kind (e.g. objective, key_result, tension)."),
12239
- limit: z31.number().int().positive().max(200).optional().describe("'accountable': max explicit-list rows per page (default and maximum 200)."),
12240
- cursor: z31.number().optional().describe("'accountable': continue the explicit list from an earlier truncated page's nextCursor."),
12241
- person: z31.string().max(200).optional().describe(
12247
+ roleId: z32.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 every action except 'invite'."),
12248
+ canonicalKey: z32.string().max(200).optional().describe("'accountable': narrow to one kind (e.g. objective, key_result, tension)."),
12249
+ limit: z32.number().int().positive().max(200).optional().describe("'accountable': max explicit-list rows per page (default and maximum 200)."),
12250
+ cursor: z32.number().optional().describe("'accountable': continue the explicit list from an earlier truncated page's nextCursor."),
12251
+ person: z32.string().max(200).optional().describe(
12242
12252
  "'seat' / 'unseat': an existing person, by person id or exact email. For 'seat', give this or newPersonName, not both. 'invite': the placeholder's person id."
12243
12253
  ),
12244
- newPersonName: z31.string().max(120).optional().describe(
12254
+ newPersonName: z32.string().max(120).optional().describe(
12245
12255
  "'seat': the name of a person who has no login yet; a placeholder person is created once and reused for the same exact name. Refused when the name belongs to someone with an account. 'invite': the name of a new person to invite, instead of person."
12246
12256
  ),
12247
- email: z31.string().max(320).optional().describe("'invite': where the login link goes. Required for 'invite'."),
12248
- teamId: z31.string().max(200).optional().describe(
12257
+ email: z32.string().max(320).optional().describe("'invite': where the login link goes. Required for 'invite'."),
12258
+ teamId: z32.string().max(200).optional().describe(
12249
12259
  "'seat' / 'unseat': the team, by chain id or entry id. Only needed for Team Lead, which lives in every team; any other role is seated in its home team."
12250
12260
  )
12251
12261
  });
12252
- var accountableVariant = z31.object({
12253
- action: z31.literal("accountable"),
12254
- roleId: z31.string().max(200),
12255
- canonicalKey: z31.string().max(200).optional(),
12256
- limit: z31.number().int().positive().max(200).optional(),
12257
- cursor: z31.number().optional()
12262
+ var accountableVariant = z32.object({
12263
+ action: z32.literal("accountable"),
12264
+ roleId: z32.string().max(200),
12265
+ canonicalKey: z32.string().max(200).optional(),
12266
+ limit: z32.number().int().positive().max(200).optional(),
12267
+ cursor: z32.number().optional()
12258
12268
  });
12259
- var seatVariant = z31.object({
12260
- action: z31.literal("seat"),
12261
- roleId: z31.string().max(200),
12262
- person: z31.string().max(200).optional(),
12263
- newPersonName: z31.string().max(120).optional(),
12264
- teamId: z31.string().max(200).optional()
12269
+ var seatVariant = z32.object({
12270
+ action: z32.literal("seat"),
12271
+ roleId: z32.string().max(200),
12272
+ person: z32.string().max(200).optional(),
12273
+ newPersonName: z32.string().max(120).optional(),
12274
+ teamId: z32.string().max(200).optional()
12265
12275
  });
12266
- var unseatVariant = z31.object({
12267
- action: z31.literal("unseat"),
12268
- roleId: z31.string().max(200),
12269
- person: z31.string().max(200),
12270
- teamId: z31.string().max(200).optional()
12276
+ var unseatVariant = z32.object({
12277
+ action: z32.literal("unseat"),
12278
+ roleId: z32.string().max(200),
12279
+ person: z32.string().max(200),
12280
+ teamId: z32.string().max(200).optional()
12271
12281
  });
12272
- var inviteVariant = z31.object({
12273
- action: z31.literal("invite"),
12274
- email: z31.string().max(320),
12275
- person: z31.string().max(200).optional(),
12276
- newPersonName: z31.string().max(120).optional()
12282
+ var inviteVariant = z32.object({
12283
+ action: z32.literal("invite"),
12284
+ email: z32.string().max(320),
12285
+ person: z32.string().max(200).optional(),
12286
+ newPersonName: z32.string().max(120).optional()
12277
12287
  });
12278
- var roleActionUnion = z31.discriminatedUnion("action", [accountableVariant, seatVariant, unseatVariant, inviteVariant]);
12288
+ var roleActionUnion = z32.discriminatedUnion("action", [accountableVariant, seatVariant, unseatVariant, inviteVariant]);
12279
12289
  var ROLE_ACTION_SPECS = {
12280
12290
  accountable: { params: ["roleId", "canonicalKey", "limit", "cursor"], description: "roleId is required; canonicalKey/limit/cursor are optional." },
12281
12291
  seat: { params: ["roleId", "person", "newPersonName", "teamId"], description: "roleId is required, plus exactly one of person or newPersonName; teamId only for Team Lead." },
@@ -12420,49 +12430,49 @@ function registerRoleTools(server) {
12420
12430
  }
12421
12431
 
12422
12432
  // src/tools/outcome.ts
12423
- import { z as z32 } from "zod/v3";
12433
+ import { z as z33 } from "zod/v3";
12424
12434
  var OUTCOME_ACTIONS = ["record", "list", "show"];
12425
12435
  var READING_KINDS = ["measurement", "estimate", "correction"];
12426
- var outcomeSchema = z32.object({
12427
- action: z32.enum(OUTCOME_ACTIONS).describe(
12436
+ var outcomeSchema = z33.object({
12437
+ action: z33.enum(OUTCOME_ACTIONS).describe(
12428
12438
  "'record': record a reading (evidence, not a verdict). 'list': list readings, newest first. 'show': the derived view \u2014 current, progress, pace, staleness, recorded completion."
12429
12439
  ),
12430
- entryId: z32.string().max(200).optional().describe("The key result (or other outcome-bearing) entry, by its chain id. Required for all three actions."),
12440
+ entryId: z33.string().max(200).optional().describe("The key result (or other outcome-bearing) entry, by its chain id. Required for all three actions."),
12431
12441
  // PR #858 review round 3 (Codex P2, PRRT_kwDORS4ils6gXHj9): a JSON number that overflows to
12432
12442
  // `Infinity` (e.g. `1e400`) parses fine in JS and passes a plain `z.number()`, but
12433
12443
  // `callGateway()` serializes it with `JSON.stringify`, which turns `Infinity` into `null` —
12434
12444
  // the backend's `v.number()` validator then rejects a call this tool's own schema accepted.
12435
12445
  // `.finite()` rejects it here, matching the explicit finite-value checks the CLI/other outcome
12436
12446
  // entry surfaces already use.
12437
- value: z32.number().finite().optional().describe("'record': the measured value. Required for 'record'."),
12438
- valueText: z32.string().max(500).optional().describe("'record': verbatim as-reported form when the source was not clean, e.g. '~62%'. Display only."),
12439
- asOf: z32.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."),
12440
- kind: z32.enum(READING_KINDS).optional().describe("'record': measurement | estimate | correction (default: measurement)."),
12441
- correctsReadingId: z32.string().max(200).optional().describe("'record': required with kind='correction' \u2014 the reading id this replaces. Refused if that row is already superseded."),
12442
- recordedByRoleId: z32.string().max(200).optional().describe("'record': the accountable role (default: the entry's reporterRoleId, then its owning role)."),
12443
- note: z32.string().max(2e3).optional().describe("'record': free-text note recorded with the reading."),
12444
- source: z32.string().max(500).optional().describe("'record': where the number came from \u2014 a dashboard name, a query, a URL."),
12445
- limit: z32.number().int().positive().max(200).optional().describe("'list': max rows to return (default and maximum 200).")
12447
+ value: z33.number().finite().optional().describe("'record': the measured value. Required for 'record'."),
12448
+ valueText: z33.string().max(500).optional().describe("'record': verbatim as-reported form when the source was not clean, e.g. '~62%'. Display only."),
12449
+ asOf: z33.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."),
12450
+ kind: z33.enum(READING_KINDS).optional().describe("'record': measurement | estimate | correction (default: measurement)."),
12451
+ correctsReadingId: z33.string().max(200).optional().describe("'record': required with kind='correction' \u2014 the reading id this replaces. Refused if that row is already superseded."),
12452
+ recordedByRoleId: z33.string().max(200).optional().describe("'record': the accountable role (default: the entry's reporterRoleId, then its owning role)."),
12453
+ note: z33.string().max(2e3).optional().describe("'record': free-text note recorded with the reading."),
12454
+ source: z33.string().max(500).optional().describe("'record': where the number came from \u2014 a dashboard name, a query, a URL."),
12455
+ limit: z33.number().int().positive().max(200).optional().describe("'list': max rows to return (default and maximum 200).")
12446
12456
  });
12447
- var recordVariant = z32.object({
12448
- action: z32.literal("record"),
12449
- entryId: z32.string().max(200),
12450
- value: z32.number().finite(),
12451
- valueText: z32.string().max(500).optional(),
12452
- asOf: z32.string().max(64).optional(),
12453
- kind: z32.enum(READING_KINDS).optional(),
12454
- correctsReadingId: z32.string().max(200).optional(),
12455
- recordedByRoleId: z32.string().max(200).optional(),
12456
- note: z32.string().max(2e3).optional(),
12457
- source: z32.string().max(500).optional()
12457
+ var recordVariant = z33.object({
12458
+ action: z33.literal("record"),
12459
+ entryId: z33.string().max(200),
12460
+ value: z33.number().finite(),
12461
+ valueText: z33.string().max(500).optional(),
12462
+ asOf: z33.string().max(64).optional(),
12463
+ kind: z33.enum(READING_KINDS).optional(),
12464
+ correctsReadingId: z33.string().max(200).optional(),
12465
+ recordedByRoleId: z33.string().max(200).optional(),
12466
+ note: z33.string().max(2e3).optional(),
12467
+ source: z33.string().max(500).optional()
12458
12468
  });
12459
- var listVariant2 = z32.object({
12460
- action: z32.literal("list"),
12461
- entryId: z32.string().max(200),
12462
- limit: z32.number().int().positive().max(200).optional()
12469
+ var listVariant2 = z33.object({
12470
+ action: z33.literal("list"),
12471
+ entryId: z33.string().max(200),
12472
+ limit: z33.number().int().positive().max(200).optional()
12463
12473
  });
12464
- var showVariant = z32.object({ action: z32.literal("show"), entryId: z32.string().max(200) });
12465
- var outcomeActionUnion = z32.discriminatedUnion("action", [recordVariant, listVariant2, showVariant]);
12474
+ var showVariant = z33.object({ action: z33.literal("show"), entryId: z33.string().max(200) });
12475
+ var outcomeActionUnion = z33.discriminatedUnion("action", [recordVariant, listVariant2, showVariant]);
12466
12476
  var OUTCOME_ACTION_SPECS = {
12467
12477
  record: {
12468
12478
  params: ["entryId", "value", "valueText", "asOf", "kind", "correctsReadingId", "recordedByRoleId", "note", "source"],
@@ -12751,9 +12761,9 @@ var AGENT_CHEATSHEET = `# Product Brain \u2014 Agent Cheatsheet
12751
12761
  |---|---|---|
12752
12762
  | \`orient\` | Workspace context, governance, active work packages, session start | \`action\`: start, task |
12753
12763
  | \`capture\` | Create entry | \`action\`: capture |
12754
- | \`entries\` | Read and write entries | \`action\`: list, get, batch, search, update, commit, history, move, verify, preflight, still-true |
12764
+ | \`entries\` | Find and write entries | \`action\`: list, batch, search, update, commit, history, move, verify, preflight, still-true |
12755
12765
  | \`relations\` | Link entries, delete links, find connections | \`action\`: create, batch-create, delete, find |
12756
- | \`context\` | Gather related knowledge, last-verified brief | \`action\`: gather, build, neighborhood, changes, chain, cross-cut, incremental, brief, last-verified-brief |
12766
+ | \`context\` | Look-ups; incremental also records a brief run | \`action\`: get, gather, build, neighborhood, changes, chain, cross-cut, incremental, brief, last-verified-brief |
12757
12767
  | \`collections\` | Browse, describe, audit and export collections; manage labels | \`action\`: list, update, describe, audit, export, label-* |
12758
12768
  | \`quality\` | Score an entry, verify the Chain, spine check | \`action\`: check, re-evaluate, verify-chain, spine-check |
12759
12769
  | \`session\` | Start / close, wrapup, resume, constellation accept | \`action\`: start, close, status, wrapup-review, wrapup-commit, resume, commit-constellation |
@@ -12820,7 +12830,7 @@ Unified entries model: collections define field schemas, entries hold data in a
12820
12830
  The \`data\` field is polymorphic: plain fields for generic entries, \`ChainData\` (chainTypeId + links) for processes.
12821
12831
  Tags for filtering (e.g. \`severity:high\`), relations via \`entryRelations\`, versions via \`entryVersions\`, labels via \`labels\` + \`entryLabels\`.
12822
12832
 
12823
- ` + collList + "\n\nUse `collections action=list` for field schemas, `entries action=get` for full records."
12833
+ ` + collList + "\n\nUse `collections action=list` for field schemas, `context action=get` for full records."
12824
12834
  );
12825
12835
  } else {
12826
12836
  sections.push(
@@ -12828,7 +12838,7 @@ Tags for filtering (e.g. \`severity:high\`), relations via \`entryRelations\`, v
12828
12838
  );
12829
12839
  }
12830
12840
  sections.push(
12831
- '## Rules\nThe rules that bind you are in the briefing above, each with its why. A rule on no list binds nobody.\nOpen one: `entries action=get entryId="<ID>"`. Find one: `entries action=search query="<noun>"`.\nDraft a new rule: use the `draft-rule-from-context` prompt.'
12841
+ '## Rules\nThe rules that bind you are in the briefing above, each with its why. A rule on no list binds nobody.\nOpen one: `context action=get entryId="<ID>"`. Find one: `entries action=search query="<noun>"`.\nDraft a new rule: use the `draft-rule-from-context` prompt.'
12832
12842
  );
12833
12843
  sections.push(
12834
12844
  "## Knowledge Graph\nEntries are connected via typed relations (`entryRelations` table). Relations are bidirectional and collection-agnostic \u2014 any entry can link to any other entry.\n\n**Recommended relation types** (extensible \u2014 any string accepted):\n- `governs` \u2014 a rule constrains behavior of a feature\n- `defines_term_for` \u2014 a glossary term is canonical vocabulary for a feature/area\n- `belongs_to` \u2014 a feature belongs to a product area or parent concept (typed successor: `anchored_to`)\n- `informs` \u2014 a decision or insight informs a feature\n- `surfaces_tension_in` \u2014 a tension exists within a feature area\n- `related_to`, `depends_on`, `replaces`, `conflicts_with`, `references`, `confused_with`\n\nEach relation type is defined as a glossary entry (prefix `GT-REL-*`) to prevent terminology drift.\n\n**Tools:**\n- `context action=gather` \u2014 get the full context around any entry (multi-hop graph traversal)\n- `relations action=create` \u2014 create a typed link between two entries\n- `relations action=find` \u2014 list direct relations for an entry\n\n**Convention:** A relation is written only when you ask for it, with exactly the verb you send \u2014 link the entries you know are related with `relations action=create`."
@@ -13231,7 +13241,7 @@ ${entry.labels.map((l) => `- ${l.name ?? l.slug}`).join("\n")}`);
13231
13241
  }
13232
13242
 
13233
13243
  // src/prompts/index.ts
13234
- import { z as z33 } from "zod/v3";
13244
+ import { z as z34 } from "zod/v3";
13235
13245
  async function buildReviewAgainstRulesPrompt(domain) {
13236
13246
  const entries = await kernelQuery("chain.listEntries", { collectionSlug: "rules" });
13237
13247
  const rules = entries.slice(0, 50);
@@ -13313,27 +13323,27 @@ function registerPrompts(server) {
13313
13323
  server.prompt(
13314
13324
  "review-against-rules",
13315
13325
  "Review code or a design decision against the rules, focused on a given area. Fetches the rules and asks you to do a structured compliance review.",
13316
- { domain: z33.string().describe("Business rule domain (e.g. 'Identity & Access', 'Governance & Decision-Making')") },
13326
+ { domain: z34.string().describe("Business rule domain (e.g. 'Identity & Access', 'Governance & Decision-Making')") },
13317
13327
  async ({ domain }) => buildReviewAgainstRulesPrompt(domain)
13318
13328
  );
13319
13329
  server.prompt(
13320
13330
  "name-check",
13321
13331
  "Check variable names, field names, or API names against the glossary for terminology alignment. Flags drift from canonical terms.",
13322
- { names: z33.string().describe("Comma-separated list of names to check (e.g. 'user_id, workspace_id, entry_status')") },
13332
+ { names: z34.string().describe("Comma-separated list of names to check (e.g. 'user_id, workspace_id, entry_status')") },
13323
13333
  async ({ names }) => buildNameCheckPrompt(names)
13324
13334
  );
13325
13335
  server.prompt(
13326
13336
  "draft-decision-record",
13327
13337
  "Draft a structured decision record from a description of what was decided. Includes context from recent decisions and relevant rules.",
13328
- { context: z33.string().describe("Description of the decision (e.g. 'We decided to keep one body field per entry because...')") },
13338
+ { context: z34.string().describe("Description of the decision (e.g. 'We decided to keep one body field per entry because...')") },
13329
13339
  async ({ context }) => buildDraftDecisionRecordPrompt(context)
13330
13340
  );
13331
13341
  server.prompt(
13332
13342
  "draft-rule-from-context",
13333
13343
  "Draft a new business rule from an observation or discovery made while coding. Fetches existing rules for the domain to ensure consistency.",
13334
13344
  {
13335
- observation: z33.string().describe("What you observed or discovered (e.g. 'A workspace can have more than one owner role')"),
13336
- domain: z33.string().describe("Which domain this rule belongs to (e.g. 'Governance & Decision-Making')")
13345
+ observation: z34.string().describe("What you observed or discovered (e.g. 'A workspace can have more than one owner role')"),
13346
+ domain: z34.string().describe("Which domain this rule belongs to (e.g. 'Governance & Decision-Making')")
13337
13347
  },
13338
13348
  async ({ observation, domain }) => buildDraftRuleFromContextPrompt(observation, domain)
13339
13349
  );
@@ -13426,7 +13436,7 @@ var INSTRUCTIONS = [
13426
13436
  "## Pull the rest",
13427
13437
  "",
13428
13438
  '- `orient action=task task="<what you are doing>"`: context shaped to the task, with the rules for your team and role.',
13429
- '- `entries action=get entryId="<ID>"`: one entry in full, with data, relations and history.',
13439
+ '- `context action=get entryId="<ID>"`: one entry in full, with data, relations and history.',
13430
13440
  '- `entries action=search query="<noun>"`: find entries by what they are about.',
13431
13441
  "",
13432
13442
  "## Writing",
@@ -13442,7 +13452,7 @@ var INSTRUCTIONS = [
13442
13452
  "",
13443
13453
  "Every tool and action: `productbrain://agent-cheatsheet`."
13444
13454
  ].join("\n");
13445
- var sessionIdArg = z34.string().max(200).optional().describe(
13455
+ var sessionIdArg = z35.string().max(200).optional().describe(
13446
13456
  "The sessionId `session action=start` returned. Pass it on every write: the connection does not remember your session between calls."
13447
13457
  );
13448
13458
  function acceptSessionIdOnEveryTool(server) {
@@ -13534,4 +13544,4 @@ export {
13534
13544
  createProductBrainServer,
13535
13545
  initFeatureFlags
13536
13546
  };
13537
- //# sourceMappingURL=chunk-APQ2MKVQ.js.map
13547
+ //# sourceMappingURL=chunk-J5MP5CNG.js.map