@productbrain/mcp 0.0.1-beta.6470 → 0.0.1-beta.6483
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.
- package/dist/{chunk-EP66ZPBW.js → chunk-GLLZURWD.js} +1 -1
- package/dist/chunk-GLLZURWD.js.map +1 -0
- package/dist/{chunk-PZDI2QMN.js → chunk-YSYVDNEK.js} +986 -2109
- package/dist/chunk-YSYVDNEK.js.map +1 -0
- package/dist/cli/index.js +1 -1
- package/dist/http.js +2 -2
- package/dist/index.js +2 -2
- package/dist/{setup-GDYECAJV.js → setup-BZOTN4SR.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-EP66ZPBW.js.map +0 -1
- package/dist/chunk-PZDI2QMN.js.map +0 -1
- /package/dist/{setup-GDYECAJV.js.map → setup-BZOTN4SR.js.map} +0 -0
|
@@ -41,7 +41,7 @@ import {
|
|
|
41
41
|
trackSessionCaptureRate,
|
|
42
42
|
trackWriteBackHintServed,
|
|
43
43
|
trackZeroCaptureAuditFired
|
|
44
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-GLLZURWD.js";
|
|
45
45
|
|
|
46
46
|
// src/server.ts
|
|
47
47
|
import { McpServer as McpServer2 } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
@@ -86,15 +86,12 @@ function renderEntryPreflight(preflight) {
|
|
|
86
86
|
function isPreviewCreateEntryResult(result2) {
|
|
87
87
|
return "preview" in result2 && result2.preview === true;
|
|
88
88
|
}
|
|
89
|
-
function extractPreviewWouldBlock(result2, preview) {
|
|
90
|
-
return preview && result2 && isPreviewCreateEntryResult(result2) ? { wouldBlock: result2.wouldBlock === true, blockingReason: result2.blockingReason } : void 0;
|
|
91
|
-
}
|
|
92
89
|
function resolveEffectiveCollection(result2, preview, fallbackCollection) {
|
|
93
90
|
return preview && result2 && isPreviewCreateEntryResult(result2) ? result2.collection ?? fallbackCollection : fallbackCollection;
|
|
94
91
|
}
|
|
95
92
|
|
|
96
93
|
// src/tools/entries.ts
|
|
97
|
-
import { z as
|
|
94
|
+
import { z as z10 } from "zod/v3";
|
|
98
95
|
|
|
99
96
|
// src/envelope.ts
|
|
100
97
|
import { z } from "zod/v3";
|
|
@@ -324,8 +321,7 @@ var metaSchema = z.object({
|
|
|
324
321
|
autoLinkMs: z.number().optional(),
|
|
325
322
|
userLinksMs: z.number().optional(),
|
|
326
323
|
qualityMs: z.number().optional(),
|
|
327
|
-
totalMs: z.number()
|
|
328
|
-
perEntryAvgMs: z.number().optional()
|
|
324
|
+
totalMs: z.number()
|
|
329
325
|
}).passthrough().optional(),
|
|
330
326
|
// WP-484 S1 (§4): backpressure channel — see EnvelopeMeta for the contract.
|
|
331
327
|
tip: z.string().optional(),
|
|
@@ -563,7 +559,6 @@ var TOOL_NAME_MIGRATIONS = /* @__PURE__ */ new Map([
|
|
|
563
559
|
["health", 'workspace action="check|whoami|status|audit|self-test" (same action names)'],
|
|
564
560
|
["verify", 'quality action="verify-chain"'],
|
|
565
561
|
["verify-entry", 'entries action="verify"'],
|
|
566
|
-
["batch-capture", 'capture action="batch" (entries[] \u2192 items[])'],
|
|
567
562
|
["skills", 'workflows action="load-skill"'],
|
|
568
563
|
["start_pb", 'orient action="start"'],
|
|
569
564
|
["record_activation", 'orient action="record-activation"'],
|
|
@@ -696,10 +691,10 @@ async function dispatchDiscriminated(toolName, union2, flatData, actionSpecs, ha
|
|
|
696
691
|
}
|
|
697
692
|
|
|
698
693
|
// src/tools/knowledge.ts
|
|
699
|
-
import { z as
|
|
694
|
+
import { z as z6 } from "zod/v3";
|
|
700
695
|
|
|
701
696
|
// src/tools/smart-capture.ts
|
|
702
|
-
import { z as
|
|
697
|
+
import { z as z4 } from "zod/v3";
|
|
703
698
|
|
|
704
699
|
// src/lib/captureTimeoutOutcome.ts
|
|
705
700
|
function isGatewayTimeout(error) {
|
|
@@ -781,11 +776,6 @@ ${msg}
|
|
|
781
776
|
)
|
|
782
777
|
};
|
|
783
778
|
}
|
|
784
|
-
function describeBatchEntryError(error, entryName) {
|
|
785
|
-
const msg = error instanceof Error ? error.message : String(error);
|
|
786
|
-
if (!isGatewayTimeout(error)) return msg;
|
|
787
|
-
return error.mayHaveLanded ? `${msg} Outcome unknown for this entry \u2014 search for "${entryName}" before re-running the batch, or it may be captured twice.` : `${msg} This was a preview, so nothing was written for this entry \u2014 safe to re-run the batch.`;
|
|
788
|
-
}
|
|
789
779
|
|
|
790
780
|
// src/lib/scopedCache.ts
|
|
791
781
|
var ScopedCache = class {
|
|
@@ -1160,306 +1150,6 @@ function tokenizeText(input) {
|
|
|
1160
1150
|
return input.toLowerCase().replace(/[^\p{L}\p{N}\s]+/gu, " ").split(/\s+/).filter(Boolean);
|
|
1161
1151
|
}
|
|
1162
1152
|
|
|
1163
|
-
// src/lib/batchCaptureOutput.ts
|
|
1164
|
-
import { z as z4 } from "zod/v3";
|
|
1165
|
-
|
|
1166
|
-
// src/lib/batchTimeoutCohort.ts
|
|
1167
|
-
import { z as z3 } from "zod/v3";
|
|
1168
|
-
var unknownOutcomeEntrySchema = z3.object({
|
|
1169
|
-
index: z3.number(),
|
|
1170
|
-
collection: z3.string(),
|
|
1171
|
-
name: z3.string(),
|
|
1172
|
-
error: z3.string(),
|
|
1173
|
-
mayHaveLanded: z3.boolean(),
|
|
1174
|
-
budgetMs: z3.number(),
|
|
1175
|
-
elapsedMs: z3.number()
|
|
1176
|
-
});
|
|
1177
|
-
function deriveTimeoutOutcome(error) {
|
|
1178
|
-
return isGatewayTimeout(error) ? { mayHaveLanded: error.mayHaveLanded, budgetMs: error.budgetMs, elapsedMs: error.elapsedMs } : void 0;
|
|
1179
|
-
}
|
|
1180
|
-
function describeBatchEntryOutcome(error, entryName) {
|
|
1181
|
-
return { error: describeBatchEntryError(error, entryName), timeoutOutcome: deriveTimeoutOutcome(error) };
|
|
1182
|
-
}
|
|
1183
|
-
function splitBatchNotOk(notOk) {
|
|
1184
|
-
return {
|
|
1185
|
-
failed: notOk.filter((r) => !r.timeoutOutcome),
|
|
1186
|
-
unknownOutcome: notOk.filter((r) => r.timeoutOutcome).map((r) => ({
|
|
1187
|
-
index: r.entryIdx,
|
|
1188
|
-
collection: r.collection,
|
|
1189
|
-
name: r.name,
|
|
1190
|
-
error: r.error ?? "unknown error",
|
|
1191
|
-
mayHaveLanded: r.timeoutOutcome.mayHaveLanded,
|
|
1192
|
-
budgetMs: r.timeoutOutcome.budgetMs,
|
|
1193
|
-
elapsedMs: r.timeoutOutcome.elapsedMs
|
|
1194
|
-
}))
|
|
1195
|
-
};
|
|
1196
|
-
}
|
|
1197
|
-
function unknownOutcomeSummaryNote(entries) {
|
|
1198
|
-
return entries.length > 0 ? `, ${entries.length} outcome unknown` : "";
|
|
1199
|
-
}
|
|
1200
|
-
function renderOutcomeUnknownSection(entries) {
|
|
1201
|
-
if (entries.length === 0) return [];
|
|
1202
|
-
const anyMayHaveLanded = entries.some((e) => e.mayHaveLanded);
|
|
1203
|
-
return [
|
|
1204
|
-
"",
|
|
1205
|
-
"## Outcome Unknown \u2014 Not Failed",
|
|
1206
|
-
...entries.map((e) => `- ${e.name} [${e.collection}]: _${e.error}_`),
|
|
1207
|
-
"",
|
|
1208
|
-
anyMayHaveLanded ? "_Do NOT retry these individually \u2014 search for each name first (see `unknownOutcomeEntries` in the structured response); a retry may duplicate an entry that already landed._" : "_Nothing was written for these \u2014 the preview returns before any write, so re-running is safe. Only the validation verdict is missing._"
|
|
1209
|
-
];
|
|
1210
|
-
}
|
|
1211
|
-
|
|
1212
|
-
// src/lib/batchCaptureOutput.ts
|
|
1213
|
-
var batchCaptureRealOutputSchema = z4.object({
|
|
1214
|
-
captured: z4.array(z4.object({
|
|
1215
|
-
entryId: z4.string(),
|
|
1216
|
-
collection: z4.string(),
|
|
1217
|
-
name: z4.string(),
|
|
1218
|
-
// WP-751 M3a-1b (TASK-189, DEC-1700): "proposed" and "draft_on_failure" are never emitted
|
|
1219
|
-
// by `buildBatchEntryFailure` or the create loop anymore — both were statuses the deleted
|
|
1220
|
-
// client-side auto-commit attempt could produce. Left in the enum (not narrowed) since this
|
|
1221
|
-
// is a shared output-contract schema; narrowing it is a separate, independently-scoped change.
|
|
1222
|
-
status: z4.enum(["draft", "committed", "proposed", "draft_on_failure", "draft_spine_floor"]),
|
|
1223
|
-
spineFloor: z4.object({ relationType: z4.string(), parentKind: z4.string(), exempt: z4.boolean() }).optional(),
|
|
1224
|
-
classifiedBy: z4.enum(["llm", "heuristic", "explicit"]).optional(),
|
|
1225
|
-
confidence: z4.number().optional(),
|
|
1226
|
-
confidenceTier: z4.enum(["high", "medium", "low"]).optional(),
|
|
1227
|
-
warnings: z4.array(z4.string()).optional(),
|
|
1228
|
-
normalization: z4.object({
|
|
1229
|
-
remapped: z4.record(z4.string()).optional(),
|
|
1230
|
-
rejected: z4.array(z4.string()).optional()
|
|
1231
|
-
}).optional(),
|
|
1232
|
-
// TEN-2365: capture-time authority-domain proposal slug (PENDING ratification), when filed.
|
|
1233
|
-
domain: z4.string().optional()
|
|
1234
|
-
// WP-751 M3a-1b (TASK-189, DEC-1700): `coherencyRefusal` and `contradictionAdvisory` are
|
|
1235
|
-
// deleted — both were only ever populated by the client-side auto-commit attempt
|
|
1236
|
-
// (smart-capture.ts), deleted entirely. Role is the only governance mode a reader honors
|
|
1237
|
-
// now, and role never attempted a client-side commit.
|
|
1238
|
-
})),
|
|
1239
|
-
total: z4.number(),
|
|
1240
|
-
failed: z4.number(),
|
|
1241
|
-
committed: z4.number(),
|
|
1242
|
-
proposed: z4.number(),
|
|
1243
|
-
drafts: z4.number(),
|
|
1244
|
-
spineFloored: z4.number().optional(),
|
|
1245
|
-
classified: z4.number().optional(),
|
|
1246
|
-
autoCommitApplied: z4.boolean(),
|
|
1247
|
-
skippedLowConfidence: z4.array(z4.object({
|
|
1248
|
-
index: z4.number(),
|
|
1249
|
-
name: z4.string(),
|
|
1250
|
-
suggestedCollection: z4.string().optional(),
|
|
1251
|
-
confidence: z4.number().optional(),
|
|
1252
|
-
alternatives: z4.array(z4.object({
|
|
1253
|
-
collection: z4.string(),
|
|
1254
|
-
confidence: z4.number()
|
|
1255
|
-
})).optional()
|
|
1256
|
-
})).optional(),
|
|
1257
|
-
failedEntries: z4.array(z4.object({
|
|
1258
|
-
index: z4.number(),
|
|
1259
|
-
collection: z4.string(),
|
|
1260
|
-
name: z4.string(),
|
|
1261
|
-
error: z4.string()
|
|
1262
|
-
})).optional(),
|
|
1263
|
-
// WP-575 review round (P1, TEN-1126): a DISTINCT cohort from `failedEntries` — additive,
|
|
1264
|
-
// never removes or retypes an existing field (repo's schema rule). See
|
|
1265
|
-
// lib/batchTimeoutCohort.ts's doc comment for why this must stay separate.
|
|
1266
|
-
unknownOutcomeEntries: z4.array(unknownOutcomeEntrySchema).optional()
|
|
1267
|
-
});
|
|
1268
|
-
var batchCapturePreviewOutputSchema = z4.object({
|
|
1269
|
-
outcome: z4.literal("preview"),
|
|
1270
|
-
wouldCapture: z4.array(z4.object({
|
|
1271
|
-
// Fix 1 (WP-577 review re-review, TEN-2918 follow-up): optional, not required — see
|
|
1272
|
-
// WouldCaptureEntry's doc comment. Absent exactly when `entryIdAssignedAtCapture` is true.
|
|
1273
|
-
entryId: z4.string().optional(),
|
|
1274
|
-
entryIdAssignedAtCapture: z4.literal(true).optional(),
|
|
1275
|
-
preflight: z4.custom().optional(),
|
|
1276
|
-
collection: z4.string(),
|
|
1277
|
-
name: z4.string(),
|
|
1278
|
-
classifiedBy: z4.string().optional(),
|
|
1279
|
-
confidence: z4.number().optional(),
|
|
1280
|
-
warnings: z4.array(z4.string()).optional()
|
|
1281
|
-
})),
|
|
1282
|
-
// WP-577 review follow-up (P2, TEN-2918): entries the server's WHY/glossary gate says would
|
|
1283
|
-
// be BLOCKED on a real (non-preview) create — a distinct cohort from `wouldCapture` so the
|
|
1284
|
-
// structured response never claims a governance-refused capture would succeed. Optional/
|
|
1285
|
-
// additive: absent (or empty) on every response this route produced before this fix.
|
|
1286
|
-
wouldBlock: z4.array(z4.object({
|
|
1287
|
-
entryId: z4.string().optional(),
|
|
1288
|
-
entryIdAssignedAtCapture: z4.literal(true).optional(),
|
|
1289
|
-
preflight: z4.custom().optional(),
|
|
1290
|
-
collection: z4.string(),
|
|
1291
|
-
name: z4.string(),
|
|
1292
|
-
blockingReason: z4.string().optional(),
|
|
1293
|
-
warnings: z4.array(z4.string()).optional()
|
|
1294
|
-
})).optional(),
|
|
1295
|
-
requested: z4.number(),
|
|
1296
|
-
total: z4.number(),
|
|
1297
|
-
failed: z4.number(),
|
|
1298
|
-
skippedLowConfidence: z4.array(z4.object({
|
|
1299
|
-
index: z4.number(),
|
|
1300
|
-
name: z4.string(),
|
|
1301
|
-
suggestedCollection: z4.string().optional(),
|
|
1302
|
-
confidence: z4.number().optional()
|
|
1303
|
-
})).optional(),
|
|
1304
|
-
failedEntries: z4.array(z4.object({
|
|
1305
|
-
index: z4.number(),
|
|
1306
|
-
collection: z4.string(),
|
|
1307
|
-
name: z4.string(),
|
|
1308
|
-
error: z4.string()
|
|
1309
|
-
})).optional(),
|
|
1310
|
-
// WP-575 review round (P1, TEN-1126): sibling of the same field on
|
|
1311
|
-
// batchCaptureRealOutputSchema — preview batches reach the SAME unconditional
|
|
1312
|
-
// `chain.createEntry` catch a real batch does, so the discriminator exists here too.
|
|
1313
|
-
unknownOutcomeEntries: z4.array(unknownOutcomeEntrySchema).optional()
|
|
1314
|
-
});
|
|
1315
|
-
var batchCaptureOutputSchema = z4.union([
|
|
1316
|
-
batchCaptureRealOutputSchema,
|
|
1317
|
-
batchCapturePreviewOutputSchema
|
|
1318
|
-
]);
|
|
1319
|
-
function buildBatchPreviewSummary({ wouldCapture, wouldBlock = [], failed, unknownOutcome = [], skipped, requested }) {
|
|
1320
|
-
const noun = requested === 1 ? "entry" : "entries";
|
|
1321
|
-
const blockedNote = wouldBlock.length > 0 ? `, ${wouldBlock.length} would be BLOCKED` : "";
|
|
1322
|
-
const failedNote = failed.length > 0 ? `, ${failed.length} would fail` : "";
|
|
1323
|
-
const unknownNote = unknownOutcomeSummaryNote(unknownOutcome);
|
|
1324
|
-
const skippedNote = skipped.length > 0 ? `, ${skipped.length} skipped (low confidence)` : "";
|
|
1325
|
-
return `Preview: would capture ${wouldCapture.length} of ${requested} ${noun}${blockedNote}${failedNote}${unknownNote}${skippedNote} \u2014 no DB writes.`;
|
|
1326
|
-
}
|
|
1327
|
-
function buildBatchEntryFailure(args) {
|
|
1328
|
-
return {
|
|
1329
|
-
entryIdx: args.entryIdx,
|
|
1330
|
-
name: args.name,
|
|
1331
|
-
collection: args.collection,
|
|
1332
|
-
entryId: "",
|
|
1333
|
-
ok: false,
|
|
1334
|
-
autoLinks: 0,
|
|
1335
|
-
advisedLinks: 0,
|
|
1336
|
-
status: "draft",
|
|
1337
|
-
classifiedBy: args.classifiedBy,
|
|
1338
|
-
confidence: args.confidence,
|
|
1339
|
-
confidenceTier: args.confidenceTier,
|
|
1340
|
-
error: args.error,
|
|
1341
|
-
...args.timeoutOutcome ? { timeoutOutcome: args.timeoutOutcome } : {}
|
|
1342
|
-
};
|
|
1343
|
-
}
|
|
1344
|
-
function buildBatchPreviewFromResults(created, failed, skipped, requested, originalItems, originalAutoCommit) {
|
|
1345
|
-
const wouldCaptureEntries = created.filter((r) => !r.wouldBlock);
|
|
1346
|
-
const wouldBlockEntries = created.filter((r) => r.wouldBlock);
|
|
1347
|
-
const { failed: genuinelyFailed, unknownOutcome: timedOut } = splitBatchNotOk(failed);
|
|
1348
|
-
return buildBatchPreviewResult({
|
|
1349
|
-
// Fix 1 (TEN-2918 follow-up): report the concrete `entryId` only when it was NOT
|
|
1350
|
-
// auto-allocated (i.e. the caller supplied it for this item) — see WouldCaptureEntry's
|
|
1351
|
-
// doc comment for why an auto-ID cannot be predicted per-item within a preview batch.
|
|
1352
|
-
wouldCapture: wouldCaptureEntries.map((r) => ({
|
|
1353
|
-
...r.preflight ? { preflight: r.preflight } : {},
|
|
1354
|
-
...r.entryIdAssignedAtCapture ? { entryIdAssignedAtCapture: true } : { entryId: r.entryId },
|
|
1355
|
-
collection: r.collection,
|
|
1356
|
-
name: r.name,
|
|
1357
|
-
...r.classifiedBy ? { classifiedBy: r.classifiedBy } : {},
|
|
1358
|
-
...r.confidence != null ? { confidence: r.confidence } : {},
|
|
1359
|
-
...r.warnings?.length ? { warnings: r.warnings } : {}
|
|
1360
|
-
})),
|
|
1361
|
-
wouldBlock: wouldBlockEntries.map((r) => ({
|
|
1362
|
-
...r.preflight ? { preflight: r.preflight } : {},
|
|
1363
|
-
...r.entryIdAssignedAtCapture ? { entryIdAssignedAtCapture: true } : { entryId: r.entryId },
|
|
1364
|
-
collection: r.collection,
|
|
1365
|
-
name: r.name,
|
|
1366
|
-
...r.blockingReason ? { blockingReason: r.blockingReason } : {},
|
|
1367
|
-
...r.warnings?.length ? { warnings: r.warnings } : {}
|
|
1368
|
-
})),
|
|
1369
|
-
failed: genuinelyFailed.map((r) => ({ index: r.entryIdx, collection: r.collection, name: r.name, error: r.error ?? "unknown error" })),
|
|
1370
|
-
unknownOutcome: timedOut,
|
|
1371
|
-
// WP-575 review (P1, TEN-1126) — see lib/batchTimeoutCohort.ts.
|
|
1372
|
-
skipped: skipped.map((s) => ({ index: s.index, name: s.name, ...s.suggestedCollection ? { suggestedCollection: s.suggestedCollection } : {}, ...s.confidence != null ? { confidence: s.confidence } : {} })),
|
|
1373
|
-
requested,
|
|
1374
|
-
// WP-577 review follow-up (P2, TEN-2918): thread the caller's original batch payload
|
|
1375
|
-
// through so the "Capture for real" next-action can supply a non-empty `items` array —
|
|
1376
|
-
// omitting it left the suggestion advertising `{ action: "batch" }` alone, which fails
|
|
1377
|
-
// batchCaptureSchema's `.min(1)` items requirement the instant an agent follows it.
|
|
1378
|
-
originalItems,
|
|
1379
|
-
// Fix 1 (TEN-2918 follow-up): thread the batch's own autoCommit through unchanged.
|
|
1380
|
-
originalAutoCommit
|
|
1381
|
-
});
|
|
1382
|
-
}
|
|
1383
|
-
function buildBatchPreviewResult(input) {
|
|
1384
|
-
const { wouldCapture, wouldBlock = [], failed, unknownOutcome = [], skipped, requested, originalItems, originalAutoCommit } = input;
|
|
1385
|
-
const summary = buildBatchPreviewSummary(input);
|
|
1386
|
-
const lines = [`# Batch Preview \u2014 No Entries Created`, summary, ""];
|
|
1387
|
-
if (wouldCapture.length > 0) {
|
|
1388
|
-
lines.push("## Would capture");
|
|
1389
|
-
for (const r of wouldCapture) {
|
|
1390
|
-
const classNote = r.classifiedBy && r.classifiedBy !== "explicit" ? ` (${r.classifiedBy}${r.confidence != null ? ` ${r.confidence}%` : ""})` : "";
|
|
1391
|
-
const warnNote = r.warnings?.length ? ` \u2014 ${r.warnings.join("; ")}` : "";
|
|
1392
|
-
const idNote = r.entryId ? `**${r.entryId}**: ` : "";
|
|
1393
|
-
const assignedNote = r.entryIdAssignedAtCapture ? " (ID assigned at capture)" : "";
|
|
1394
|
-
lines.push(`- ${idNote}**${r.name}** [${r.collection}]${classNote}${warnNote}${assignedNote}`);
|
|
1395
|
-
if (r.preflight) lines.push(...renderEntryPreflight(r.preflight));
|
|
1396
|
-
}
|
|
1397
|
-
lines.push("");
|
|
1398
|
-
}
|
|
1399
|
-
if (wouldBlock.length > 0) {
|
|
1400
|
-
lines.push("## Would be BLOCKED");
|
|
1401
|
-
for (const b of wouldBlock) {
|
|
1402
|
-
const reasonNote = b.blockingReason ? ` \u2014 ${b.blockingReason}` : "";
|
|
1403
|
-
const idNote = b.entryId ? `**${b.entryId}**: ` : "";
|
|
1404
|
-
const assignedNote = b.entryIdAssignedAtCapture ? " (ID assigned at capture)" : "";
|
|
1405
|
-
lines.push(`- ${idNote}**${b.name}** [${b.collection}]${reasonNote}${assignedNote}`);
|
|
1406
|
-
if (b.preflight) lines.push(...renderEntryPreflight(b.preflight));
|
|
1407
|
-
}
|
|
1408
|
-
lines.push("");
|
|
1409
|
-
}
|
|
1410
|
-
if (skipped.length > 0) {
|
|
1411
|
-
lines.push("## Would be skipped \u2014 low confidence");
|
|
1412
|
-
for (const s of skipped) {
|
|
1413
|
-
const suggestion = s.suggestedCollection ? ` \u2014 best guess: \`${s.suggestedCollection}\`${s.confidence != null ? ` (${s.confidence}%)` : ""}` : " \u2014 no classification available";
|
|
1414
|
-
lines.push(`- **[${s.index}]** ${s.name}${suggestion}`);
|
|
1415
|
-
}
|
|
1416
|
-
lines.push("");
|
|
1417
|
-
}
|
|
1418
|
-
if (failed.length > 0) {
|
|
1419
|
-
lines.push("## Would fail");
|
|
1420
|
-
for (const f of failed) {
|
|
1421
|
-
lines.push(`- **[${f.index}]** ${f.name} [${f.collection}]: _${f.error}_`);
|
|
1422
|
-
}
|
|
1423
|
-
lines.push("");
|
|
1424
|
-
}
|
|
1425
|
-
lines.push(...renderOutcomeUnknownSection(unknownOutcome));
|
|
1426
|
-
lines.push("_No DB writes \u2014 call `capture action=batch` without `preview:true` to capture for real._");
|
|
1427
|
-
const next = originalItems && originalItems.length > 0 ? [{
|
|
1428
|
-
tool: "capture",
|
|
1429
|
-
description: "Capture for real",
|
|
1430
|
-
parameters: {
|
|
1431
|
-
action: "batch",
|
|
1432
|
-
items: originalItems,
|
|
1433
|
-
// Fix 1 (WP-577 review round 3, TEN-2918 follow-up): preserve the batch's own
|
|
1434
|
-
// autoCommit explicitly — `false` must survive (never dropped as falsy), and
|
|
1435
|
-
// `undefined` (never supplied) is omitted so the server default still governs.
|
|
1436
|
-
...originalAutoCommit !== void 0 ? { autoCommit: originalAutoCommit } : {}
|
|
1437
|
-
}
|
|
1438
|
-
}] : [];
|
|
1439
|
-
return {
|
|
1440
|
-
content: [{ type: "text", text: lines.join("\n") }],
|
|
1441
|
-
structuredContent: {
|
|
1442
|
-
...success(
|
|
1443
|
-
summary,
|
|
1444
|
-
{
|
|
1445
|
-
outcome: "preview",
|
|
1446
|
-
wouldCapture,
|
|
1447
|
-
...wouldBlock.length > 0 ? { wouldBlock } : {},
|
|
1448
|
-
requested,
|
|
1449
|
-
total: wouldCapture.length,
|
|
1450
|
-
failed: failed.length,
|
|
1451
|
-
...skipped.length > 0 ? { skippedLowConfidence: skipped } : {},
|
|
1452
|
-
...failed.length > 0 ? { failedEntries: failed } : {},
|
|
1453
|
-
// WP-575 review round (P1, TEN-1126): structured sibling of `failedEntries` — see
|
|
1454
|
-
// `UnknownOutcomeEntry`'s doc comment for why these are never merged into it.
|
|
1455
|
-
...unknownOutcome.length > 0 ? { unknownOutcomeEntries: unknownOutcome } : {}
|
|
1456
|
-
},
|
|
1457
|
-
next
|
|
1458
|
-
)
|
|
1459
|
-
}
|
|
1460
|
-
};
|
|
1461
|
-
}
|
|
1462
|
-
|
|
1463
1153
|
// src/lib/entryDataNormalization.ts
|
|
1464
1154
|
function isEmptyValue(v) {
|
|
1465
1155
|
return v == null || (Array.isArray(v) ? v.length === 0 : String(v).trim() === "");
|
|
@@ -1514,44 +1204,6 @@ function canonicalizeSelects(data, fields, isBet) {
|
|
|
1514
1204
|
}
|
|
1515
1205
|
}
|
|
1516
1206
|
|
|
1517
|
-
// src/lib/batchInlineRelations.ts
|
|
1518
|
-
async function applyBatchInlineRelations(relations, finalEntryId, preview, agentId) {
|
|
1519
|
-
const result2 = {
|
|
1520
|
-
relationsCreatedCount: 0,
|
|
1521
|
-
relationsProposedCount: 0,
|
|
1522
|
-
relationsNotValidatedCount: 0,
|
|
1523
|
-
relationsFailedList: []
|
|
1524
|
-
};
|
|
1525
|
-
if (!relations || relations.length === 0) return result2;
|
|
1526
|
-
if (preview) {
|
|
1527
|
-
result2.relationsNotValidatedCount = relations.length;
|
|
1528
|
-
return result2;
|
|
1529
|
-
}
|
|
1530
|
-
for (const rel of relations) {
|
|
1531
|
-
try {
|
|
1532
|
-
const relResult = await kernelMutation(
|
|
1533
|
-
"chain.createEntryRelation",
|
|
1534
|
-
{
|
|
1535
|
-
fromEntryId: finalEntryId,
|
|
1536
|
-
toEntryId: rel.to,
|
|
1537
|
-
type: rel.type,
|
|
1538
|
-
proposedBy: "user",
|
|
1539
|
-
sessionId: agentId ?? void 0
|
|
1540
|
-
}
|
|
1541
|
-
);
|
|
1542
|
-
if (relResult?.status === "agent_proposal_created") {
|
|
1543
|
-
result2.relationsProposedCount++;
|
|
1544
|
-
} else {
|
|
1545
|
-
result2.relationsCreatedCount++;
|
|
1546
|
-
}
|
|
1547
|
-
} catch (relErr) {
|
|
1548
|
-
const relMsg = relErr instanceof Error ? relErr.message : String(relErr);
|
|
1549
|
-
result2.relationsFailedList.push(`${rel.to} (${rel.type}): ${relMsg}`);
|
|
1550
|
-
}
|
|
1551
|
-
}
|
|
1552
|
-
return result2;
|
|
1553
|
-
}
|
|
1554
|
-
|
|
1555
1207
|
// src/lib/captureForRealAction.ts
|
|
1556
1208
|
function buildCaptureForRealNextAction(payload) {
|
|
1557
1209
|
const {
|
|
@@ -1676,156 +1328,50 @@ function formatRubricVerdictSection(verdict) {
|
|
|
1676
1328
|
}
|
|
1677
1329
|
|
|
1678
1330
|
// src/lib/captureSinglePreviewOutput.ts
|
|
1679
|
-
import { z as
|
|
1680
|
-
var groundingRelatedEntrySchema =
|
|
1681
|
-
entryId:
|
|
1682
|
-
name:
|
|
1683
|
-
collectionSlug:
|
|
1684
|
-
overlapRatio:
|
|
1685
|
-
recommendedRelationType:
|
|
1686
|
-
reasoning:
|
|
1331
|
+
import { z as z3 } from "zod/v3";
|
|
1332
|
+
var groundingRelatedEntrySchema = z3.object({
|
|
1333
|
+
entryId: z3.string(),
|
|
1334
|
+
name: z3.string(),
|
|
1335
|
+
collectionSlug: z3.string(),
|
|
1336
|
+
overlapRatio: z3.number(),
|
|
1337
|
+
recommendedRelationType: z3.string(),
|
|
1338
|
+
reasoning: z3.string()
|
|
1687
1339
|
});
|
|
1688
|
-
var groundingDuplicateEntrySchema =
|
|
1689
|
-
entryId:
|
|
1690
|
-
name:
|
|
1691
|
-
collectionSlug:
|
|
1692
|
-
matchType:
|
|
1693
|
-
overlapRatio:
|
|
1340
|
+
var groundingDuplicateEntrySchema = z3.object({
|
|
1341
|
+
entryId: z3.string(),
|
|
1342
|
+
name: z3.string(),
|
|
1343
|
+
collectionSlug: z3.string(),
|
|
1344
|
+
matchType: z3.enum(["related", "possible_duplicate"]),
|
|
1345
|
+
overlapRatio: z3.number()
|
|
1694
1346
|
});
|
|
1695
|
-
var groundingGovernanceEntrySchema =
|
|
1696
|
-
entryId:
|
|
1697
|
-
name:
|
|
1698
|
-
collectionSlug:
|
|
1347
|
+
var groundingGovernanceEntrySchema = z3.object({
|
|
1348
|
+
entryId: z3.string(),
|
|
1349
|
+
name: z3.string(),
|
|
1350
|
+
collectionSlug: z3.string()
|
|
1699
1351
|
});
|
|
1700
|
-
var groundingReportSchema =
|
|
1352
|
+
var groundingReportSchema = z3.object({
|
|
1701
1353
|
// TASK-156: null preserves uncertainty for unavailable checks or an older server response.
|
|
1702
|
-
scanTruncated:
|
|
1703
|
-
related:
|
|
1704
|
-
duplicates:
|
|
1705
|
-
governance:
|
|
1354
|
+
scanTruncated: z3.boolean().nullable(),
|
|
1355
|
+
related: z3.array(groundingRelatedEntrySchema),
|
|
1356
|
+
duplicates: z3.array(groundingDuplicateEntrySchema),
|
|
1357
|
+
governance: z3.array(groundingGovernanceEntrySchema)
|
|
1706
1358
|
});
|
|
1707
|
-
var taskAlignmentSchema =
|
|
1708
|
-
var captureSinglePreviewOutputSchema =
|
|
1709
|
-
preflight:
|
|
1710
|
-
entryId:
|
|
1711
|
-
name:
|
|
1712
|
-
collection:
|
|
1713
|
-
outcome:
|
|
1359
|
+
var taskAlignmentSchema = z3.record(z3.unknown());
|
|
1360
|
+
var captureSinglePreviewOutputSchema = z3.object({
|
|
1361
|
+
preflight: z3.custom().optional(),
|
|
1362
|
+
entryId: z3.string(),
|
|
1363
|
+
name: z3.string(),
|
|
1364
|
+
collection: z3.string(),
|
|
1365
|
+
outcome: z3.enum(["preview", "blocked"]),
|
|
1714
1366
|
// Present only when `outcome: "blocked"` AND the server supplied a reason.
|
|
1715
|
-
blockingReason:
|
|
1367
|
+
blockingReason: z3.string().optional(),
|
|
1716
1368
|
// Always present — `result.warnings ?? []`, never omitted.
|
|
1717
|
-
warnings:
|
|
1369
|
+
warnings: z3.array(z3.string()),
|
|
1718
1370
|
groundingReport: groundingReportSchema,
|
|
1719
1371
|
// TEN-2458: only present when the kernel computed a librarian verdict for this preview.
|
|
1720
1372
|
taskAlignment: taskAlignmentSchema.optional()
|
|
1721
1373
|
}).strict();
|
|
1722
1374
|
|
|
1723
|
-
// src/lib/batchPreviewDuplicates.ts
|
|
1724
|
-
function createBatchPreviewDuplicateTracker() {
|
|
1725
|
-
const seenByCollection = /* @__PURE__ */ new Map();
|
|
1726
|
-
const seenEntryIds = /* @__PURE__ */ new Set();
|
|
1727
|
-
return {
|
|
1728
|
-
isDuplicateName(collection, name) {
|
|
1729
|
-
return seenByCollection.get(collection)?.has(name) ?? false;
|
|
1730
|
-
},
|
|
1731
|
-
recordName(collection, name) {
|
|
1732
|
-
let names = seenByCollection.get(collection);
|
|
1733
|
-
if (!names) {
|
|
1734
|
-
names = /* @__PURE__ */ new Set();
|
|
1735
|
-
seenByCollection.set(collection, names);
|
|
1736
|
-
}
|
|
1737
|
-
names.add(name);
|
|
1738
|
-
},
|
|
1739
|
-
isDuplicateEntryId(entryId) {
|
|
1740
|
-
return seenEntryIds.has(entryId);
|
|
1741
|
-
},
|
|
1742
|
-
recordEntryId(entryId) {
|
|
1743
|
-
seenEntryIds.add(entryId);
|
|
1744
|
-
}
|
|
1745
|
-
};
|
|
1746
|
-
}
|
|
1747
|
-
function buildBatchPreviewDuplicateResult(entryIdx, name, collection, classifiedBy, confidence, confidenceTier) {
|
|
1748
|
-
return {
|
|
1749
|
-
entryIdx,
|
|
1750
|
-
name,
|
|
1751
|
-
collection,
|
|
1752
|
-
entryId: "",
|
|
1753
|
-
ok: false,
|
|
1754
|
-
autoLinks: 0,
|
|
1755
|
-
advisedLinks: 0,
|
|
1756
|
-
status: "draft",
|
|
1757
|
-
classifiedBy,
|
|
1758
|
-
confidence,
|
|
1759
|
-
confidenceTier,
|
|
1760
|
-
error: `Duplicate entry: "${name}" already claimed by an earlier item in this batch [${collection}] \u2014 the real (non-preview) run would write the first and reject this one.`
|
|
1761
|
-
};
|
|
1762
|
-
}
|
|
1763
|
-
function buildBatchPreviewDuplicateEntryIdResult(entryIdx, name, collection, entryId, classifiedBy, confidence, confidenceTier) {
|
|
1764
|
-
return {
|
|
1765
|
-
entryIdx,
|
|
1766
|
-
name,
|
|
1767
|
-
collection,
|
|
1768
|
-
entryId: "",
|
|
1769
|
-
ok: false,
|
|
1770
|
-
autoLinks: 0,
|
|
1771
|
-
advisedLinks: 0,
|
|
1772
|
-
status: "draft",
|
|
1773
|
-
classifiedBy,
|
|
1774
|
-
confidence,
|
|
1775
|
-
confidenceTier,
|
|
1776
|
-
error: `Duplicate entry: ID "${entryId}" already claimed by an earlier item in this batch (workspace-wide) \u2014 the real (non-preview) run would write the first and reject this one.`
|
|
1777
|
-
};
|
|
1778
|
-
}
|
|
1779
|
-
function checkBatchPreviewDuplicate(tracker, args) {
|
|
1780
|
-
if (!args.preview) return null;
|
|
1781
|
-
if (args.callerEntryId && tracker.isDuplicateEntryId(args.callerEntryId)) {
|
|
1782
|
-
return buildBatchPreviewDuplicateEntryIdResult(
|
|
1783
|
-
args.entryIdx,
|
|
1784
|
-
args.name,
|
|
1785
|
-
args.collection,
|
|
1786
|
-
args.callerEntryId,
|
|
1787
|
-
args.classifiedBy,
|
|
1788
|
-
args.confidence,
|
|
1789
|
-
args.confidenceTier
|
|
1790
|
-
);
|
|
1791
|
-
}
|
|
1792
|
-
if (tracker.isDuplicateName(args.collection, args.name)) {
|
|
1793
|
-
return buildBatchPreviewDuplicateResult(
|
|
1794
|
-
args.entryIdx,
|
|
1795
|
-
args.name,
|
|
1796
|
-
args.collection,
|
|
1797
|
-
args.classifiedBy,
|
|
1798
|
-
args.confidence,
|
|
1799
|
-
args.confidenceTier
|
|
1800
|
-
);
|
|
1801
|
-
}
|
|
1802
|
-
return null;
|
|
1803
|
-
}
|
|
1804
|
-
function recordBatchPreviewIfConfirmed(tracker, args) {
|
|
1805
|
-
if (!args.wouldCapture) return;
|
|
1806
|
-
tracker.recordName(args.effectiveCollection, args.name);
|
|
1807
|
-
if (args.callerEntryId) tracker.recordEntryId(args.callerEntryId);
|
|
1808
|
-
}
|
|
1809
|
-
function reconcileBatchPreviewDuplicate(tracker, args) {
|
|
1810
|
-
if (args.wouldCapture && tracker.isDuplicateName(args.effectiveCollection, args.name)) {
|
|
1811
|
-
return buildBatchPreviewDuplicateResult(
|
|
1812
|
-
args.entryIdx,
|
|
1813
|
-
args.name,
|
|
1814
|
-
args.effectiveCollection,
|
|
1815
|
-
args.classifiedBy,
|
|
1816
|
-
args.confidence,
|
|
1817
|
-
args.confidenceTier
|
|
1818
|
-
);
|
|
1819
|
-
}
|
|
1820
|
-
recordBatchPreviewIfConfirmed(tracker, {
|
|
1821
|
-
wouldCapture: args.wouldCapture,
|
|
1822
|
-
effectiveCollection: args.effectiveCollection,
|
|
1823
|
-
name: args.name,
|
|
1824
|
-
callerEntryId: args.callerEntryId
|
|
1825
|
-
});
|
|
1826
|
-
return null;
|
|
1827
|
-
}
|
|
1828
|
-
|
|
1829
1375
|
// src/lib/readinessNotices.ts
|
|
1830
1376
|
var READINESS_PROVISIONAL_LINE = "Readiness is provisional: its sample omitted accepted entries. Counts are lower bounds, apparent gaps may already be covered, and the overall stage is unverified.";
|
|
1831
1377
|
|
|
@@ -1895,11 +1441,6 @@ function buildScoreLinkCandidatesJob(candidates, sourceName, sourceDescription,
|
|
|
1895
1441
|
sourceCollection
|
|
1896
1442
|
};
|
|
1897
1443
|
}
|
|
1898
|
-
var LINK_SCORE_CHUNK_MAX_ENTRIES = 10;
|
|
1899
|
-
var LINK_SCORE_CHUNK_MAX_BYTES = 7e5;
|
|
1900
|
-
function estimateJobBytes(job) {
|
|
1901
|
-
return Buffer.byteLength(JSON.stringify(job), "utf8");
|
|
1902
|
-
}
|
|
1903
1444
|
function inferRelationType(_sourceCollection, _targetCollection, profile) {
|
|
1904
1445
|
const type = profile.recommendedRelationTypes[0] ?? "related_to";
|
|
1905
1446
|
const reason = `profile default (${type})`;
|
|
@@ -1911,78 +1452,54 @@ var MAX_SUGGESTIONS = 5;
|
|
|
1911
1452
|
var SPINE_FLOOR_SENTENCE = "kept as a draft; it can be accepted once its spine above is accepted \u2014 the promote door checks the whole spine and names the first missing rung.";
|
|
1912
1453
|
var SPINE_FLOOR_EXEMPT_SENTENCE = "kept as a draft, though this workspace is not yet enforcing the spine above it \u2014 it can be accepted as-is.";
|
|
1913
1454
|
var BR_STD_ENTRY_ID_REGEX = /^(BR|STD)-\d+$/;
|
|
1914
|
-
var entryIdSchema =
|
|
1915
|
-
var captureSchema =
|
|
1916
|
-
collection:
|
|
1917
|
-
name:
|
|
1918
|
-
description:
|
|
1919
|
-
context:
|
|
1455
|
+
var entryIdSchema = z4.string().regex(BR_STD_ENTRY_ID_REGEX).optional().describe("Only for business-rules and standards. Must match BR-NNN or STD-NNN. Omit for all other collections \u2014 IDs are auto-generated.");
|
|
1456
|
+
var captureSchema = z4.object({
|
|
1457
|
+
collection: z4.string().optional().describe("Collection slug, e.g. 'tensions', 'business-rules', 'glossary', 'decisions'. Optional \u2014 classifier auto-routes when omitted."),
|
|
1458
|
+
name: z4.string().describe("Display name \u2014 be specific (e.g. 'Convex adjacency list won't scale for graph traversal')"),
|
|
1459
|
+
description: z4.string().describe("Full context \u2014 what's happening, why it matters, what you observed"),
|
|
1460
|
+
context: z4.string().optional().describe("Optional additional context (e.g. 'Observed during context gather calls taking 700ms+')"),
|
|
1920
1461
|
entryId: entryIdSchema,
|
|
1921
|
-
canonicalKey:
|
|
1922
|
-
data:
|
|
1923
|
-
links:
|
|
1924
|
-
to:
|
|
1925
|
-
type:
|
|
1462
|
+
canonicalKey: z4.string().optional().describe("Semantic type (e.g. 'decision', 'tension', 'vision'). Auto-assigned from collection if omitted."),
|
|
1463
|
+
data: z4.record(z4.unknown()).optional().describe("Explicit field values when you know the schema (e.g. canonical_key, cardinality_rule, required_fields). Merged with inferred values; user-provided wins."),
|
|
1464
|
+
links: z4.array(z4.object({
|
|
1465
|
+
to: z4.string().describe("Target entry ID (e.g. '<PREFIX>-<n>')"),
|
|
1466
|
+
type: z4.string().describe("Relation type (e.g. 'governs', 'related_to', 'informs')")
|
|
1926
1467
|
})).optional().describe("Relations to create after capture. Skips auto-link discovery when provided."),
|
|
1927
|
-
sourceRef:
|
|
1928
|
-
sourceExcerpt:
|
|
1468
|
+
sourceRef: z4.string().optional().describe("URI or path of the source document backing this entry (e.g. 'meeting-2026-03-28.md', 'import://batch-5'). Stored as top-level entry field, not in data."),
|
|
1469
|
+
sourceExcerpt: z4.string().optional().describe("Verbatim excerpt from the source that backs this entry's claims. Stored as top-level entry field, not in data."),
|
|
1929
1470
|
// WP-316 S3: Preview gate — dry-run mode. Returns what would happen, no DB writes.
|
|
1930
|
-
preview:
|
|
1471
|
+
preview: z4.boolean().optional().describe("If true, validates the capture without writing. Returns what would happen. Default false."),
|
|
1931
1472
|
// WP-318 S2: Pre-write grounding — run link suggestion before creating entry.
|
|
1932
|
-
suggestOnly:
|
|
1473
|
+
suggestOnly: z4.boolean().optional().describe("If true, runs pre-write grounding (chain.capture) and returns a groundingReport WITHOUT creating any entry. Use to preview graph participation before accepting. Default false."),
|
|
1933
1474
|
// WP-318 S2: Format for groundingReport in response.
|
|
1934
|
-
format:
|
|
1475
|
+
format: z4.enum(["agent", "human"]).optional().describe("Response format for grounding data. 'agent' (default): full JSON groundingReport. 'human': compressed summary string appended to the capture summary."),
|
|
1935
1476
|
// WP-513: explicit role to create AS OWNER of (rung 2 only). WP-753 O1b (DEC-1715):
|
|
1936
1477
|
// ownerTeamEntryId is deleted — the server derives the team from the role's own placement,
|
|
1937
1478
|
// and an unnamed create resolves a default owner itself instead of landing ownerless.
|
|
1938
|
-
ownerRoleEntryId:
|
|
1479
|
+
ownerRoleEntryId: z4.string().max(200).optional().describe("Owning role entry ID/ref (rung 2); its home team is derived automatically.")
|
|
1939
1480
|
});
|
|
1940
|
-
var
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
sourceRef: z6.string().max(2e3).optional().describe("URI or path of the source document backing this entry (e.g. 'meeting-2026-03-28.md', 'import://batch-5'). Stored as top-level entry field, not in data."),
|
|
1954
|
-
sourceExcerpt: z6.string().max(5e3).optional().describe("Verbatim excerpt from the source that backs this entry's claims. Stored as top-level entry field, not in data."),
|
|
1955
|
-
// TEN-957 (WP-484 S2): relations to create right after this entry is captured.
|
|
1956
|
-
relations: z6.array(batchCaptureRelationSchema).max(10).optional().describe("Relations to create right after this entry is captured \u2014 each {to, type} links the NEW entry to an existing Chain entry."),
|
|
1957
|
-
// WP-513: explicit role to create THIS entry AS OWNER of (rung 2 only). WP-753 O1b:
|
|
1958
|
-
// ownerTeamEntryId deleted — team derives from the role's own placement.
|
|
1959
|
-
ownerRoleEntryId: z6.string().max(200).optional().describe("Owning role entry ID/ref (rung 2); its home team is derived automatically.")
|
|
1960
|
-
})).min(1).max(50).describe("Array of entries to capture"),
|
|
1961
|
-
// WP-316 S3: Preview gate — dry-run mode. Returns what would happen, no DB writes.
|
|
1962
|
-
preview: z6.boolean().optional().describe("If true, validates all captures without writing. Returns what would happen. Default false.")
|
|
1963
|
-
});
|
|
1964
|
-
var captureClassifierSchema = z6.object({
|
|
1965
|
-
enabled: z6.boolean(),
|
|
1966
|
-
autoRouted: z6.boolean(),
|
|
1967
|
-
agrees: z6.boolean(),
|
|
1968
|
-
abstained: z6.boolean(),
|
|
1969
|
-
topConfidence: z6.number(),
|
|
1970
|
-
confidence: z6.number(),
|
|
1971
|
-
reasons: z6.array(z6.string()),
|
|
1972
|
-
candidates: z6.array(
|
|
1973
|
-
z6.object({
|
|
1974
|
-
collection: z6.string(),
|
|
1975
|
-
signalScore: z6.number().optional(),
|
|
1976
|
-
confidence: z6.number(),
|
|
1481
|
+
var captureClassifierSchema = z4.object({
|
|
1482
|
+
enabled: z4.boolean(),
|
|
1483
|
+
autoRouted: z4.boolean(),
|
|
1484
|
+
agrees: z4.boolean(),
|
|
1485
|
+
abstained: z4.boolean(),
|
|
1486
|
+
topConfidence: z4.number(),
|
|
1487
|
+
confidence: z4.number(),
|
|
1488
|
+
reasons: z4.array(z4.string()),
|
|
1489
|
+
candidates: z4.array(
|
|
1490
|
+
z4.object({
|
|
1491
|
+
collection: z4.string(),
|
|
1492
|
+
signalScore: z4.number().optional(),
|
|
1493
|
+
confidence: z4.number(),
|
|
1977
1494
|
/** WP-316 S2: required-field cost — how many fields the agent must supply for this collection. */
|
|
1978
|
-
requiredFieldCount:
|
|
1495
|
+
requiredFieldCount: z4.number().optional()
|
|
1979
1496
|
})
|
|
1980
1497
|
),
|
|
1981
|
-
agentProvidedCollection:
|
|
1982
|
-
overrideCommand:
|
|
1983
|
-
classifiedBy:
|
|
1984
|
-
confidenceTier:
|
|
1985
|
-
reasoning:
|
|
1498
|
+
agentProvidedCollection: z4.string().optional(),
|
|
1499
|
+
overrideCommand: z4.string().optional(),
|
|
1500
|
+
classifiedBy: z4.enum(["llm", "heuristic", "explicit"]).optional(),
|
|
1501
|
+
confidenceTier: z4.enum(["high", "medium", "low"]).optional(),
|
|
1502
|
+
reasoning: z4.string().optional()
|
|
1986
1503
|
});
|
|
1987
1504
|
function trackClassifierTelemetry(params) {
|
|
1988
1505
|
const telemetry = {
|
|
@@ -2210,43 +1727,42 @@ async function resolveCaptureCollection(params) {
|
|
|
2210
1727
|
classifierMeta
|
|
2211
1728
|
};
|
|
2212
1729
|
}
|
|
2213
|
-
var captureSuccessOutputSchema =
|
|
2214
|
-
entryId:
|
|
2215
|
-
collection:
|
|
2216
|
-
name:
|
|
2217
|
-
|
|
2218
|
-
status: z6.enum(["draft", "committed", "proposed", "draft_on_failure", "draft_spine_floor"]),
|
|
1730
|
+
var captureSuccessOutputSchema = z4.object({
|
|
1731
|
+
entryId: z4.string(),
|
|
1732
|
+
collection: z4.string(),
|
|
1733
|
+
name: z4.string(),
|
|
1734
|
+
status: z4.enum(["draft", "committed", "proposed", "draft_on_failure", "draft_spine_floor"]),
|
|
2219
1735
|
// WP-480 S1: `qualityScore` (required, client N/10) deleted — a named, accepted
|
|
2220
1736
|
// breaking output-contract change. The server verdict stays as `qualityVerdict`.
|
|
2221
|
-
qualityVerdict:
|
|
2222
|
-
qualityHints:
|
|
2223
|
-
relationSuggestions:
|
|
1737
|
+
qualityVerdict: z4.record(z4.unknown()).optional(),
|
|
1738
|
+
qualityHints: z4.array(z4.record(z4.unknown())).optional(),
|
|
1739
|
+
relationSuggestions: z4.array(z4.record(z4.unknown())).optional(),
|
|
2224
1740
|
groundingReport: captureSinglePreviewOutputSchema.shape.groundingReport.optional(),
|
|
2225
1741
|
classifier: captureClassifierSchema.optional(),
|
|
2226
|
-
studioUrl:
|
|
2227
|
-
warnings:
|
|
2228
|
-
normalization:
|
|
2229
|
-
remapped:
|
|
2230
|
-
rejected:
|
|
1742
|
+
studioUrl: z4.string().optional(),
|
|
1743
|
+
warnings: z4.array(z4.string()).optional(),
|
|
1744
|
+
normalization: z4.object({
|
|
1745
|
+
remapped: z4.record(z4.string()).optional(),
|
|
1746
|
+
rejected: z4.array(z4.string()).optional()
|
|
2231
1747
|
}).optional(),
|
|
2232
|
-
expectedFields:
|
|
2233
|
-
key:
|
|
2234
|
-
type:
|
|
2235
|
-
required:
|
|
1748
|
+
expectedFields: z4.array(z4.object({
|
|
1749
|
+
key: z4.string(),
|
|
1750
|
+
type: z4.string(),
|
|
1751
|
+
required: z4.boolean().optional()
|
|
2236
1752
|
})).optional(),
|
|
2237
1753
|
// TASK-160: the server's birth-floor verdict must survive the strict output contract.
|
|
2238
|
-
spineFloor:
|
|
1754
|
+
spineFloor: z4.object({ relationType: z4.string(), parentKind: z4.string(), exempt: z4.boolean() }).optional(),
|
|
2239
1755
|
// WP-751 M3a-1b (TASK-189, DEC-1700): `coherencyRefusal` and `contradictionAdvisory` are
|
|
2240
1756
|
// deleted — both were only ever populated by the client-side auto-commit attempt (surfacing
|
|
2241
1757
|
// its own gate refusal, or the commit response's contradiction advisory), and that attempt is
|
|
2242
1758
|
// deleted entirely. Neither field is set anywhere in this file anymore.
|
|
2243
|
-
fallbackApplied:
|
|
1759
|
+
fallbackApplied: z4.boolean().optional()
|
|
2244
1760
|
// round 2 (PRRT_kwDORS4ils6cTNbF): classifier field above still names the original (pre-substitution) prediction
|
|
2245
1761
|
}).strict();
|
|
2246
|
-
var captureClassifierOnlyOutputSchema =
|
|
1762
|
+
var captureClassifierOnlyOutputSchema = z4.object({
|
|
2247
1763
|
classifier: captureClassifierSchema
|
|
2248
1764
|
}).strict();
|
|
2249
|
-
var captureOutputSchema =
|
|
1765
|
+
var captureOutputSchema = z4.union([
|
|
2250
1766
|
captureSuccessOutputSchema,
|
|
2251
1767
|
captureSinglePreviewOutputSchema,
|
|
2252
1768
|
captureClassifierOnlyOutputSchema
|
|
@@ -2262,60 +1778,48 @@ function buildDataFromFields(fields, descriptionField, descriptionValue) {
|
|
|
2262
1778
|
}
|
|
2263
1779
|
return data;
|
|
2264
1780
|
}
|
|
2265
|
-
var CAPTURE_ACTIONS = ["capture"
|
|
2266
|
-
var
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
description: z6.string().max(2e4).optional().describe("For 'capture': full context \u2014 required for this action."),
|
|
2273
|
-
context: z6.string().max(5e3).optional().describe("For 'capture': optional additional context."),
|
|
1781
|
+
var CAPTURE_ACTIONS = ["capture"];
|
|
1782
|
+
var captureCompoundSchema = z4.object({
|
|
1783
|
+
action: z4.enum(CAPTURE_ACTIONS).optional().default("capture").describe("Create a single knowledge entry."),
|
|
1784
|
+
collection: z4.string().max(200).optional().describe("Collection slug, e.g. 'tensions', 'business-rules', 'glossary', 'decisions'. Optional \u2014 classifier auto-routes when omitted."),
|
|
1785
|
+
name: z4.string().max(500).optional().describe("Display name \u2014 required."),
|
|
1786
|
+
description: z4.string().max(2e4).optional().describe("Full context \u2014 required."),
|
|
1787
|
+
context: z4.string().max(5e3).optional().describe("Optional additional context."),
|
|
2274
1788
|
entryId: entryIdSchema,
|
|
2275
|
-
canonicalKey:
|
|
2276
|
-
data:
|
|
2277
|
-
links:
|
|
2278
|
-
to:
|
|
2279
|
-
type:
|
|
2280
|
-
})).max(20).optional().describe("
|
|
2281
|
-
sourceRef:
|
|
2282
|
-
sourceExcerpt:
|
|
2283
|
-
preview:
|
|
2284
|
-
suggestOnly:
|
|
2285
|
-
format:
|
|
2286
|
-
// For 'batch' — mirrors batchCaptureSchema's `entries`, renamed `items` per §3.
|
|
2287
|
-
items: z6.array(captureItemSchema).min(1).max(50).optional().describe("For 'batch': array of entries to capture, each may carry inline `relations`."),
|
|
1789
|
+
canonicalKey: z4.string().max(200).optional().describe("Semantic type (e.g. 'decision', 'tension', 'vision'). Auto-assigned from collection if omitted."),
|
|
1790
|
+
data: z4.record(z4.unknown()).optional().describe("Explicit field values. Merged with inferred values; user-provided wins."),
|
|
1791
|
+
links: z4.array(z4.object({
|
|
1792
|
+
to: z4.string().max(200).describe("Target entry ID (e.g. '<PREFIX>-<n>')"),
|
|
1793
|
+
type: z4.string().max(200).describe("Relation type (e.g. 'governs', 'related_to', 'informs')")
|
|
1794
|
+
})).max(20).optional().describe("Relations to create after capture. Skips auto-link discovery when provided."),
|
|
1795
|
+
sourceRef: z4.string().max(2e3).optional().describe("URI or path of the source document backing this entry."),
|
|
1796
|
+
sourceExcerpt: z4.string().max(5e3).optional().describe("Verbatim excerpt from the source backing this entry's claims."),
|
|
1797
|
+
preview: z4.boolean().optional().describe("If true, validates without writing."),
|
|
1798
|
+
suggestOnly: z4.boolean().optional().describe("If true, runs pre-write grounding and returns a groundingReport WITHOUT creating any entry."),
|
|
1799
|
+
format: z4.enum(["agent", "human"]).optional().describe("Response format for grounding data."),
|
|
2288
1800
|
// WP-513: explicit role to create AS OWNER of (rung 2 only). WP-753 O1b: ownerTeamEntryId
|
|
2289
1801
|
// deleted — team derives from the role's own placement.
|
|
2290
|
-
ownerRoleEntryId:
|
|
2291
|
-
});
|
|
2292
|
-
var captureSingleVariant = captureSchema.extend({ action: z6.literal("capture") });
|
|
2293
|
-
var captureBatchVariant = z6.object({
|
|
2294
|
-
action: z6.literal("batch"),
|
|
2295
|
-
items: z6.array(captureItemSchema).min(1).max(50),
|
|
2296
|
-
preview: z6.boolean().optional()
|
|
1802
|
+
ownerRoleEntryId: z4.string().max(200).optional().describe("Owning role (rung-2); its home team is derived automatically.")
|
|
2297
1803
|
});
|
|
2298
|
-
var
|
|
2299
|
-
|
|
2300
|
-
|
|
1804
|
+
var captureSingleVariant = captureSchema.extend({ action: z4.literal("capture") });
|
|
1805
|
+
var captureActionUnion = z4.discriminatedUnion("action", [
|
|
1806
|
+
captureSingleVariant
|
|
2301
1807
|
]);
|
|
2302
1808
|
var CAPTURE_ACTION_SPECS = {
|
|
2303
1809
|
capture: {
|
|
2304
1810
|
params: ["collection", "name", "description", "context", "entryId", "canonicalKey", "data", "links", "sourceRef", "sourceExcerpt", "preview", "suggestOnly", "format"],
|
|
2305
1811
|
description: "name and description are required."
|
|
2306
|
-
}
|
|
2307
|
-
batch: { params: ["items", "preview"], description: "items (1-50, each may carry inline relations) is required." }
|
|
1812
|
+
}
|
|
2308
1813
|
};
|
|
2309
1814
|
function registerSmartCaptureTools(server) {
|
|
2310
1815
|
const captureHandlers = {
|
|
2311
|
-
capture: (data) => handleCapture(server, data)
|
|
2312
|
-
batch: (data) => handleBatchCapture(server, { entries: data.items, preview: data.preview })
|
|
1816
|
+
capture: (data) => handleCapture(server, data)
|
|
2313
1817
|
};
|
|
2314
1818
|
server.registerTool(
|
|
2315
1819
|
"capture",
|
|
2316
1820
|
{
|
|
2317
1821
|
title: "Capture",
|
|
2318
|
-
description: "The tool for creating
|
|
1822
|
+
description: "The tool for creating a single knowledge entry. Creates an entry, auto-links related entries, and returns a quality scorecard \u2014 all in one call. Provide a name and description; `collection` is optional \u2014 the classifier auto-routes when omitted. An agent capturing several atoms from one text calls this once per atom.\n\nSupported collections with smart profiles: tensions, business-rules, glossary, decisions, features, audiences, strategy, standards, chains, insights, principles.\nAll other collections get an ENT-{random} ID and sensible defaults.\n\n**Explicit data:** When you know the schema, pass `data: { field: value }` to set fields directly. Top-level `name` and `description` always win for those fields. `data` wins over inference for all other fields.\n\n**Compound capture:** Pass `links` to create relations in the same call (skips auto-link discovery). Entries are always created as `draft` \u2014 use `entries action=commit` to promote when ready.",
|
|
2319
1823
|
inputSchema: captureCompoundSchema,
|
|
2320
1824
|
annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false }
|
|
2321
1825
|
},
|
|
@@ -3168,633 +2672,6 @@ Use \`entries action=get\` to inspect the existing entry, or \`entries action=up
|
|
|
3168
2672
|
};
|
|
3169
2673
|
return toolResult;
|
|
3170
2674
|
}
|
|
3171
|
-
async function handleBatchCapture(server, { entries, preview }) {
|
|
3172
|
-
requireWriteAccess();
|
|
3173
|
-
const batchTimingStart = Date.now();
|
|
3174
|
-
const agentId = getAgentSessionId();
|
|
3175
|
-
const createdBy = agentId ? `agent:${agentId}` : "capture";
|
|
3176
|
-
const wsCtx = await getWorkspaceContext();
|
|
3177
|
-
let autoCommitApplied = false;
|
|
3178
|
-
const needsClassification = entries.map((e, i) => ({ ...e, index: i })).filter((e) => !e.collection);
|
|
3179
|
-
let classificationMap = /* @__PURE__ */ new Map();
|
|
3180
|
-
if (needsClassification.length > 0) {
|
|
3181
|
-
await server.sendLoggingMessage({
|
|
3182
|
-
level: "info",
|
|
3183
|
-
data: `Classifying ${needsClassification.length}/${entries.length} entries via LLM...`,
|
|
3184
|
-
logger: "product-brain"
|
|
3185
|
-
});
|
|
3186
|
-
const classifications = await Promise.all(
|
|
3187
|
-
needsClassification.map(
|
|
3188
|
-
(e) => resolveCollection({ name: e.name, description: e.description }).catch(() => null)
|
|
3189
|
-
)
|
|
3190
|
-
);
|
|
3191
|
-
for (let i = 0; i < needsClassification.length; i++) {
|
|
3192
|
-
classificationMap.set(needsClassification[i].index, classifications[i]);
|
|
3193
|
-
}
|
|
3194
|
-
}
|
|
3195
|
-
const results = [];
|
|
3196
|
-
const previewDupTracker = createBatchPreviewDuplicateTracker();
|
|
3197
|
-
const skippedLowConfidence = [];
|
|
3198
|
-
await server.sendLoggingMessage({
|
|
3199
|
-
level: "info",
|
|
3200
|
-
data: `Batch capturing ${entries.length} entries...`,
|
|
3201
|
-
logger: "product-brain"
|
|
3202
|
-
});
|
|
3203
|
-
const allCollections = await getCollections();
|
|
3204
|
-
const hubSlugs = await populateHubCache();
|
|
3205
|
-
const collCache = /* @__PURE__ */ new Map();
|
|
3206
|
-
for (const c of allCollections) collCache.set(c.slug, c);
|
|
3207
|
-
const collIdToSlug = /* @__PURE__ */ new Map();
|
|
3208
|
-
for (const c of allCollections) collIdToSlug.set(c._id, c.slug);
|
|
3209
|
-
async function flushPendingChunk(chunk) {
|
|
3210
|
-
if (chunk.length === 0) return;
|
|
3211
|
-
const jobsToScore = chunk.filter((p) => p.job !== null).map((p) => p.job);
|
|
3212
|
-
let scoreResultsByJob = [];
|
|
3213
|
-
if (jobsToScore.length > 0) {
|
|
3214
|
-
try {
|
|
3215
|
-
scoreResultsByJob = await kernelQuery("chain.scoreLinkCandidates", {
|
|
3216
|
-
collMap: Object.fromEntries(collIdToSlug),
|
|
3217
|
-
hubSlugs: [...hubSlugs],
|
|
3218
|
-
jobs: jobsToScore
|
|
3219
|
-
});
|
|
3220
|
-
} catch {
|
|
3221
|
-
scoreResultsByJob = jobsToScore.map(() => []);
|
|
3222
|
-
}
|
|
3223
|
-
}
|
|
3224
|
-
let scoreCursor = 0;
|
|
3225
|
-
for (const pending of chunk) {
|
|
3226
|
-
const scores = pending.job !== null ? scoreResultsByJob[scoreCursor++] ?? [] : [];
|
|
3227
|
-
try {
|
|
3228
|
-
await pending.finish(scores);
|
|
3229
|
-
} catch (error) {
|
|
3230
|
-
const msg = error instanceof Error ? error.message : String(error);
|
|
3231
|
-
results.push(buildBatchEntryFailure({
|
|
3232
|
-
entryIdx: pending.entryIdx,
|
|
3233
|
-
name: pending.entry.name,
|
|
3234
|
-
collection: pending.resolvedSlug,
|
|
3235
|
-
classifiedBy: pending.classifiedBy,
|
|
3236
|
-
confidence: pending.confidence,
|
|
3237
|
-
confidenceTier: pending.confidenceTier,
|
|
3238
|
-
error: msg
|
|
3239
|
-
}));
|
|
3240
|
-
}
|
|
3241
|
-
}
|
|
3242
|
-
}
|
|
3243
|
-
let pendingFinish = [];
|
|
3244
|
-
let chunkBytes = 0;
|
|
3245
|
-
for (let entryIdx = 0; entryIdx < entries.length; entryIdx++) {
|
|
3246
|
-
const entry = entries[entryIdx];
|
|
3247
|
-
if (entryIdx > 0 && entryIdx % 5 === 0) {
|
|
3248
|
-
await server.sendLoggingMessage({
|
|
3249
|
-
level: "info",
|
|
3250
|
-
data: `Captured ${entryIdx}/${entries.length} entries...`,
|
|
3251
|
-
logger: "product-brain"
|
|
3252
|
-
});
|
|
3253
|
-
}
|
|
3254
|
-
let resolvedSlug = entry.collection;
|
|
3255
|
-
let classifiedBy;
|
|
3256
|
-
let confidence;
|
|
3257
|
-
let confidenceTier;
|
|
3258
|
-
if (resolvedSlug) {
|
|
3259
|
-
classifiedBy = "explicit";
|
|
3260
|
-
} else {
|
|
3261
|
-
const resolved = classificationMap.get(entryIdx);
|
|
3262
|
-
if (resolved) {
|
|
3263
|
-
emitClassificationTelemetry(resolved, wsCtx.workspaceId, {
|
|
3264
|
-
explicitCollectionProvided: false,
|
|
3265
|
-
autoRouted: resolved.tier !== "low"
|
|
3266
|
-
});
|
|
3267
|
-
}
|
|
3268
|
-
if (!resolved || resolved.tier === "low") {
|
|
3269
|
-
skippedLowConfidence.push({
|
|
3270
|
-
index: entryIdx,
|
|
3271
|
-
name: entry.name,
|
|
3272
|
-
suggestedCollection: resolved?.collection,
|
|
3273
|
-
confidence: resolved?.confidence,
|
|
3274
|
-
alternatives: resolved?.alternatives.slice(0, 3)
|
|
3275
|
-
});
|
|
3276
|
-
continue;
|
|
3277
|
-
}
|
|
3278
|
-
resolvedSlug = resolved.collection;
|
|
3279
|
-
classifiedBy = resolved.classifiedBy;
|
|
3280
|
-
confidence = resolved.confidence;
|
|
3281
|
-
confidenceTier = resolved.tier;
|
|
3282
|
-
}
|
|
3283
|
-
const profile = await getProfile(resolvedSlug);
|
|
3284
|
-
const col = collCache.get(resolvedSlug);
|
|
3285
|
-
if (!col) {
|
|
3286
|
-
results.push(buildBatchEntryFailure({
|
|
3287
|
-
entryIdx,
|
|
3288
|
-
name: entry.name,
|
|
3289
|
-
collection: resolvedSlug,
|
|
3290
|
-
classifiedBy,
|
|
3291
|
-
confidence,
|
|
3292
|
-
confidenceTier,
|
|
3293
|
-
error: `Collection "${resolvedSlug}" not found`
|
|
3294
|
-
}));
|
|
3295
|
-
continue;
|
|
3296
|
-
}
|
|
3297
|
-
if (entry.entryId && resolvedSlug !== "business-rules" && resolvedSlug !== "standards") {
|
|
3298
|
-
results.push(buildBatchEntryFailure({
|
|
3299
|
-
entryIdx,
|
|
3300
|
-
name: entry.name,
|
|
3301
|
-
collection: resolvedSlug,
|
|
3302
|
-
classifiedBy,
|
|
3303
|
-
confidence,
|
|
3304
|
-
confidenceTier,
|
|
3305
|
-
// BR-111
|
|
3306
|
-
error: `entryId only allowed for business-rules and standards. Omit for ${resolvedSlug}.`
|
|
3307
|
-
}));
|
|
3308
|
-
continue;
|
|
3309
|
-
}
|
|
3310
|
-
const data = buildDataFromFields(col.fields ?? [], profile.descriptionField, entry.description);
|
|
3311
|
-
for (const def of profile.defaults) {
|
|
3312
|
-
if (def.value !== "infer" && def.value !== "today") data[def.key] = def.value;
|
|
3313
|
-
}
|
|
3314
|
-
if (profile.inferField) {
|
|
3315
|
-
const inferred = profile.inferField({
|
|
3316
|
-
collection: resolvedSlug,
|
|
3317
|
-
name: entry.name,
|
|
3318
|
-
description: entry.description,
|
|
3319
|
-
data,
|
|
3320
|
-
entryId: "",
|
|
3321
|
-
linksCreated: [],
|
|
3322
|
-
linksSuggested: [],
|
|
3323
|
-
collectionFields: col.fields ?? []
|
|
3324
|
-
});
|
|
3325
|
-
for (const [key, val] of Object.entries(inferred)) {
|
|
3326
|
-
if (val !== void 0 && val !== "") data[key] = val;
|
|
3327
|
-
}
|
|
3328
|
-
}
|
|
3329
|
-
if (isEmptyValue(data.date)) {
|
|
3330
|
-
const inferredSourceDate = inferSourceDate(entry.name, entry.description);
|
|
3331
|
-
if (inferredSourceDate && (col.fields ?? []).some((field) => field.key === "date")) {
|
|
3332
|
-
data.date = inferredSourceDate;
|
|
3333
|
-
}
|
|
3334
|
-
}
|
|
3335
|
-
if (!data[profile.descriptionField] && !data.description && !data.canonical) {
|
|
3336
|
-
data[profile.descriptionField || "description"] = entry.description;
|
|
3337
|
-
}
|
|
3338
|
-
if (entry.data && typeof entry.data === "object") {
|
|
3339
|
-
for (const [k, v] of Object.entries(entry.data)) {
|
|
3340
|
-
if (v !== void 0 && v !== null && v !== "") data[k] = v;
|
|
3341
|
-
}
|
|
3342
|
-
}
|
|
3343
|
-
const batchIsBet = resolvedSlug === "work-packages" || entry.canonicalKey === "work_package";
|
|
3344
|
-
const batchIsStrategy = col?.thinkingLayer === "strategy";
|
|
3345
|
-
const shouldDecomposeBatch = (batchIsStrategy || batchIsBet) && entry.description?.trim();
|
|
3346
|
-
let batchDecomposeWarning;
|
|
3347
|
-
if (shouldDecomposeBatch) {
|
|
3348
|
-
try {
|
|
3349
|
-
const decomposed = await kernelCall(
|
|
3350
|
-
"chain.decomposeContent",
|
|
3351
|
-
{
|
|
3352
|
-
collectionSlug: resolvedSlug,
|
|
3353
|
-
entryName: entry.name,
|
|
3354
|
-
description: entry.description,
|
|
3355
|
-
existingData: data,
|
|
3356
|
-
...batchIsBet ? { canonicalKey: "work_package" } : {},
|
|
3357
|
-
...col?.thinkingLayer ? { thinkingLayer: col.thinkingLayer } : {}
|
|
3358
|
-
}
|
|
3359
|
-
);
|
|
3360
|
-
if (decomposed?.decomposed) {
|
|
3361
|
-
for (const [key, val] of Object.entries(decomposed.decomposed)) {
|
|
3362
|
-
if (isEmptyValue(data[key]) && isNonEmptyValue(val)) {
|
|
3363
|
-
data[key] = val;
|
|
3364
|
-
}
|
|
3365
|
-
}
|
|
3366
|
-
}
|
|
3367
|
-
} catch {
|
|
3368
|
-
batchDecomposeWarning = "Content decomposition skipped (transient error). Entry saved with description only.";
|
|
3369
|
-
}
|
|
3370
|
-
}
|
|
3371
|
-
canonicalizeSelects(data, col.fields ?? [], batchIsBet);
|
|
3372
|
-
const previewDuplicate = checkBatchPreviewDuplicate(previewDupTracker, {
|
|
3373
|
-
preview,
|
|
3374
|
-
entryIdx,
|
|
3375
|
-
name: entry.name,
|
|
3376
|
-
collection: resolvedSlug,
|
|
3377
|
-
callerEntryId: entry.entryId,
|
|
3378
|
-
classifiedBy,
|
|
3379
|
-
confidence,
|
|
3380
|
-
confidenceTier
|
|
3381
|
-
});
|
|
3382
|
-
if (previewDuplicate) {
|
|
3383
|
-
results.push(previewDuplicate);
|
|
3384
|
-
continue;
|
|
3385
|
-
}
|
|
3386
|
-
try {
|
|
3387
|
-
const rawResult = await kernelMutation("chain.createEntry", {
|
|
3388
|
-
collectionSlug: resolvedSlug,
|
|
3389
|
-
entryId: entry.entryId ?? void 0,
|
|
3390
|
-
name: entry.name,
|
|
3391
|
-
// DEC-896 / BR-76: omit status — server resolves from governanceMode (Open→active, else draft).
|
|
3392
|
-
data,
|
|
3393
|
-
createdBy,
|
|
3394
|
-
sessionId: agentId ?? void 0,
|
|
3395
|
-
canonicalKey: entry.canonicalKey ?? void 0,
|
|
3396
|
-
// BR-76 S2: Distinguish batch provenance in retrospective metrics (path a).
|
|
3397
|
-
originDetailOverride: "mcp-batch-capture",
|
|
3398
|
-
...entry.sourceRef ? { sourceRef: entry.sourceRef } : {},
|
|
3399
|
-
...entry.sourceExcerpt ? { sourceExcerpt: entry.sourceExcerpt } : {},
|
|
3400
|
-
...preview ? { preview: true } : {},
|
|
3401
|
-
// WP-513: explicit rung-2 owner override. WP-753 O1b: team derives server-side.
|
|
3402
|
-
...entry.ownerRoleEntryId ? { ownerRoleEntryId: entry.ownerRoleEntryId } : {}
|
|
3403
|
-
});
|
|
3404
|
-
const preflight = isPreviewCreateEntryResult(rawResult) ? await resolvePreviewPreflight(rawResult, entry.relations) : void 0;
|
|
3405
|
-
const previewWouldBlock = extractPreviewWouldBlock(rawResult, preview);
|
|
3406
|
-
const effectiveCollection = resolveEffectiveCollection(rawResult, preview, resolvedSlug);
|
|
3407
|
-
const result2 = rawResult;
|
|
3408
|
-
const postRoutingDuplicate = reconcileBatchPreviewDuplicate(previewDupTracker, {
|
|
3409
|
-
wouldCapture: Boolean(preview && previewWouldBlock && !previewWouldBlock.wouldBlock),
|
|
3410
|
-
effectiveCollection,
|
|
3411
|
-
entryIdx,
|
|
3412
|
-
name: entry.name,
|
|
3413
|
-
callerEntryId: entry.entryId,
|
|
3414
|
-
classifiedBy,
|
|
3415
|
-
confidence,
|
|
3416
|
-
confidenceTier
|
|
3417
|
-
});
|
|
3418
|
-
if (postRoutingDuplicate) {
|
|
3419
|
-
results.push(postRoutingDuplicate);
|
|
3420
|
-
continue;
|
|
3421
|
-
}
|
|
3422
|
-
const internalId = result2.docId;
|
|
3423
|
-
const finalEntryId = result2.entryId;
|
|
3424
|
-
const batchEntryWarnings = [
|
|
3425
|
-
...batchDecomposeWarning ? [batchDecomposeWarning] : [],
|
|
3426
|
-
...result2.warnings ?? []
|
|
3427
|
-
];
|
|
3428
|
-
if (!preview) resolveGapsForEntry(entry.name, result2.entryId);
|
|
3429
|
-
const batchWasAutoCommittedServerSide = result2.status === "active";
|
|
3430
|
-
const batchSpineFloor = result2.spineFloor;
|
|
3431
|
-
const finalStatus = batchWasAutoCommittedServerSide ? "committed" : batchSpineFloor ? "draft_spine_floor" : "draft";
|
|
3432
|
-
if (batchWasAutoCommittedServerSide) {
|
|
3433
|
-
if (!preview) autoCommitApplied = true;
|
|
3434
|
-
await recordSessionActivity({ entryModified: internalId });
|
|
3435
|
-
trackChainEntryCommitted(wsCtx.workspaceId, {
|
|
3436
|
-
entry_id: finalEntryId,
|
|
3437
|
-
collection: resolvedSlug ?? void 0,
|
|
3438
|
-
commit_method: "auto",
|
|
3439
|
-
surface: "mcp_capture"
|
|
3440
|
-
});
|
|
3441
|
-
}
|
|
3442
|
-
let candidatesFiltered = [];
|
|
3443
|
-
let job = null;
|
|
3444
|
-
const searchQuery = extractSearchTerms(entry.name, entry.description);
|
|
3445
|
-
if (searchQuery) {
|
|
3446
|
-
try {
|
|
3447
|
-
const searchResults = await kernelQuery("chain.searchEntries", { query: searchQuery });
|
|
3448
|
-
candidatesFiltered = (searchResults ?? []).filter((r) => r.entryId !== finalEntryId).map((r) => ({
|
|
3449
|
-
name: r.name,
|
|
3450
|
-
entryId: r.entryId,
|
|
3451
|
-
collectionId: r.collectionId
|
|
3452
|
-
}));
|
|
3453
|
-
if (candidatesFiltered.length > 0) {
|
|
3454
|
-
job = buildScoreLinkCandidatesJob(
|
|
3455
|
-
candidatesFiltered.map((r) => ({ name: r.name, collectionId: r.collectionId })),
|
|
3456
|
-
entry.name,
|
|
3457
|
-
entry.description,
|
|
3458
|
-
resolvedSlug
|
|
3459
|
-
);
|
|
3460
|
-
}
|
|
3461
|
-
} catch {
|
|
3462
|
-
}
|
|
3463
|
-
}
|
|
3464
|
-
const prospectiveJobBytes = job ? estimateJobBytes(job) : 0;
|
|
3465
|
-
if (pendingFinish.length > 0 && (pendingFinish.length >= LINK_SCORE_CHUNK_MAX_ENTRIES || chunkBytes + prospectiveJobBytes > LINK_SCORE_CHUNK_MAX_BYTES)) {
|
|
3466
|
-
await flushPendingChunk(pendingFinish);
|
|
3467
|
-
pendingFinish = [];
|
|
3468
|
-
chunkBytes = 0;
|
|
3469
|
-
}
|
|
3470
|
-
pendingFinish.push({
|
|
3471
|
-
entryIdx,
|
|
3472
|
-
entry,
|
|
3473
|
-
resolvedSlug,
|
|
3474
|
-
classifiedBy,
|
|
3475
|
-
confidence,
|
|
3476
|
-
confidenceTier,
|
|
3477
|
-
job,
|
|
3478
|
-
finish: async (scores) => {
|
|
3479
|
-
let autoLinkCount = 0;
|
|
3480
|
-
let advisedLinkCount = 0;
|
|
3481
|
-
let entryOverlapCount = 0;
|
|
3482
|
-
if (candidatesFiltered.length > 0) {
|
|
3483
|
-
try {
|
|
3484
|
-
const candidates = scores.map((s) => {
|
|
3485
|
-
const r = candidatesFiltered[s.index];
|
|
3486
|
-
return { ...r, collSlug: collIdToSlug.get(r.collectionId) ?? "unknown", confidence: s.score };
|
|
3487
|
-
});
|
|
3488
|
-
entryOverlapCount = candidates.filter((c) => c.entryId).length;
|
|
3489
|
-
const batchAutoLinks = [];
|
|
3490
|
-
for (const c of candidates) {
|
|
3491
|
-
if (batchAutoLinks.length >= MAX_AUTO_LINKS) break;
|
|
3492
|
-
if (c.confidence < AUTO_LINK_CONFIDENCE_THRESHOLD) break;
|
|
3493
|
-
if (!c.entryId) continue;
|
|
3494
|
-
const { type: relationType } = inferRelationType(resolvedSlug, c.collSlug, profile);
|
|
3495
|
-
batchAutoLinks.push({ fromEntryId: finalEntryId, toEntryId: c.entryId, type: relationType, proposedBy: "auto-link", confidence: c.confidence });
|
|
3496
|
-
}
|
|
3497
|
-
if (batchAutoLinks.length > 0 && preview) {
|
|
3498
|
-
batchEntryWarnings.push(`${batchAutoLinks.length} auto-link(s) would be created (preview \u2014 no DB writes).`);
|
|
3499
|
-
} else if (batchAutoLinks.length > 0) {
|
|
3500
|
-
const batchRes = await kernelMutation("chain.createEntryRelations", {
|
|
3501
|
-
relations: batchAutoLinks,
|
|
3502
|
-
sessionId: agentId ?? void 0
|
|
3503
|
-
});
|
|
3504
|
-
autoLinkCount = batchRes.created;
|
|
3505
|
-
advisedLinkCount = batchRes.advised ?? 0;
|
|
3506
|
-
if (advisedLinkCount > 0) {
|
|
3507
|
-
batchEntryWarnings.push(`${advisedLinkCount} auto-link(s) advised, not written (untypeable) \u2014 accept with \`relations action=create\` to promote.`);
|
|
3508
|
-
}
|
|
3509
|
-
}
|
|
3510
|
-
} catch {
|
|
3511
|
-
}
|
|
3512
|
-
}
|
|
3513
|
-
const {
|
|
3514
|
-
relationsCreatedCount,
|
|
3515
|
-
relationsProposedCount,
|
|
3516
|
-
relationsNotValidatedCount,
|
|
3517
|
-
relationsFailedList
|
|
3518
|
-
} = await applyBatchInlineRelations(entry.relations, finalEntryId, preview, agentId);
|
|
3519
|
-
if (relationsFailedList.length > 0) {
|
|
3520
|
-
batchEntryWarnings.push(`${relationsFailedList.length} inline relation(s) failed: ${relationsFailedList.join("; ")}`);
|
|
3521
|
-
}
|
|
3522
|
-
if (relationsNotValidatedCount > 0) {
|
|
3523
|
-
batchEntryWarnings.push(`${relationsNotValidatedCount} inline relation(s) not validated in preview (target existence and relation policy are checked at capture).`);
|
|
3524
|
-
}
|
|
3525
|
-
if (relationsProposedCount > 0) {
|
|
3526
|
-
batchEntryWarnings.push(`${relationsProposedCount} inline relation(s) converted to an agent proposal (misuse pattern) \u2014 review in Cortex UI.`);
|
|
3527
|
-
}
|
|
3528
|
-
const entryNorm = result2.normalization;
|
|
3529
|
-
results.push({
|
|
3530
|
-
entryIdx,
|
|
3531
|
-
name: entry.name,
|
|
3532
|
-
// P0 round 4 (fix 1/3, root): EFFECTIVE (post-routing) collection — see
|
|
3533
|
-
// `effectiveCollection`'s declaration above, ~2 screens up.
|
|
3534
|
-
collection: effectiveCollection,
|
|
3535
|
-
entryId: finalEntryId,
|
|
3536
|
-
ok: true,
|
|
3537
|
-
autoLinks: autoLinkCount,
|
|
3538
|
-
advisedLinks: advisedLinkCount,
|
|
3539
|
-
status: finalStatus,
|
|
3540
|
-
classifiedBy,
|
|
3541
|
-
confidence,
|
|
3542
|
-
confidenceTier,
|
|
3543
|
-
...previewWouldBlock ? { wouldBlock: previewWouldBlock.wouldBlock } : {},
|
|
3544
|
-
...preflight ? { preflight } : {},
|
|
3545
|
-
...previewWouldBlock?.blockingReason ? { blockingReason: previewWouldBlock.blockingReason } : {},
|
|
3546
|
-
// Fix 1 (TEN-2918 follow-up): not caller-supplied — the preview projection
|
|
3547
|
-
// must not report this predicted-but-duplicable ID as concrete.
|
|
3548
|
-
...!entry.entryId ? { entryIdAssignedAtCapture: true } : {},
|
|
3549
|
-
...batchSpineFloor ? { spineFloor: batchSpineFloor } : {},
|
|
3550
|
-
// WP-745 TASK-160: read by the render below.
|
|
3551
|
-
...batchEntryWarnings.length > 0 ? { warnings: batchEntryWarnings } : {},
|
|
3552
|
-
...entryNorm && (Object.keys(entryNorm.remapped).length > 0 || entryNorm.rejected.length > 0) && {
|
|
3553
|
-
normalization: { remapped: entryNorm.remapped, rejected: entryNorm.rejected }
|
|
3554
|
-
},
|
|
3555
|
-
// BET-167: Track overlap count for conflict advisory
|
|
3556
|
-
...entryOverlapCount > 0 ? { overlapCount: entryOverlapCount } : {},
|
|
3557
|
-
// TEN-957 (WP-484 S2): inline relations created for this entry.
|
|
3558
|
-
...relationsCreatedCount > 0 ? { relationsCreated: relationsCreatedCount } : {},
|
|
3559
|
-
// Finding #14: distinct from relationsCreated — never counted as a write.
|
|
3560
|
-
...relationsProposedCount > 0 ? { relationsProposed: relationsProposedCount } : {}
|
|
3561
|
-
});
|
|
3562
|
-
}
|
|
3563
|
-
});
|
|
3564
|
-
if (job) chunkBytes += prospectiveJobBytes;
|
|
3565
|
-
} catch (error) {
|
|
3566
|
-
results.push(buildBatchEntryFailure({
|
|
3567
|
-
entryIdx,
|
|
3568
|
-
name: entry.name,
|
|
3569
|
-
collection: resolvedSlug,
|
|
3570
|
-
classifiedBy,
|
|
3571
|
-
confidence,
|
|
3572
|
-
confidenceTier,
|
|
3573
|
-
...describeBatchEntryOutcome(error, entry.name)
|
|
3574
|
-
// WP-575 review (P1, TEN-1126) — see lib/batchTimeoutCohort.ts.
|
|
3575
|
-
}));
|
|
3576
|
-
}
|
|
3577
|
-
}
|
|
3578
|
-
await flushPendingChunk(pendingFinish);
|
|
3579
|
-
const created = results.filter((r) => r.ok);
|
|
3580
|
-
const { failed, unknownOutcome: unknownOutcomeEntries } = splitBatchNotOk(results.filter((r) => !r.ok));
|
|
3581
|
-
const committed = created.filter((r) => r.status === "committed");
|
|
3582
|
-
const proposed = created.filter((r) => r.status === "proposed");
|
|
3583
|
-
const drafts = created.filter((r) => r.status === "draft");
|
|
3584
|
-
const commitFailed = created.filter((r) => r.status === "draft_on_failure");
|
|
3585
|
-
const spineFloored = created.filter((r) => r.status === "draft_spine_floor");
|
|
3586
|
-
const classifiedCount = created.filter((r) => r.classifiedBy && r.classifiedBy !== "explicit").length;
|
|
3587
|
-
await server.sendLoggingMessage({
|
|
3588
|
-
level: "info",
|
|
3589
|
-
data: `Batch complete. ${created.length} succeeded, ${failed.length} failed, ${skippedLowConfidence.length} skipped (low confidence).`,
|
|
3590
|
-
logger: "product-brain"
|
|
3591
|
-
});
|
|
3592
|
-
if (preview) {
|
|
3593
|
-
return buildBatchPreviewFromResults(created, failed, skippedLowConfidence, entries.length, entries);
|
|
3594
|
-
}
|
|
3595
|
-
const totalAutoLinks = created.reduce((sum, r) => sum + r.autoLinks, 0);
|
|
3596
|
-
const totalAdvisedLinks = created.reduce((sum, r) => sum + r.advisedLinks, 0);
|
|
3597
|
-
const byCollection = /* @__PURE__ */ new Map();
|
|
3598
|
-
for (const r of created) {
|
|
3599
|
-
byCollection.set(r.collection, (byCollection.get(r.collection) ?? 0) + 1);
|
|
3600
|
-
}
|
|
3601
|
-
const lines = [
|
|
3602
|
-
`# Batch Capture Complete`,
|
|
3603
|
-
`**${created.length}** created, **${failed.length}** failed, **${skippedLowConfidence.length}** skipped out of ${entries.length} total.`,
|
|
3604
|
-
`**Auto-links created:** ${totalAutoLinks}${totalAdvisedLinks > 0 ? `, ${totalAdvisedLinks} advised` : ""}`,
|
|
3605
|
-
""
|
|
3606
|
-
];
|
|
3607
|
-
if (classifiedCount > 0) {
|
|
3608
|
-
lines.push(`**Auto-classified:** ${classifiedCount} entries routed by LLM/heuristic.`);
|
|
3609
|
-
lines.push("");
|
|
3610
|
-
}
|
|
3611
|
-
if (created.length > 0) {
|
|
3612
|
-
const commitFailedSegment = commitFailed.length > 0 ? `, ${commitFailed.length} commit-failed` : "";
|
|
3613
|
-
const spineFloorSegment = spineFloored.length > 0 ? `, ${spineFloored.length} spine-floored` : "";
|
|
3614
|
-
lines.push(
|
|
3615
|
-
`**Statuses:** ${committed.length} committed, ${proposed.length} proposed, ${drafts.length} draft${spineFloorSegment}${commitFailedSegment}.`
|
|
3616
|
-
);
|
|
3617
|
-
lines.push("");
|
|
3618
|
-
}
|
|
3619
|
-
if (byCollection.size > 0) {
|
|
3620
|
-
lines.push("## By Collection");
|
|
3621
|
-
for (const [col, count] of byCollection) {
|
|
3622
|
-
lines.push(`- \`${col}\`: ${count} entries`);
|
|
3623
|
-
}
|
|
3624
|
-
lines.push("");
|
|
3625
|
-
}
|
|
3626
|
-
if (created.length > 0) {
|
|
3627
|
-
const highConfidence = created.filter((r) => r.confidenceTier === "high" || r.classifiedBy === "explicit");
|
|
3628
|
-
const mediumConfidence = created.filter((r) => r.confidenceTier === "medium");
|
|
3629
|
-
if (highConfidence.length > 0) {
|
|
3630
|
-
lines.push("## Created \u2014 High Confidence / Explicit");
|
|
3631
|
-
for (const r of highConfidence) {
|
|
3632
|
-
const linkNote = r.autoLinks > 0 ? `, ${r.autoLinks} auto-links` : "";
|
|
3633
|
-
const classNote = r.classifiedBy !== "explicit" ? ` (${r.classifiedBy} ${r.confidence}%)` : "";
|
|
3634
|
-
lines.push(`- **${r.entryId}**: ${r.name} [${r.collection}] \u2014 \`${r.status}\`${classNote}${linkNote}`);
|
|
3635
|
-
}
|
|
3636
|
-
}
|
|
3637
|
-
if (mediumConfidence.length > 0) {
|
|
3638
|
-
lines.push("");
|
|
3639
|
-
lines.push("## Created \u2014 Medium Confidence (review recommended)");
|
|
3640
|
-
for (const r of mediumConfidence) {
|
|
3641
|
-
const linkNote = r.autoLinks > 0 ? `, ${r.autoLinks} auto-links` : "";
|
|
3642
|
-
lines.push(`- **${r.entryId}**: ${r.name} [${r.collection}] \u2014 \`${r.status}\` (${r.classifiedBy} ${r.confidence}%)${linkNote}`);
|
|
3643
|
-
}
|
|
3644
|
-
lines.push(`
|
|
3645
|
-
_Use \`entries action=move\` to correct any misclassified entries._`);
|
|
3646
|
-
}
|
|
3647
|
-
}
|
|
3648
|
-
if (skippedLowConfidence.length > 0) {
|
|
3649
|
-
lines.push("");
|
|
3650
|
-
lines.push("## Skipped \u2014 Low Confidence (needs explicit collection)");
|
|
3651
|
-
for (const s of skippedLowConfidence) {
|
|
3652
|
-
const suggestion = s.suggestedCollection ? ` \u2014 best guess: \`${s.suggestedCollection}\` (${s.confidence}%)` : " \u2014 no classification available";
|
|
3653
|
-
const alts = s.alternatives?.length ? ` | alternatives: ${s.alternatives.map((a) => `\`${a.collection}\` (${a.confidence}%)`).join(", ")}` : "";
|
|
3654
|
-
lines.push(`- **[${s.index}]** ${s.name}${suggestion}${alts}`);
|
|
3655
|
-
}
|
|
3656
|
-
lines.push("");
|
|
3657
|
-
lines.push("_Re-capture these with an explicit `collection` or use the suggested collection._");
|
|
3658
|
-
}
|
|
3659
|
-
if (spineFloored.length > 0) {
|
|
3660
|
-
lines.push("");
|
|
3661
|
-
lines.push("## Saved as draft");
|
|
3662
|
-
for (const r of spineFloored) {
|
|
3663
|
-
lines.push(`- **${r.entryId}**: ${r.name} [${r.collection}] \u2014 ${r.spineFloor.exempt ? SPINE_FLOOR_EXEMPT_SENTENCE : SPINE_FLOOR_SENTENCE} Next: \`entries action=commit entryId="${r.entryId}"\`.`);
|
|
3664
|
-
}
|
|
3665
|
-
}
|
|
3666
|
-
const entriesWithOverlaps = created.filter((r) => r.overlapCount && r.overlapCount > 0);
|
|
3667
|
-
if (entriesWithOverlaps.length > 0) {
|
|
3668
|
-
lines.push("");
|
|
3669
|
-
lines.push("## Related-entry Suggestions");
|
|
3670
|
-
lines.push(`${entriesWithOverlaps.length} ${entriesWithOverlaps.length === 1 ? "entry has" : "entries have"} link candidates. Review their relevance before linking:`);
|
|
3671
|
-
for (const r of entriesWithOverlaps) {
|
|
3672
|
-
lines.push(`- **${r.entryId}**: ${r.name} \u2014 ${r.overlapCount} link ${r.overlapCount === 1 ? "candidate" : "candidates"}`);
|
|
3673
|
-
}
|
|
3674
|
-
}
|
|
3675
|
-
const entriesWithWarnings = created.filter((r) => r.warnings && r.warnings.length > 0);
|
|
3676
|
-
if (entriesWithWarnings.length > 0) {
|
|
3677
|
-
lines.push("");
|
|
3678
|
-
lines.push("## Validation Warnings");
|
|
3679
|
-
for (const r of entriesWithWarnings) {
|
|
3680
|
-
lines.push(`- **${r.entryId}** (${r.name}): ${r.warnings.join("; ")}`);
|
|
3681
|
-
}
|
|
3682
|
-
}
|
|
3683
|
-
if (failed.length > 0) {
|
|
3684
|
-
lines.push("");
|
|
3685
|
-
lines.push("## Failed");
|
|
3686
|
-
for (const r of failed) {
|
|
3687
|
-
lines.push(`- ${r.name} [${r.collection}]: _${r.error}_`);
|
|
3688
|
-
}
|
|
3689
|
-
lines.push("");
|
|
3690
|
-
lines.push(`_If failed > 0, inspect \`failedEntries\` in the structured response and retry individually._`);
|
|
3691
|
-
}
|
|
3692
|
-
lines.push(...renderOutcomeUnknownSection(unknownOutcomeEntries));
|
|
3693
|
-
const entryIds = created.map((r) => r.entryId);
|
|
3694
|
-
if (entryIds.length > 0 || skippedLowConfidence.length > 0) {
|
|
3695
|
-
lines.push("");
|
|
3696
|
-
lines.push("## Next Steps");
|
|
3697
|
-
if (entryIds.length > 0) {
|
|
3698
|
-
lines.push(`- **Connect:** Run \`relations action=suggest\` on key entries to build the knowledge graph`);
|
|
3699
|
-
}
|
|
3700
|
-
if (drafts.length > 0) {
|
|
3701
|
-
lines.push("- **Review possibilities:** Retain useful alternatives as visible drafts. Accept only intended commitments within your role's authority. Types reserved for human acceptance require human ratification. Do not accept a draft merely to clear an advisory.");
|
|
3702
|
-
}
|
|
3703
|
-
if (skippedLowConfidence.length > 0) {
|
|
3704
|
-
lines.push(`- **Classify:** Re-capture ${skippedLowConfidence.length} skipped entries with explicit collections`);
|
|
3705
|
-
}
|
|
3706
|
-
if (entryIds.length > 0) {
|
|
3707
|
-
lines.push(`- **Quality:** Run \`quality action=check\` on individual entries to assess completeness`);
|
|
3708
|
-
}
|
|
3709
|
-
}
|
|
3710
|
-
const skippedNote = skippedLowConfidence.length > 0 ? `, ${skippedLowConfidence.length} skipped (low confidence)` : "";
|
|
3711
|
-
const classifiedNote = classifiedCount > 0 ? `, ${classifiedCount} auto-classified` : "";
|
|
3712
|
-
const commitFailedNote = commitFailed.length > 0 ? `, ${commitFailed.length} commit-failed` : "";
|
|
3713
|
-
const spineFloorNote = spineFloored.length > 0 ? `, ${spineFloored.length} spine-floored` : "";
|
|
3714
|
-
const summary = failed.length > 0 || unknownOutcomeEntries.length > 0 || skippedLowConfidence.length > 0 || commitFailed.length > 0 || spineFloored.length > 0 ? `Batch captured ${created.length}/${entries.length} entries (${failed.length} failed${unknownOutcomeSummaryNote(unknownOutcomeEntries)}${skippedNote}, ${committed.length} committed, ${proposed.length} proposed, ${drafts.length} draft${spineFloorNote}${commitFailedNote}${classifiedNote}).` : `Batch captured ${created.length} entries successfully (${committed.length} committed, ${proposed.length} proposed, ${drafts.length} draft${classifiedNote}).`;
|
|
3715
|
-
const firstDraft = drafts[0] ?? spineFloored[0] ?? commitFailed[0];
|
|
3716
|
-
const next = [];
|
|
3717
|
-
if (created.length > 0) {
|
|
3718
|
-
next.push({ tool: "relations", description: "Discover connections", parameters: { action: "suggest", entryId: created[0].entryId } });
|
|
3719
|
-
}
|
|
3720
|
-
if (firstDraft) {
|
|
3721
|
-
next.push({ tool: "entries", description: "Review first draft alternative", parameters: { action: "get", entryId: firstDraft.entryId } });
|
|
3722
|
-
next.push({ tool: "entries", description: "Accept onto Chain", parameters: { action: "commit", entryId: firstDraft.entryId } });
|
|
3723
|
-
}
|
|
3724
|
-
if (skippedLowConfidence.length > 0) {
|
|
3725
|
-
next.push({ tool: "capture", description: `Capture skipped entry with explicit collection`, parameters: { name: skippedLowConfidence[0].name, collection: skippedLowConfidence[0].suggestedCollection ?? "" } });
|
|
3726
|
-
}
|
|
3727
|
-
const batchTotalMs = Date.now() - batchTimingStart;
|
|
3728
|
-
const batchTiming = {
|
|
3729
|
-
totalMs: batchTotalMs,
|
|
3730
|
-
perEntryAvgMs: created.length > 0 ? Math.round(batchTotalMs / created.length) : 0
|
|
3731
|
-
};
|
|
3732
|
-
return {
|
|
3733
|
-
content: [{ type: "text", text: lines.join("\n") }],
|
|
3734
|
-
structuredContent: {
|
|
3735
|
-
...success(
|
|
3736
|
-
summary,
|
|
3737
|
-
{
|
|
3738
|
-
captured: created.map((r) => ({
|
|
3739
|
-
entryId: r.entryId,
|
|
3740
|
-
collection: r.collection,
|
|
3741
|
-
name: r.name,
|
|
3742
|
-
status: r.status,
|
|
3743
|
-
...r.classifiedBy ? { classifiedBy: r.classifiedBy } : {},
|
|
3744
|
-
...r.confidence != null ? { confidence: r.confidence } : {},
|
|
3745
|
-
...r.confidenceTier ? { confidenceTier: r.confidenceTier } : {},
|
|
3746
|
-
...r.warnings?.length ? { warnings: r.warnings } : {},
|
|
3747
|
-
...r.normalization ? { normalization: r.normalization } : {},
|
|
3748
|
-
// WP-751 M3a-1b (TASK-189, DEC-1700): `commitError`, `coherencyRefusal` (from
|
|
3749
|
-
// `r.commitRefusal`), and `contradictionAdvisory` are deleted — all three were
|
|
3750
|
-
// only ever populated by the client-side auto-commit attempt, deleted entirely.
|
|
3751
|
-
...r.spineFloor ? { spineFloor: r.spineFloor } : {},
|
|
3752
|
-
// WP-745 TASK-160: the projection a machine consumer receives; was human-render only (Copilot review, PR #901).
|
|
3753
|
-
// TEN-957 (WP-484 S2): inline relations created for this entry.
|
|
3754
|
-
...r.relationsCreated ? { relationsCreated: r.relationsCreated } : {},
|
|
3755
|
-
// Finding #14: proposal outcomes are distinct from writes — never folded in.
|
|
3756
|
-
...r.relationsProposed ? { relationsProposed: r.relationsProposed } : {}
|
|
3757
|
-
})),
|
|
3758
|
-
total: created.length,
|
|
3759
|
-
failed: failed.length,
|
|
3760
|
-
committed: committed.length,
|
|
3761
|
-
proposed: proposed.length,
|
|
3762
|
-
drafts: drafts.length,
|
|
3763
|
-
...commitFailed.length > 0 ? { commitFailed: commitFailed.length } : {},
|
|
3764
|
-
...spineFloored.length > 0 ? { spineFloored: spineFloored.length } : {},
|
|
3765
|
-
...classifiedCount > 0 ? { classified: classifiedCount } : {},
|
|
3766
|
-
autoCommitApplied,
|
|
3767
|
-
...skippedLowConfidence.length > 0 && {
|
|
3768
|
-
skippedLowConfidence: skippedLowConfidence.map((s) => ({
|
|
3769
|
-
index: s.index,
|
|
3770
|
-
name: s.name,
|
|
3771
|
-
...s.suggestedCollection ? { suggestedCollection: s.suggestedCollection } : {},
|
|
3772
|
-
...s.confidence != null ? { confidence: s.confidence } : {},
|
|
3773
|
-
...s.alternatives?.length ? { alternatives: s.alternatives } : {}
|
|
3774
|
-
}))
|
|
3775
|
-
},
|
|
3776
|
-
...failed.length > 0 && {
|
|
3777
|
-
// PR #392 round 2 (Codex, finding 2): `r.entryIdx` is the ORIGINAL input
|
|
3778
|
-
// position, carried explicitly since the moment each result was built —
|
|
3779
|
-
// NEVER `results.indexOf(r)` (the chunked pipeline pushes results in a
|
|
3780
|
-
// different order than `entries`' input order, so that would silently
|
|
3781
|
-
// report the wrong index for a batch with a mix of early/late failures).
|
|
3782
|
-
failedEntries: failed.map((r) => ({
|
|
3783
|
-
index: r.entryIdx,
|
|
3784
|
-
collection: r.collection,
|
|
3785
|
-
name: r.name,
|
|
3786
|
-
error: r.error ?? "unknown error"
|
|
3787
|
-
}))
|
|
3788
|
-
},
|
|
3789
|
-
...unknownOutcomeEntries.length > 0 && { unknownOutcomeEntries }
|
|
3790
|
-
// WP-575 review (P1, TEN-1126) — kept OUT of failedEntries.
|
|
3791
|
-
},
|
|
3792
|
-
next
|
|
3793
|
-
),
|
|
3794
|
-
_meta: { timing: batchTiming }
|
|
3795
|
-
}
|
|
3796
|
-
};
|
|
3797
|
-
}
|
|
3798
2675
|
async function runContradictionCheck(name, description, excludeEntryId, excludeDocId) {
|
|
3799
2676
|
const warnings = [];
|
|
3800
2677
|
try {
|
|
@@ -3861,9 +2738,9 @@ async function runConflictPreflight(name, description, collectionHint) {
|
|
|
3861
2738
|
}
|
|
3862
2739
|
|
|
3863
2740
|
// src/tools/knowledge/getHistory.ts
|
|
3864
|
-
import { z as
|
|
3865
|
-
var getHistorySchema =
|
|
3866
|
-
entryId:
|
|
2741
|
+
import { z as z5 } from "zod/v3";
|
|
2742
|
+
var getHistorySchema = z5.object({
|
|
2743
|
+
entryId: z5.string().describe("Entry ID, e.g. 'T-SUPPLIER', '<PREFIX>-<n>'")
|
|
3867
2744
|
});
|
|
3868
2745
|
async function handleGetHistory({ entryId }) {
|
|
3869
2746
|
const history = await kernelQuery("chain.listEntryHistory", { entryId });
|
|
@@ -3893,39 +2770,39 @@ ${formatted}` }],
|
|
|
3893
2770
|
}
|
|
3894
2771
|
|
|
3895
2772
|
// src/tools/knowledge.ts
|
|
3896
|
-
var updateEntrySchema =
|
|
3897
|
-
entryId:
|
|
3898
|
-
name:
|
|
2773
|
+
var updateEntrySchema = z6.object({
|
|
2774
|
+
entryId: z6.string().describe("Entry ID to update, e.g. 'T-SUPPLIER', '<PREFIX>-<n>'"),
|
|
2775
|
+
name: z6.string().optional().describe("New display name"),
|
|
3899
2776
|
// Chain-ID-leak guard (check:chain-id-leaks): the retired legacy-shim ticket number stays in
|
|
3900
2777
|
// the code comment above, never in this user-visible describe() string.
|
|
3901
|
-
status:
|
|
3902
|
-
workflowStatus:
|
|
3903
|
-
data:
|
|
3904
|
-
order:
|
|
3905
|
-
canonicalKey:
|
|
3906
|
-
autoPublish:
|
|
2778
|
+
status: z6.enum(["draft", "active", "deprecated", "archived"]).optional().describe("Lifecycle status: draft | active | deprecated | archived. Use `workflowStatus` for collection-specific workflow values \u2014 those are no longer accepted via `status`."),
|
|
2779
|
+
workflowStatus: z6.string().optional().describe("Collection workflow state. Valid values are collection-specific and server-owned \u2014 discover them via `collections action=describe` for the target collection. The server rejects invalid values and returns the valid set in the error."),
|
|
2780
|
+
data: z6.record(z6.unknown()).optional().describe("Fields to update (merged with existing data)"),
|
|
2781
|
+
order: z6.number().optional().describe("New sort order"),
|
|
2782
|
+
canonicalKey: z6.string().optional().describe("Semantic type (e.g. 'decision', 'tension'). Only changeable on draft/uncommitted entries."),
|
|
2783
|
+
autoPublish: z6.boolean().optional().default(false).describe("Accepted for backward compatibility but IGNORED \u2014 draft vs. published is decided by the entry's own accepted/active status, never by this flag. Removal tracked as a follow-up."),
|
|
3907
2784
|
// DEC-1716
|
|
3908
|
-
changeNote:
|
|
3909
|
-
sourceRef:
|
|
3910
|
-
sourceExcerpt:
|
|
2785
|
+
changeNote: z6.string().optional().describe("Strongly recommended: short human-readable rationale for WHY this change was made (e.g. 'Aligned description with F1-themed copy'). Surfaces in activity feed and pb get. If omitted, falls back to session purpose or auto-generated field summary."),
|
|
2786
|
+
sourceRef: z6.string().optional().describe("URI or path of the source document backing this entry. Write-once: can only be set if currently empty."),
|
|
2787
|
+
sourceExcerpt: z6.string().optional().describe("Verbatim excerpt from the source that backs this entry's claims. Write-once: can only be set if currently empty."),
|
|
3911
2788
|
// WP-465 slice ⑤ — relay-only (TEN-2233): validation/min-length/recording live in Convex.
|
|
3912
|
-
steeringOverrideReason:
|
|
3913
|
-
coherencyAcknowledgement:
|
|
3914
|
-
response:
|
|
3915
|
-
entryId:
|
|
3916
|
-
reason:
|
|
2789
|
+
steeringOverrideReason: z6.string().optional().describe("Typed override (\u226512 chars) that clears a steering coherency block on a misaligned governance write \u2014 always recorded with author attribution."),
|
|
2790
|
+
coherencyAcknowledgement: z6.object({
|
|
2791
|
+
response: z6.enum(["linked", "accepted-fix", "diverged"]).describe("Explicit response to an acknowledge-required coherency challenge."),
|
|
2792
|
+
entryId: z6.string().optional().describe("Authorizing entry being linked/accepted (required for 'linked' and 'accepted-fix')."),
|
|
2793
|
+
reason: z6.string().optional().describe("Divergence rationale (required for 'diverged', \u226512 chars).")
|
|
3917
2794
|
}).optional().describe("Explicit response to a coherency challenge (standard/strict workspace modes). One acknowledgement per challenge per entry per session.")
|
|
3918
2795
|
});
|
|
3919
|
-
var commitEntrySchema =
|
|
3920
|
-
entryId:
|
|
2796
|
+
var commitEntrySchema = z6.object({
|
|
2797
|
+
entryId: z6.string().describe("Entry ID to accept, e.g. 'TEN-abc123', '<PREFIX>-<n>'"),
|
|
3921
2798
|
// WP-316 S3: Preview gate — dry-run mode. Returns would-succeed result, no DB writes.
|
|
3922
|
-
preview:
|
|
2799
|
+
preview: z6.boolean().optional().describe("If true, validates the accept without writing. Returns what would happen. Default false."),
|
|
3923
2800
|
// WP-465 slice ⑤ — relay-only (TEN-2233): validation/recording live in Convex.
|
|
3924
|
-
steeringOverrideReason:
|
|
3925
|
-
coherencyAcknowledgement:
|
|
3926
|
-
response:
|
|
3927
|
-
entryId:
|
|
3928
|
-
reason:
|
|
2801
|
+
steeringOverrideReason: z6.string().optional().describe("Typed override (\u226512 chars) that clears a steering coherency block at the publish chokepoint \u2014 always recorded with author attribution."),
|
|
2802
|
+
coherencyAcknowledgement: z6.object({
|
|
2803
|
+
response: z6.enum(["linked", "accepted-fix", "diverged"]).describe("Explicit response to an acknowledge-required coherency challenge."),
|
|
2804
|
+
entryId: z6.string().optional().describe("Authorizing entry being linked/accepted (required for 'linked' and 'accepted-fix')."),
|
|
2805
|
+
reason: z6.string().optional().describe("Divergence rationale (required for 'diverged', \u226512 chars).")
|
|
3929
2806
|
}).optional().describe("Explicit response to a coherency challenge (standard/strict workspace modes).")
|
|
3930
2807
|
});
|
|
3931
2808
|
async function handleUpdateEntry({ entryId, name, status: rawStatus, workflowStatus: rawWorkflowStatus, data, order, canonicalKey, autoPublish, changeNote, sourceRef, sourceExcerpt, steeringOverrideReason, coherencyAcknowledgement }, toolName = "entries") {
|
|
@@ -4302,7 +3179,7 @@ No DB writes \u2014 call without \`preview:true\` to accept for real.` }],
|
|
|
4302
3179
|
// src/tools/verify.ts
|
|
4303
3180
|
import { existsSync as existsSync2, readFileSync } from "fs";
|
|
4304
3181
|
import { resolve as resolve2 } from "path";
|
|
4305
|
-
import { z as
|
|
3182
|
+
import { z as z7 } from "zod/v3";
|
|
4306
3183
|
|
|
4307
3184
|
// src/lib/resolve-project-root.ts
|
|
4308
3185
|
import { existsSync } from "fs";
|
|
@@ -4454,12 +3331,12 @@ function formatTrustReport(collection, entryCount, mappings, refs, fixes, mode,
|
|
|
4454
3331
|
lines.push("", "---", `_Schema: ${schemaTableCount} tables parsed from convex/schema.ts. Project root: ${projectRoot}_`);
|
|
4455
3332
|
return lines.join("\n");
|
|
4456
3333
|
}
|
|
4457
|
-
var verifySchema =
|
|
4458
|
-
collection:
|
|
4459
|
-
mode:
|
|
3334
|
+
var verifySchema = z7.object({
|
|
3335
|
+
collection: z7.string().max(200).default("glossary").describe("Collection slug to verify (default: glossary)"),
|
|
3336
|
+
mode: z7.enum(["report", "fix"]).default("report").describe("'report' = read-only trust report. 'fix' = also update drifted codeMapping statuses.")
|
|
4460
3337
|
});
|
|
4461
|
-
var verifyEntrySchema =
|
|
4462
|
-
entryId:
|
|
3338
|
+
var verifyEntrySchema = z7.object({
|
|
3339
|
+
entryId: z7.string().max(200).describe("Human entry ID (e.g. '<PREFIX>-<n>') to mark as verified")
|
|
4463
3340
|
});
|
|
4464
3341
|
async function handleVerifyChain(server, { collection, mode }) {
|
|
4465
3342
|
const projectRoot = resolveProjectRoot();
|
|
@@ -4676,14 +3553,14 @@ async function handleVerifyEntry({ entryId }) {
|
|
|
4676
3553
|
}
|
|
4677
3554
|
|
|
4678
3555
|
// src/tools/entry-move.ts
|
|
4679
|
-
import { z as
|
|
4680
|
-
var moveEntrySchema =
|
|
4681
|
-
entryId:
|
|
4682
|
-
toCollection:
|
|
3556
|
+
import { z as z8 } from "zod/v3";
|
|
3557
|
+
var moveEntrySchema = z8.object({
|
|
3558
|
+
entryId: z8.string().describe("Entry ID to move, e.g. '<PREFIX>-<n>'"),
|
|
3559
|
+
toCollection: z8.string().describe("Target collection slug, e.g. 'decisions', 'architecture'"),
|
|
4683
3560
|
// WP-707 S2 (TASK-146): optional atomic move+RETYPE — validates and persists the entry's NEW
|
|
4684
3561
|
// canonicalKey and its destination collection in the SAME write (convex/agentKnowledge/
|
|
4685
3562
|
// moveToCollectionOperation.ts round 3, DEC-1622). Omit for a plain same-kind relocation.
|
|
4686
|
-
canonicalKey:
|
|
3563
|
+
canonicalKey: z8.string().optional().describe(
|
|
4687
3564
|
"Optional: also reclassify the entry to this canonical key atomically with the move (e.g. 'decision', 'objective'). Omit for a plain relocation."
|
|
4688
3565
|
)
|
|
4689
3566
|
});
|
|
@@ -4746,7 +3623,7 @@ ${recovery}`,
|
|
|
4746
3623
|
}
|
|
4747
3624
|
|
|
4748
3625
|
// src/tools/entriesContract.ts
|
|
4749
|
-
import { z as
|
|
3626
|
+
import { z as z9 } from "zod/v3";
|
|
4750
3627
|
var ENTRIES_ACTIONS = [
|
|
4751
3628
|
"list",
|
|
4752
3629
|
"get",
|
|
@@ -4759,97 +3636,97 @@ var ENTRIES_ACTIONS = [
|
|
|
4759
3636
|
"verify",
|
|
4760
3637
|
"preflight"
|
|
4761
3638
|
];
|
|
4762
|
-
var entriesStatusFilterSchema =
|
|
4763
|
-
var coherencyAcknowledgementFlatSchema =
|
|
4764
|
-
response:
|
|
4765
|
-
entryId:
|
|
4766
|
-
reason:
|
|
3639
|
+
var entriesStatusFilterSchema = z9.union([z9.string().max(200), z9.array(z9.enum(["draft", "active", "accepted", "deprecated", "archived"])).max(5)]);
|
|
3640
|
+
var coherencyAcknowledgementFlatSchema = z9.object({
|
|
3641
|
+
response: z9.enum(["linked", "accepted-fix", "diverged"]).describe("Explicit response to an acknowledge-required coherency challenge."),
|
|
3642
|
+
entryId: z9.string().max(200).optional().describe("Authorizing entry being linked/accepted (required for 'linked' and 'accepted-fix')."),
|
|
3643
|
+
reason: z9.string().max(2e3).optional().describe("Divergence rationale (required for 'diverged', \u226512 chars).")
|
|
4767
3644
|
});
|
|
4768
|
-
var preflightLinks =
|
|
4769
|
-
var entriesSchema =
|
|
3645
|
+
var preflightLinks = z9.array(z9.object({ type: z9.string().max(200), entryId: z9.string().max(200) })).max(50).optional();
|
|
3646
|
+
var entriesSchema = z9.object({
|
|
4770
3647
|
links: preflightLinks.describe("For preflight: proposed context links; saves nothing."),
|
|
4771
|
-
action:
|
|
3648
|
+
action: z9.enum(ENTRIES_ACTIONS).describe(
|
|
4772
3649
|
"'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)."
|
|
4773
3650
|
),
|
|
4774
|
-
entryId:
|
|
3651
|
+
entryId: z9.string().max(200).optional().describe(
|
|
4775
3652
|
"Entry ID, e.g. '<PREFIX>-<n>'. Required for: get, update, commit, history, move, verify."
|
|
4776
3653
|
),
|
|
4777
|
-
entryIds:
|
|
4778
|
-
collection:
|
|
3654
|
+
entryIds: z9.array(z9.string().max(200)).min(1).max(20).optional().describe("Entry IDs for 'batch', e.g. ['TYPE-strategy', 'STR-jljeg7']"),
|
|
3655
|
+
collection: z9.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)."),
|
|
4779
3656
|
status: entriesStatusFilterSchema.optional().describe(
|
|
4780
3657
|
"For 'list': defaults to accepted entries (active/accepted); use status='draft' to discover drafts. One lifecycle value (draft|active|accepted|deprecated|archived). For 'search': one value OR an array of up to 5 (e.g. ['active','accepted']). For 'update': draft|active|deprecated|archived ONLY \u2014 'accepted' is set via 'commit', never 'update'. Workflow values use `workflowStatus` instead."
|
|
4781
3658
|
),
|
|
4782
|
-
tag:
|
|
4783
|
-
label:
|
|
4784
|
-
query:
|
|
4785
|
-
name:
|
|
4786
|
-
workflowStatus:
|
|
3659
|
+
tag: z9.string().max(200).optional().describe("For 'list': filter by internal tag."),
|
|
3660
|
+
label: z9.string().max(200).optional().describe("For 'list': filter by label slug \u2014 matches entries across all collections."),
|
|
3661
|
+
query: z9.string().min(2).max(500).optional().describe("For 'search': search text (min 2 characters)."),
|
|
3662
|
+
name: z9.string().max(500).optional().describe("For 'update': new display name."),
|
|
3663
|
+
workflowStatus: z9.string().max(200).optional().describe(
|
|
4787
3664
|
"For 'update': collection workflow state. Valid values are collection-specific and server-owned \u2014 discover via `collections action=describe`. Invalid values are rejected with the valid set."
|
|
4788
3665
|
),
|
|
4789
|
-
data:
|
|
4790
|
-
order:
|
|
4791
|
-
canonicalKey:
|
|
3666
|
+
data: z9.record(z9.unknown()).optional().describe("For 'update': fields to update (merged with existing data)."),
|
|
3667
|
+
order: z9.number().optional().describe("For 'update': new sort order."),
|
|
3668
|
+
canonicalKey: z9.string().max(200).optional().describe(
|
|
4792
3669
|
"For 'update': semantic type (e.g. 'decision', 'tension'); only changeable on draft/uncommitted entries. For 'move': optional atomic move+retype target. For 'preflight': optional semantic type to check requirements for."
|
|
4793
3670
|
),
|
|
4794
3671
|
// DEC-1716: draft vs. published is decided by the entry's own accepted/active status, never this flag.
|
|
4795
|
-
autoPublish:
|
|
3672
|
+
autoPublish: z9.boolean().optional().default(false).describe(
|
|
4796
3673
|
"For 'update': accepted for backward compatibility but IGNORED \u2014 draft vs. published is decided by the entry's own accepted/active status, never by this flag."
|
|
4797
3674
|
),
|
|
4798
|
-
changeNote:
|
|
3675
|
+
changeNote: z9.string().max(2e3).optional().describe(
|
|
4799
3676
|
"For 'update': short human-readable rationale for WHY this change was made. Surfaces in activity feed."
|
|
4800
3677
|
),
|
|
4801
|
-
sourceRef:
|
|
3678
|
+
sourceRef: z9.string().max(2e3).optional().describe(
|
|
4802
3679
|
"For 'update': URI or path of the source document backing this entry. Write-once."
|
|
4803
3680
|
),
|
|
4804
|
-
sourceExcerpt:
|
|
3681
|
+
sourceExcerpt: z9.string().max(5e3).optional().describe(
|
|
4805
3682
|
"For 'update': verbatim excerpt from the source backing this entry's claims. Write-once."
|
|
4806
3683
|
),
|
|
4807
|
-
steeringOverrideReason:
|
|
3684
|
+
steeringOverrideReason: z9.string().max(2e3).optional().describe(
|
|
4808
3685
|
"For 'update'/'commit': typed override (\u226512 chars) that clears a steering coherency block."
|
|
4809
3686
|
),
|
|
4810
3687
|
coherencyAcknowledgement: coherencyAcknowledgementFlatSchema.optional().describe(
|
|
4811
3688
|
"For 'update'/'commit': explicit response to a coherency challenge (standard/strict workspace modes)."
|
|
4812
3689
|
),
|
|
4813
|
-
preview:
|
|
3690
|
+
preview: z9.boolean().optional().describe(
|
|
4814
3691
|
"For 'commit': if true, validates the accept without writing \u2014 returns what would happen."
|
|
4815
3692
|
),
|
|
4816
|
-
toCollection:
|
|
3693
|
+
toCollection: z9.string().max(200).optional().describe("For 'move': target collection slug, e.g. 'decisions', 'architecture'.")
|
|
4817
3694
|
});
|
|
4818
|
-
var entriesListVariant =
|
|
4819
|
-
action:
|
|
4820
|
-
collection:
|
|
4821
|
-
status:
|
|
4822
|
-
tag:
|
|
4823
|
-
label:
|
|
3695
|
+
var entriesListVariant = z9.object({
|
|
3696
|
+
action: z9.literal("list"),
|
|
3697
|
+
collection: z9.string().max(200).optional(),
|
|
3698
|
+
status: z9.string().max(200).optional(),
|
|
3699
|
+
tag: z9.string().max(200).optional(),
|
|
3700
|
+
label: z9.string().max(200).optional()
|
|
4824
3701
|
});
|
|
4825
|
-
var entriesGetVariant =
|
|
4826
|
-
action:
|
|
4827
|
-
entryId:
|
|
3702
|
+
var entriesGetVariant = z9.object({
|
|
3703
|
+
action: z9.literal("get"),
|
|
3704
|
+
entryId: z9.string().max(200)
|
|
4828
3705
|
});
|
|
4829
|
-
var entriesBatchVariant =
|
|
4830
|
-
action:
|
|
4831
|
-
entryIds:
|
|
3706
|
+
var entriesBatchVariant = z9.object({
|
|
3707
|
+
action: z9.literal("batch"),
|
|
3708
|
+
entryIds: z9.array(z9.string().max(200)).min(1).max(20)
|
|
4832
3709
|
});
|
|
4833
|
-
var entriesSearchVariant =
|
|
4834
|
-
action:
|
|
4835
|
-
query:
|
|
4836
|
-
collection:
|
|
3710
|
+
var entriesSearchVariant = z9.object({
|
|
3711
|
+
action: z9.literal("search"),
|
|
3712
|
+
query: z9.string().min(2).max(500),
|
|
3713
|
+
collection: z9.string().max(200).optional(),
|
|
4837
3714
|
status: entriesStatusFilterSchema.optional()
|
|
4838
3715
|
// PR #660 R1 Zqh1K: string|array.
|
|
4839
3716
|
});
|
|
4840
|
-
var entriesUpdateVariant = updateEntrySchema.extend({ action:
|
|
4841
|
-
var entriesCommitVariant = commitEntrySchema.extend({ action:
|
|
4842
|
-
var entriesHistoryVariant = getHistorySchema.extend({ action:
|
|
4843
|
-
var entriesMoveVariant =
|
|
4844
|
-
action:
|
|
4845
|
-
entryId:
|
|
4846
|
-
toCollection:
|
|
4847
|
-
canonicalKey:
|
|
3717
|
+
var entriesUpdateVariant = updateEntrySchema.extend({ action: z9.literal("update") });
|
|
3718
|
+
var entriesCommitVariant = commitEntrySchema.extend({ action: z9.literal("commit") });
|
|
3719
|
+
var entriesHistoryVariant = getHistorySchema.extend({ action: z9.literal("history") });
|
|
3720
|
+
var entriesMoveVariant = z9.object({
|
|
3721
|
+
action: z9.literal("move"),
|
|
3722
|
+
entryId: z9.string().max(200),
|
|
3723
|
+
toCollection: z9.string().max(200),
|
|
3724
|
+
canonicalKey: z9.string().max(200).optional()
|
|
4848
3725
|
// WP-707 S2: optional atomic move+RETYPE.
|
|
4849
3726
|
});
|
|
4850
|
-
var entriesVerifyVariant = verifyEntrySchema.extend({ action:
|
|
4851
|
-
var entriesActionUnion =
|
|
4852
|
-
|
|
3727
|
+
var entriesVerifyVariant = verifyEntrySchema.extend({ action: z9.literal("verify") });
|
|
3728
|
+
var entriesActionUnion = z9.discriminatedUnion("action", [
|
|
3729
|
+
z9.object({ action: z9.literal("preflight"), collection: z9.string().max(200), canonicalKey: z9.string().max(200).optional(), links: preflightLinks }),
|
|
4853
3730
|
entriesListVariant,
|
|
4854
3731
|
entriesGetVariant,
|
|
4855
3732
|
entriesBatchVariant,
|
|
@@ -4927,15 +3804,15 @@ function renderVerificationLine(e) {
|
|
|
4927
3804
|
}
|
|
4928
3805
|
return `**Verification:** ${String(e.verificationStatus)}${who}`;
|
|
4929
3806
|
}
|
|
4930
|
-
var entriesGetOutputSchema =
|
|
4931
|
-
entryId:
|
|
4932
|
-
name:
|
|
4933
|
-
collection:
|
|
4934
|
-
status:
|
|
4935
|
-
capturedAt:
|
|
4936
|
-
origin:
|
|
4937
|
-
originDetail:
|
|
4938
|
-
verificationStatus:
|
|
3807
|
+
var entriesGetOutputSchema = z10.object({
|
|
3808
|
+
entryId: z10.string(),
|
|
3809
|
+
name: z10.string(),
|
|
3810
|
+
collection: z10.string(),
|
|
3811
|
+
status: z10.string(),
|
|
3812
|
+
capturedAt: z10.number().optional(),
|
|
3813
|
+
origin: z10.string().optional(),
|
|
3814
|
+
originDetail: z10.string().optional(),
|
|
3815
|
+
verificationStatus: z10.string().optional(),
|
|
4939
3816
|
// Attestation-model finding (PR #341 review): the server's honest verifier label and
|
|
4940
3817
|
// derived attestation strength/basis — connectors NEVER re-derive strength (spec §5),
|
|
4941
3818
|
// they only render what chain.getEntry ships. Mirrors packages/cli EntryFromApi.
|
|
@@ -4944,74 +3821,74 @@ var entriesGetOutputSchema = z12.object({
|
|
|
4944
3821
|
// attestation.ts's AttestationStrength SSOT (allowlisted in Check D —
|
|
4945
3822
|
// scripts/check-collection-ssot.mjs's CHECK_D_ALLOWLIST — with the full
|
|
4946
3823
|
// reasoning for why this can't just import that module). Update both together.
|
|
4947
|
-
verifiedBy:
|
|
4948
|
-
attestation:
|
|
4949
|
-
strength:
|
|
4950
|
-
basis:
|
|
3824
|
+
verifiedBy: z10.string().optional(),
|
|
3825
|
+
attestation: z10.object({
|
|
3826
|
+
strength: z10.enum(["human-direct", "delegated", "system", "unattested"]),
|
|
3827
|
+
basis: z10.string().optional()
|
|
4951
3828
|
}).optional(),
|
|
4952
|
-
sourceRef:
|
|
4953
|
-
sourceExcerpt:
|
|
4954
|
-
why:
|
|
3829
|
+
sourceRef: z10.string().optional(),
|
|
3830
|
+
sourceExcerpt: z10.string().optional(),
|
|
3831
|
+
why: z10.string().optional(),
|
|
4955
3832
|
// TEN-2191: quality of the captured WHY — 'rationale' | 'missing' | 'restated'.
|
|
4956
|
-
whyQuality:
|
|
4957
|
-
data:
|
|
4958
|
-
relations:
|
|
4959
|
-
entryId:
|
|
4960
|
-
name:
|
|
4961
|
-
type:
|
|
4962
|
-
direction:
|
|
4963
|
-
status:
|
|
3833
|
+
whyQuality: z10.enum(["rationale", "missing", "restated"]).optional(),
|
|
3834
|
+
data: z10.record(z10.unknown()).optional(),
|
|
3835
|
+
relations: z10.array(z10.object({
|
|
3836
|
+
entryId: z10.string().optional(),
|
|
3837
|
+
name: z10.string(),
|
|
3838
|
+
type: z10.string(),
|
|
3839
|
+
direction: z10.string(),
|
|
3840
|
+
status: z10.string().optional()
|
|
4964
3841
|
})).optional(),
|
|
4965
|
-
labels:
|
|
3842
|
+
labels: z10.array(z10.string()).optional(),
|
|
4966
3843
|
owner: ownerOutputShape.optional()
|
|
4967
3844
|
}).passthrough();
|
|
4968
|
-
var entriesListOutputSchema =
|
|
4969
|
-
entries:
|
|
4970
|
-
entryId:
|
|
4971
|
-
name:
|
|
4972
|
-
collection:
|
|
4973
|
-
status:
|
|
3845
|
+
var entriesListOutputSchema = z10.object({
|
|
3846
|
+
entries: z10.array(z10.object({
|
|
3847
|
+
entryId: z10.string(),
|
|
3848
|
+
name: z10.string(),
|
|
3849
|
+
collection: z10.string(),
|
|
3850
|
+
status: z10.string()
|
|
4974
3851
|
})),
|
|
4975
|
-
total:
|
|
3852
|
+
total: z10.number()
|
|
4976
3853
|
});
|
|
4977
|
-
var entriesSearchOutputSchema =
|
|
4978
|
-
results:
|
|
4979
|
-
entryId:
|
|
4980
|
-
name:
|
|
4981
|
-
collection:
|
|
4982
|
-
status:
|
|
4983
|
-
score:
|
|
3854
|
+
var entriesSearchOutputSchema = z10.object({
|
|
3855
|
+
results: z10.array(z10.object({
|
|
3856
|
+
entryId: z10.string(),
|
|
3857
|
+
name: z10.string(),
|
|
3858
|
+
collection: z10.string(),
|
|
3859
|
+
status: z10.string(),
|
|
3860
|
+
score: z10.number().optional()
|
|
4984
3861
|
})),
|
|
4985
|
-
total:
|
|
4986
|
-
query:
|
|
3862
|
+
total: z10.number(),
|
|
3863
|
+
query: z10.string()
|
|
4987
3864
|
});
|
|
4988
|
-
var entriesBatchOutputSchema =
|
|
4989
|
-
entries:
|
|
4990
|
-
entryId:
|
|
4991
|
-
name:
|
|
4992
|
-
collection:
|
|
4993
|
-
status:
|
|
4994
|
-
capturedAt:
|
|
4995
|
-
origin:
|
|
4996
|
-
originDetail:
|
|
4997
|
-
verificationStatus:
|
|
3865
|
+
var entriesBatchOutputSchema = z10.object({
|
|
3866
|
+
entries: z10.array(z10.object({
|
|
3867
|
+
entryId: z10.string(),
|
|
3868
|
+
name: z10.string(),
|
|
3869
|
+
collection: z10.string(),
|
|
3870
|
+
status: z10.string(),
|
|
3871
|
+
capturedAt: z10.number().optional(),
|
|
3872
|
+
origin: z10.string().optional(),
|
|
3873
|
+
originDetail: z10.string().optional(),
|
|
3874
|
+
verificationStatus: z10.string().optional(),
|
|
4998
3875
|
// Attestation-model finding (PR #341 review): mirror entriesGetOutputSchema — batch
|
|
4999
3876
|
// entries now carry the same honest verifiedBy/attestation fields. Literal set is
|
|
5000
3877
|
// the same hand-kept SSOT mirror — see entriesGetOutputSchema's attestation
|
|
5001
3878
|
// comment above for the full Check D / kernel-import reasoning.
|
|
5002
|
-
verifiedBy:
|
|
5003
|
-
attestation:
|
|
5004
|
-
strength:
|
|
5005
|
-
basis:
|
|
3879
|
+
verifiedBy: z10.string().optional(),
|
|
3880
|
+
attestation: z10.object({
|
|
3881
|
+
strength: z10.enum(["human-direct", "delegated", "system", "unattested"]),
|
|
3882
|
+
basis: z10.string().optional()
|
|
5006
3883
|
}).optional(),
|
|
5007
|
-
sourceRef:
|
|
5008
|
-
sourceExcerpt:
|
|
3884
|
+
sourceRef: z10.string().optional(),
|
|
3885
|
+
sourceExcerpt: z10.string().optional(),
|
|
5009
3886
|
// TEN-2191: mirror entriesGetOutputSchema — batch entries now carry why/whyQuality.
|
|
5010
|
-
why:
|
|
5011
|
-
whyQuality:
|
|
5012
|
-
data:
|
|
3887
|
+
why: z10.string().optional(),
|
|
3888
|
+
whyQuality: z10.enum(["rationale", "missing", "restated"]).optional(),
|
|
3889
|
+
data: z10.record(z10.unknown()).optional()
|
|
5013
3890
|
}).passthrough()),
|
|
5014
|
-
total:
|
|
3891
|
+
total: z10.number()
|
|
5015
3892
|
});
|
|
5016
3893
|
function registerEntriesTools(server) {
|
|
5017
3894
|
const entriesHandlers = {
|
|
@@ -5395,41 +4272,41 @@ ${footer}` }],
|
|
|
5395
4272
|
}
|
|
5396
4273
|
|
|
5397
4274
|
// src/tools/relations.ts
|
|
5398
|
-
import { z as
|
|
4275
|
+
import { z as z12 } from "zod/v3";
|
|
5399
4276
|
|
|
5400
4277
|
// src/tools/graph.ts
|
|
5401
|
-
import { z as
|
|
4278
|
+
import { z as z11 } from "zod/v3";
|
|
5402
4279
|
var GRAPH_ACTIONS = ["find", "suggest"];
|
|
5403
|
-
var graphSchema =
|
|
5404
|
-
action:
|
|
4280
|
+
var graphSchema = z11.object({
|
|
4281
|
+
action: z11.enum(GRAPH_ACTIONS).describe(
|
|
5405
4282
|
"'find': traverse relations from an entry (graph walk). 'suggest': discover potential connections for an entry."
|
|
5406
4283
|
),
|
|
5407
|
-
entryId:
|
|
5408
|
-
direction:
|
|
5409
|
-
limit:
|
|
5410
|
-
depth:
|
|
4284
|
+
entryId: z11.string().max(200).describe("Entry ID, e.g. '<PREFIX>-<n>'"),
|
|
4285
|
+
direction: z11.enum(["incoming", "outgoing", "both"]).default("both").optional().describe("For find: 'incoming' = what references this, 'outgoing' = what this references"),
|
|
4286
|
+
limit: z11.number().min(1).max(20).default(10).optional().describe("For suggest: max suggestions to return"),
|
|
4287
|
+
depth: z11.number().min(1).max(3).default(2).optional().describe("For suggest: graph traversal depth")
|
|
5411
4288
|
});
|
|
5412
|
-
var graphFindOutputSchema =
|
|
5413
|
-
entryId:
|
|
5414
|
-
relations:
|
|
5415
|
-
entryId:
|
|
5416
|
-
name:
|
|
5417
|
-
type:
|
|
5418
|
-
direction:
|
|
4289
|
+
var graphFindOutputSchema = z11.object({
|
|
4290
|
+
entryId: z11.string(),
|
|
4291
|
+
relations: z11.array(z11.object({
|
|
4292
|
+
entryId: z11.string().optional(),
|
|
4293
|
+
name: z11.string(),
|
|
4294
|
+
type: z11.string(),
|
|
4295
|
+
direction: z11.enum(["outgoing", "incoming"])
|
|
5419
4296
|
})),
|
|
5420
|
-
total:
|
|
4297
|
+
total: z11.number()
|
|
5421
4298
|
});
|
|
5422
|
-
var graphSuggestOutputSchema =
|
|
5423
|
-
entryId:
|
|
5424
|
-
suggestions:
|
|
5425
|
-
targetEntryId:
|
|
5426
|
-
targetName:
|
|
5427
|
-
relationType:
|
|
5428
|
-
direction:
|
|
5429
|
-
confidence:
|
|
5430
|
-
reason:
|
|
4299
|
+
var graphSuggestOutputSchema = z11.object({
|
|
4300
|
+
entryId: z11.string(),
|
|
4301
|
+
suggestions: z11.array(z11.object({
|
|
4302
|
+
targetEntryId: z11.string().optional(),
|
|
4303
|
+
targetName: z11.string(),
|
|
4304
|
+
relationType: z11.string(),
|
|
4305
|
+
direction: z11.string(),
|
|
4306
|
+
confidence: z11.number(),
|
|
4307
|
+
reason: z11.string()
|
|
5431
4308
|
})),
|
|
5432
|
-
total:
|
|
4309
|
+
total: z11.number()
|
|
5433
4310
|
});
|
|
5434
4311
|
async function handleFind(entryId, direction) {
|
|
5435
4312
|
const relations = await kernelQuery("chain.listEntryRelations", { entryId });
|
|
@@ -5620,64 +4497,64 @@ async function handleSuggest(entryId, limit, depth) {
|
|
|
5620
4497
|
|
|
5621
4498
|
// src/tools/relations.ts
|
|
5622
4499
|
var RELATIONS_ACTIONS = ["create", "batch-create", "dismiss", "delete", "find", "suggest"];
|
|
5623
|
-
var relationItemSchema =
|
|
5624
|
-
from:
|
|
5625
|
-
to:
|
|
5626
|
-
type:
|
|
4500
|
+
var relationItemSchema = z12.object({
|
|
4501
|
+
from: z12.string().max(200),
|
|
4502
|
+
to: z12.string().max(200),
|
|
4503
|
+
type: z12.string().max(200)
|
|
5627
4504
|
});
|
|
5628
|
-
var relationsSchema =
|
|
5629
|
-
action:
|
|
4505
|
+
var relationsSchema = z12.object({
|
|
4506
|
+
action: z12.enum(RELATIONS_ACTIONS).describe(
|
|
5630
4507
|
"'create': link two entries. 'batch-create': create multiple relations (validates every item before writing any). 'dismiss': record that a suggestion was not relevant. 'delete': remove a relation. 'find': traverse relations from an entry (graph walk, absorbs graph action=find). 'suggest': discover potential connections for an entry (absorbs graph action=suggest)."
|
|
5631
4508
|
),
|
|
5632
|
-
from:
|
|
5633
|
-
to:
|
|
5634
|
-
type:
|
|
5635
|
-
score:
|
|
5636
|
-
relations:
|
|
4509
|
+
from: z12.string().max(200).optional().describe("For 'create'/'dismiss'/'delete': source entry ID."),
|
|
4510
|
+
to: z12.string().max(200).optional().describe("For 'create'/'dismiss'/'delete': target entry ID."),
|
|
4511
|
+
type: z12.string().max(200).optional().describe("For 'create'/'dismiss'/'delete': relation type."),
|
|
4512
|
+
score: z12.number().optional().describe("For 'dismiss': suggestion score from action=suggest."),
|
|
4513
|
+
relations: z12.array(relationItemSchema).min(1).max(20).optional().describe("For 'batch-create': array of {from, to, type}."),
|
|
5637
4514
|
// WP-316 S3: Preview gate — dry-run mode for action=create.
|
|
5638
|
-
preview:
|
|
5639
|
-
entryId:
|
|
5640
|
-
direction:
|
|
5641
|
-
limit:
|
|
5642
|
-
depth:
|
|
4515
|
+
preview: z12.boolean().optional().describe("For 'create': if true, validates the relation without writing. Returns what would happen. Default false."),
|
|
4516
|
+
entryId: z12.string().max(200).optional().describe("For 'find'/'suggest': entry ID, e.g. '<PREFIX>-<n>'."),
|
|
4517
|
+
direction: z12.enum(["incoming", "outgoing", "both"]).optional().describe("For 'find': 'incoming' = what references this, 'outgoing' = what this references. Default 'both'."),
|
|
4518
|
+
limit: z12.number().min(1).max(20).optional().describe("For 'suggest': max suggestions to return. Default 10."),
|
|
4519
|
+
depth: z12.number().min(1).max(3).optional().describe("For 'suggest': graph traversal depth. Default 2.")
|
|
5643
4520
|
});
|
|
5644
|
-
var relationsCreateVariant =
|
|
5645
|
-
action:
|
|
5646
|
-
from:
|
|
5647
|
-
to:
|
|
5648
|
-
type:
|
|
5649
|
-
score:
|
|
5650
|
-
preview:
|
|
4521
|
+
var relationsCreateVariant = z12.object({
|
|
4522
|
+
action: z12.literal("create"),
|
|
4523
|
+
from: z12.string().max(200),
|
|
4524
|
+
to: z12.string().max(200),
|
|
4525
|
+
type: z12.string().max(200),
|
|
4526
|
+
score: z12.number().optional(),
|
|
4527
|
+
preview: z12.boolean().optional()
|
|
5651
4528
|
});
|
|
5652
|
-
var relationsBatchCreateVariant =
|
|
5653
|
-
action:
|
|
5654
|
-
relations:
|
|
4529
|
+
var relationsBatchCreateVariant = z12.object({
|
|
4530
|
+
action: z12.literal("batch-create"),
|
|
4531
|
+
relations: z12.array(relationItemSchema).min(1).max(20)
|
|
5655
4532
|
});
|
|
5656
|
-
var relationsDismissVariant =
|
|
5657
|
-
action:
|
|
5658
|
-
from:
|
|
5659
|
-
to:
|
|
5660
|
-
type:
|
|
5661
|
-
score:
|
|
4533
|
+
var relationsDismissVariant = z12.object({
|
|
4534
|
+
action: z12.literal("dismiss"),
|
|
4535
|
+
from: z12.string().max(200),
|
|
4536
|
+
to: z12.string().max(200),
|
|
4537
|
+
type: z12.string().max(200).optional(),
|
|
4538
|
+
score: z12.number().optional()
|
|
5662
4539
|
});
|
|
5663
|
-
var relationsDeleteVariant =
|
|
5664
|
-
action:
|
|
5665
|
-
from:
|
|
5666
|
-
to:
|
|
5667
|
-
type:
|
|
4540
|
+
var relationsDeleteVariant = z12.object({
|
|
4541
|
+
action: z12.literal("delete"),
|
|
4542
|
+
from: z12.string().max(200),
|
|
4543
|
+
to: z12.string().max(200),
|
|
4544
|
+
type: z12.string().max(200)
|
|
5668
4545
|
});
|
|
5669
|
-
var relationsFindVariant =
|
|
5670
|
-
action:
|
|
5671
|
-
entryId:
|
|
5672
|
-
direction:
|
|
4546
|
+
var relationsFindVariant = z12.object({
|
|
4547
|
+
action: z12.literal("find"),
|
|
4548
|
+
entryId: z12.string().max(200),
|
|
4549
|
+
direction: z12.enum(["incoming", "outgoing", "both"]).optional().default("both")
|
|
5673
4550
|
});
|
|
5674
|
-
var relationsSuggestVariant =
|
|
5675
|
-
action:
|
|
5676
|
-
entryId:
|
|
5677
|
-
limit:
|
|
5678
|
-
depth:
|
|
4551
|
+
var relationsSuggestVariant = z12.object({
|
|
4552
|
+
action: z12.literal("suggest"),
|
|
4553
|
+
entryId: z12.string().max(200),
|
|
4554
|
+
limit: z12.number().min(1).max(20).optional().default(10),
|
|
4555
|
+
depth: z12.number().min(1).max(3).optional().default(2)
|
|
5679
4556
|
});
|
|
5680
|
-
var relationsActionUnion =
|
|
4557
|
+
var relationsActionUnion = z12.discriminatedUnion("action", [
|
|
5681
4558
|
relationsCreateVariant,
|
|
5682
4559
|
relationsBatchCreateVariant,
|
|
5683
4560
|
relationsDismissVariant,
|
|
@@ -6032,19 +4909,19 @@ async function handleDelete(from, to, type) {
|
|
|
6032
4909
|
}
|
|
6033
4910
|
|
|
6034
4911
|
// src/tools/context.ts
|
|
6035
|
-
import { z as
|
|
4912
|
+
import { z as z14 } from "zod/v3";
|
|
6036
4913
|
|
|
6037
4914
|
// src/tools/documents.ts
|
|
6038
|
-
import { z as
|
|
4915
|
+
import { z as z13 } from "zod/v3";
|
|
6039
4916
|
var DOCUMENTS_ACTIONS = ["get-last-verified-brief"];
|
|
6040
|
-
var documentsSchema =
|
|
6041
|
-
action:
|
|
4917
|
+
var documentsSchema = z13.object({
|
|
4918
|
+
action: z13.enum(DOCUMENTS_ACTIONS).describe(
|
|
6042
4919
|
"'get-last-verified-brief': fetch the most recent verified brief snapshot for a (templateId, scopeKey) pair. Returns the verified summary so agents can build delta narratives ('since you last verified, X workstreams advanced')."
|
|
6043
4920
|
),
|
|
6044
|
-
templateId:
|
|
4921
|
+
templateId: z13.string().max(200).describe(
|
|
6045
4922
|
"Brief template identifier \u2014 currently 'steering-brief' is the only registered template."
|
|
6046
4923
|
),
|
|
6047
|
-
scopeKey:
|
|
4924
|
+
scopeKey: z13.string().max(200).describe(
|
|
6048
4925
|
"Canonical scope key. Use 'workspace:<workspaceId>' for the full workspace brief, or 'initiative:<INI-ID>' for an initiative-scoped brief. The same formula is applied at write time (chainwork/docKernel/scopeKey.ts), so passing the wrong shape returns exists:false."
|
|
6049
4926
|
)
|
|
6050
4927
|
});
|
|
@@ -6124,89 +5001,89 @@ function epistemicCollectionHint(collectionName) {
|
|
|
6124
5001
|
return "";
|
|
6125
5002
|
}
|
|
6126
5003
|
var CONTEXT_ACTIONS = ["gather", "build", "neighborhood", "changes", "chain", "cross-cut", "incremental", "brief", "last-verified-brief"];
|
|
6127
|
-
var contextSchema =
|
|
5004
|
+
var contextSchema = z14.object({
|
|
6128
5005
|
// provenance: neighborhood BET-142; changes/chain/cross-cut/incremental/brief BET-239 (E4, E6)
|
|
6129
|
-
action:
|
|
5006
|
+
action: z14.enum(CONTEXT_ACTIONS).describe(
|
|
6130
5007
|
"'gather': assemble knowledge context (entry graph, task auto-load, journey mode, or graph mode). 'build': structured build spec for an entry. 'neighborhood': typed graph neighborhood for an entry \u2014 blocking chain, dependencies, parent context, tensions, staleness. 'changes': entries modified and relations created since a timestamp. Requires 'since' parameter. 'chain': directed traversal along one relation type to depth 4. Requires entryId. Optional: direction, relationType, maxHops (1-4). 'cross-cut': structural aggregation \u2014 all relations of a given type grouped by source collection. Requires 'relationType' parameter. 'incremental': delta since last brief run for a skill. Requires 'skill' parameter. Returns only entries changed since the skill's last brief. 'brief': compound intelligence query. Requires 'briefType' parameter: 'steering' (changes + structure + delta + readiness), 'confidence' (changes + active bets + tensions), or 'delta' (changes + relations since timestamp). Optional 'since' for delta type. 'last-verified-brief': fetch the most recent verified brief snapshot for a (templateId, scopeKey) pair (absorbs documents action=get-last-verified-brief). Requires templateId and scopeKey."
|
|
6131
5008
|
),
|
|
6132
|
-
entryId:
|
|
6133
|
-
mapEntryId:
|
|
5009
|
+
entryId: z14.string().max(200).optional().describe("For 'build'/'neighborhood'/'chain': entry ID, e.g. '<PREFIX>-<n>'. For 'gather': optional entry ID for entry-graph mode."),
|
|
5010
|
+
mapEntryId: z14.string().max(200).optional().describe(
|
|
6134
5011
|
"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>'."
|
|
6135
5012
|
),
|
|
6136
|
-
task:
|
|
6137
|
-
since:
|
|
5013
|
+
task: z14.string().max(2e3).optional().describe("For 'gather': natural-language task description for loading task-relevant governance, binding constraints, and supporting context."),
|
|
5014
|
+
since: z14.string().max(200).optional().describe(
|
|
6138
5015
|
"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'."
|
|
6139
5016
|
),
|
|
6140
|
-
direction:
|
|
6141
|
-
relationType:
|
|
5017
|
+
direction: z14.enum(["outgoing", "incoming"]).default("outgoing").optional().describe("For 'chain' action: traversal direction. 'outgoing' follows relations from source, 'incoming' follows relations to source. Default: outgoing."),
|
|
5018
|
+
relationType: z14.string().max(200).optional().describe(
|
|
6142
5019
|
"Relation type filter. For 'chain': optional filter to traverse only this relation type. For 'cross-cut': required \u2014 scans all relations of this type across the workspace. Examples: 'part_of', 'informs', 'governs', 'blocks', 'depends_on'."
|
|
6143
5020
|
),
|
|
6144
|
-
mode:
|
|
6145
|
-
maxHops:
|
|
6146
|
-
maxResults:
|
|
6147
|
-
strategy:
|
|
6148
|
-
skill:
|
|
5021
|
+
mode: z14.enum(["search", "graph"]).default("search").optional().describe("For gather: 'search' (default) or 'graph' (enhanced with provenance paths). Ignored when mapEntryId is provided."),
|
|
5022
|
+
maxHops: z14.number().min(1).max(4).default(2).describe("Relation traversal depth (1=direct only, 2=default, 3=wide net, 4=deep chain walk)"),
|
|
5023
|
+
maxResults: z14.number().min(1).max(25).default(10).optional().describe("Max entries to return in gather task mode (default 10)"),
|
|
5024
|
+
strategy: z14.enum(["hybrid", "keyword"]).default("keyword").optional().describe("Seed strategy for task-based gather: 'keyword' (FTS only, default) or 'hybrid' (vector + FTS). Only affects task mode."),
|
|
5025
|
+
skill: z14.string().max(200).optional().describe(
|
|
6149
5026
|
"Skill name for 'incremental' action \u2014 identifies which skill's brief history to compare against. Examples: 'preflight', 'shaping', 'review'. Required when action is 'incremental'."
|
|
6150
5027
|
),
|
|
6151
|
-
briefType:
|
|
5028
|
+
briefType: z14.enum(["steering", "confidence", "delta"]).optional().describe(
|
|
6152
5029
|
"Compound query type for 'brief' action. 'steering': 7d changes + structural aggregation (part_of, depends_on, constrains) + incremental delta + workspace readiness. 'confidence': 7d changes + active bets summary + active tensions breakdown. 'delta': changes + relations since a custom timestamp (use 'since' param). Required when action is 'brief'."
|
|
6153
5030
|
),
|
|
6154
|
-
templateId:
|
|
5031
|
+
templateId: z14.string().max(200).optional().describe(
|
|
6155
5032
|
"For 'last-verified-brief': brief template identifier \u2014 currently 'steering-brief' is the only registered template."
|
|
6156
5033
|
),
|
|
6157
|
-
scopeKey:
|
|
5034
|
+
scopeKey: z14.string().max(200).optional().describe(
|
|
6158
5035
|
"For 'last-verified-brief': canonical scope key \u2014 'workspace:<workspaceId>' or 'initiative:<INI-ID>'."
|
|
6159
5036
|
)
|
|
6160
5037
|
});
|
|
6161
|
-
var contextGatherVariant =
|
|
6162
|
-
action:
|
|
6163
|
-
entryId:
|
|
6164
|
-
mapEntryId:
|
|
6165
|
-
task:
|
|
6166
|
-
mode:
|
|
6167
|
-
maxHops:
|
|
6168
|
-
maxResults:
|
|
6169
|
-
strategy:
|
|
5038
|
+
var contextGatherVariant = z14.object({
|
|
5039
|
+
action: z14.literal("gather"),
|
|
5040
|
+
entryId: z14.string().max(200).optional(),
|
|
5041
|
+
mapEntryId: z14.string().max(200).optional(),
|
|
5042
|
+
task: z14.string().max(2e3).optional(),
|
|
5043
|
+
mode: z14.enum(["search", "graph"]).optional().default("search"),
|
|
5044
|
+
maxHops: z14.number().min(1).max(4).optional().default(2),
|
|
5045
|
+
maxResults: z14.number().min(1).max(25).optional().default(10),
|
|
5046
|
+
strategy: z14.enum(["hybrid", "keyword"]).optional().default("keyword")
|
|
6170
5047
|
});
|
|
6171
|
-
var contextBuildVariant =
|
|
6172
|
-
action:
|
|
6173
|
-
entryId:
|
|
6174
|
-
maxHops:
|
|
5048
|
+
var contextBuildVariant = z14.object({
|
|
5049
|
+
action: z14.literal("build"),
|
|
5050
|
+
entryId: z14.string().max(200),
|
|
5051
|
+
maxHops: z14.number().min(1).max(4).optional().default(2)
|
|
6175
5052
|
});
|
|
6176
|
-
var contextNeighborhoodVariant =
|
|
6177
|
-
action:
|
|
6178
|
-
entryId:
|
|
5053
|
+
var contextNeighborhoodVariant = z14.object({
|
|
5054
|
+
action: z14.literal("neighborhood"),
|
|
5055
|
+
entryId: z14.string().max(200)
|
|
6179
5056
|
});
|
|
6180
|
-
var contextChangesVariant =
|
|
6181
|
-
action:
|
|
6182
|
-
since:
|
|
5057
|
+
var contextChangesVariant = z14.object({
|
|
5058
|
+
action: z14.literal("changes"),
|
|
5059
|
+
since: z14.string().max(200)
|
|
6183
5060
|
});
|
|
6184
|
-
var contextChainVariant =
|
|
6185
|
-
action:
|
|
6186
|
-
entryId:
|
|
6187
|
-
direction:
|
|
6188
|
-
maxHops:
|
|
6189
|
-
relationType:
|
|
5061
|
+
var contextChainVariant = z14.object({
|
|
5062
|
+
action: z14.literal("chain"),
|
|
5063
|
+
entryId: z14.string().max(200),
|
|
5064
|
+
direction: z14.enum(["outgoing", "incoming"]).optional().default("outgoing"),
|
|
5065
|
+
maxHops: z14.number().min(1).max(4).optional().default(2),
|
|
5066
|
+
relationType: z14.string().max(200).optional()
|
|
6190
5067
|
});
|
|
6191
|
-
var contextCrossCutVariant =
|
|
6192
|
-
action:
|
|
6193
|
-
relationType:
|
|
5068
|
+
var contextCrossCutVariant = z14.object({
|
|
5069
|
+
action: z14.literal("cross-cut"),
|
|
5070
|
+
relationType: z14.string().max(200)
|
|
6194
5071
|
});
|
|
6195
|
-
var contextIncrementalVariant =
|
|
6196
|
-
action:
|
|
6197
|
-
skill:
|
|
5072
|
+
var contextIncrementalVariant = z14.object({
|
|
5073
|
+
action: z14.literal("incremental"),
|
|
5074
|
+
skill: z14.string().max(200)
|
|
6198
5075
|
});
|
|
6199
|
-
var contextBriefVariant =
|
|
6200
|
-
action:
|
|
6201
|
-
briefType:
|
|
6202
|
-
since:
|
|
5076
|
+
var contextBriefVariant = z14.object({
|
|
5077
|
+
action: z14.literal("brief"),
|
|
5078
|
+
briefType: z14.enum(["steering", "confidence", "delta"]),
|
|
5079
|
+
since: z14.string().max(200).optional()
|
|
6203
5080
|
});
|
|
6204
|
-
var contextLastVerifiedBriefVariant =
|
|
6205
|
-
action:
|
|
6206
|
-
templateId:
|
|
6207
|
-
scopeKey:
|
|
5081
|
+
var contextLastVerifiedBriefVariant = z14.object({
|
|
5082
|
+
action: z14.literal("last-verified-brief"),
|
|
5083
|
+
templateId: z14.string().max(200),
|
|
5084
|
+
scopeKey: z14.string().max(200)
|
|
6208
5085
|
});
|
|
6209
|
-
var contextActionUnion =
|
|
5086
|
+
var contextActionUnion = z14.discriminatedUnion("action", [
|
|
6210
5087
|
contextGatherVariant,
|
|
6211
5088
|
contextBuildVariant,
|
|
6212
5089
|
contextNeighborhoodVariant,
|
|
@@ -7248,20 +6125,20 @@ function formatTimeAgo(ms) {
|
|
|
7248
6125
|
}
|
|
7249
6126
|
|
|
7250
6127
|
// src/tools/collections.ts
|
|
7251
|
-
import { z as
|
|
6128
|
+
import { z as z16 } from "zod/v3";
|
|
7252
6129
|
|
|
7253
6130
|
// src/tools/labels.ts
|
|
7254
|
-
import { z as
|
|
7255
|
-
var labelsSchema =
|
|
7256
|
-
action:
|
|
7257
|
-
slug:
|
|
7258
|
-
name:
|
|
7259
|
-
color:
|
|
7260
|
-
description:
|
|
7261
|
-
parentSlug:
|
|
7262
|
-
isGroup:
|
|
7263
|
-
order:
|
|
7264
|
-
entryId:
|
|
6131
|
+
import { z as z15 } from "zod/v3";
|
|
6132
|
+
var labelsSchema = z15.object({
|
|
6133
|
+
action: z15.enum(["list", "create", "update", "delete", "apply", "remove"]).describe("Action: list all labels, create/update/delete a label, or apply/remove a label on an entry"),
|
|
6134
|
+
slug: z15.string().max(200).optional().describe("Label slug (required for create/update/delete/apply/remove)"),
|
|
6135
|
+
name: z15.string().max(500).optional().describe("Display name (required for create)"),
|
|
6136
|
+
color: z15.string().max(50).optional().describe("Hex color, e.g. '#ef4444'"),
|
|
6137
|
+
description: z15.string().max(2e3).optional().describe("What this label means"),
|
|
6138
|
+
parentSlug: z15.string().max(200).optional().describe("Parent group slug for label hierarchy"),
|
|
6139
|
+
isGroup: z15.boolean().optional().describe("True if this is a group container, not a taggable label"),
|
|
6140
|
+
order: z15.number().optional().describe("Sort order within its group"),
|
|
6141
|
+
entryId: z15.string().max(200).optional().describe("Entry ID for apply/remove actions")
|
|
7265
6142
|
});
|
|
7266
6143
|
async function handleLabelsList() {
|
|
7267
6144
|
const labels = await kernelQuery("chain.listLabels");
|
|
@@ -7365,118 +6242,118 @@ var COLLECTIONS_ACTIONS = [
|
|
|
7365
6242
|
"label-apply",
|
|
7366
6243
|
"label-remove"
|
|
7367
6244
|
];
|
|
7368
|
-
var qualityCriterionSchema =
|
|
7369
|
-
field:
|
|
6245
|
+
var qualityCriterionSchema = z16.object({
|
|
6246
|
+
field: z16.string().max(200).describe("Entry data field key this criterion applies to, e.g. 'description', 'owner'"),
|
|
7370
6247
|
// WP-480 S1: `max_length` — must mirror the Convex rule union, or the tool rejects a
|
|
7371
6248
|
// valid criterion before the request ever reaches the server.
|
|
7372
|
-
rule:
|
|
7373
|
-
value:
|
|
6249
|
+
rule: z16.enum(["required", "min_length", "max_length", "pattern"]).describe("'required': field must be non-empty (blocks accept). 'min_length': minimum string length (warns). 'max_length': maximum string length (warns). 'pattern': regex match (warns)."),
|
|
6250
|
+
value: z16.string().max(500).optional().describe("For min_length/max_length: the length bound as a string integer. For pattern: the regex string. Unused for 'required'.")
|
|
7374
6251
|
});
|
|
7375
|
-
var fieldSchema =
|
|
7376
|
-
key:
|
|
7377
|
-
label:
|
|
7378
|
-
type:
|
|
7379
|
-
required:
|
|
7380
|
-
options:
|
|
7381
|
-
searchable:
|
|
7382
|
-
displayHint:
|
|
7383
|
-
zone:
|
|
7384
|
-
colorMap:
|
|
6252
|
+
var fieldSchema = z16.object({
|
|
6253
|
+
key: z16.string().max(200).describe("Field key, e.g. 'description', 'severity', 'status'"),
|
|
6254
|
+
label: z16.string().max(200).describe("Display label, e.g. 'Description', 'Severity'"),
|
|
6255
|
+
type: z16.string().max(50).describe("Field type: 'string', 'select', 'array', 'number', 'boolean'"),
|
|
6256
|
+
required: z16.boolean().optional().describe("Whether this field is required"),
|
|
6257
|
+
options: z16.array(z16.string().max(200)).max(200).optional().describe("Options for 'select' type fields"),
|
|
6258
|
+
searchable: z16.boolean().optional().describe("Whether this field is included in full-text search"),
|
|
6259
|
+
displayHint: z16.enum(["hero", "badge", "meta", "section", "hidden", "inline-meta"]).optional().describe("V2 rendering hint: how the field should be displayed in Cortex"),
|
|
6260
|
+
zone: z16.enum(["header", "body", "meta"]).optional().describe("V2 layout zone: where the field appears in the entry view"),
|
|
6261
|
+
colorMap: z16.record(z16.string().max(50)).optional().describe("V2 value-to-semantic-color mapping, e.g. { critical: 'danger', low: 'success' }"),
|
|
7385
6262
|
// ENT-61
|
|
7386
|
-
accentSource:
|
|
6263
|
+
accentSource: z16.boolean().optional().describe("When true, this field's colorMap value drives the card-level accent styling"),
|
|
7387
6264
|
// ENT-61
|
|
7388
|
-
iconMap:
|
|
7389
|
-
helpText:
|
|
7390
|
-
optionDescriptions:
|
|
6265
|
+
iconMap: z16.record(z16.string(), z16.string().max(50)).optional().describe("Maps field values to icons (emoji/symbol), prepended to badge text"),
|
|
6266
|
+
helpText: z16.string().max(2e3).optional().describe("Help text shown in editors and describe output"),
|
|
6267
|
+
optionDescriptions: z16.record(z16.string().max(500)).optional().describe("Per-option guidance for select fields"),
|
|
7391
6268
|
// BET-136
|
|
7392
|
-
semanticRole:
|
|
6269
|
+
semanticRole: z16.enum(["problem", "appetite", "elements", "architecture", "done_when", "risks", "exclusions"]).optional().describe("Semantic role for schema-driven consumers \u2014 enables field-key-independent validation and rendering"),
|
|
7393
6270
|
// BET-196
|
|
7394
|
-
maxLength:
|
|
6271
|
+
maxLength: z16.number().optional().describe("Maximum character length for field values. Three-tier resolution: explicit > displayHint > type fallback."),
|
|
7395
6272
|
// BET-196
|
|
7396
|
-
minLength:
|
|
6273
|
+
minLength: z16.number().optional().describe("Minimum character length for field values. Only explicit \u2014 no defaults.")
|
|
7397
6274
|
});
|
|
7398
|
-
var collectionsSchema =
|
|
7399
|
-
action:
|
|
6275
|
+
var collectionsSchema = z16.object({
|
|
6276
|
+
action: z16.enum(COLLECTIONS_ACTIONS).describe(
|
|
7400
6277
|
"'list': browse all collections. 'update': update an existing collection. 'describe': full documentation for one collection \u2014 fields, option guides, usage guidance, examples. 'audit': health report for all collections \u2014 missing classification, icon, displayHint coverage, and field schema gaps. 'export': full system_collection_definitions export with classification metadata (thinkingLayer, classificationPriority, classificationCheck, classificationSignals, governanceRole, governanceFunction, timelineRole, canBeElementOf, descriptionFieldKey). Admin only. 'label-list'/'label-create'/'label-update'/'label-delete'/'label-apply'/'label-remove': manage workspace labels (absorbs the `labels` tool). Creating a new collection is not offered here \u2014 ask a platform admin to provision it, or enable the module ontology pack that owns the drawer."
|
|
7401
6278
|
),
|
|
7402
|
-
slug:
|
|
7403
|
-
name:
|
|
7404
|
-
description:
|
|
7405
|
-
purpose:
|
|
7406
|
-
icon:
|
|
7407
|
-
navGroup:
|
|
7408
|
-
fields:
|
|
7409
|
-
axis:
|
|
7410
|
-
stageLabelMap:
|
|
6279
|
+
slug: z16.string().max(200).optional().describe("URL-safe identifier for create/update, e.g. 'glossary', 'tech-debt'. For label-*: label slug."),
|
|
6280
|
+
name: z16.string().max(500).optional().describe("Display name for create, or new name for update. For label-create: label display name."),
|
|
6281
|
+
description: z16.string().max(2e4).optional().describe("What this collection is for. For label-create/label-update: what the label means."),
|
|
6282
|
+
purpose: z16.string().max(2e3).optional().describe("Why this collection exists \u2014 strategic reason"),
|
|
6283
|
+
icon: z16.string().max(50).optional().describe("Emoji icon for the collection"),
|
|
6284
|
+
navGroup: z16.enum(["daily", "strategic", "governance", "reference", "collections"]).optional().describe("Sidebar placement: 'daily', 'strategic', 'governance', 'reference', 'collections'"),
|
|
6285
|
+
fields: z16.array(fieldSchema).max(200).optional().describe("Field definitions for create, or replacement schema for update (replaces all fields)"),
|
|
6286
|
+
axis: z16.enum(["work", "none", "pending"]).optional().describe("REQUIRED for create: 'work' (needs stageLabelMap + validWorkflowStatuses), 'none', or 'pending'. For update: only settable on a non-system-stratum (custom) collection \u2014 the repair path for a legacy collection that predates the axis contract."),
|
|
6287
|
+
stageLabelMap: z16.record(z16.string(), z16.enum(["open", "in_progress", "done", "stopped", "tag"])).optional().describe("Required when axis is 'work': maps each valid workflowStatus to a canonical stage."),
|
|
7411
6288
|
// ENT-62
|
|
7412
|
-
defaultCanonicalKey:
|
|
6289
|
+
defaultCanonicalKey: z16.string().max(200).optional().describe("The canonical_key entries in this collection default to (e.g. 'decision', 'insight'). Consumers read from collection doc; code map is fallback."),
|
|
7413
6290
|
// ENT-67
|
|
7414
|
-
defaultWorkflowStatus:
|
|
6291
|
+
defaultWorkflowStatus: z16.string().max(200).optional().describe("Default workflowStatus for new entries. Must be in validWorkflowStatuses when set (e.g. 'hypothesis' for insights)."),
|
|
7415
6292
|
// ENT-65
|
|
7416
|
-
validWorkflowStatuses:
|
|
6293
|
+
validWorkflowStatuses: z16.array(z16.string().max(200)).max(50).optional().describe("The allowed workflowStatus values for entries in this collection. New entries are validated against this list. Empty array means no constraint."),
|
|
7417
6294
|
// ENT-65, FEAT-200
|
|
7418
|
-
classificationCheck:
|
|
6295
|
+
classificationCheck: z16.string().max(500).optional().describe("LLM decision-tree check for this collection (3\u2013500 chars). Guides the classifier in routing entries here."),
|
|
7419
6296
|
// ENT-65, FEAT-200
|
|
7420
|
-
classificationPriority:
|
|
6297
|
+
classificationPriority: z16.number().optional().describe("Classifier priority (1\u20139, lower = higher priority). Used with classificationCheck to order the decision tree."),
|
|
7421
6298
|
// FEAT-301 Slice 2: quality gate criteria and usage guidance.
|
|
7422
6299
|
// FEAT-257
|
|
7423
|
-
qualityCriteria:
|
|
7424
|
-
usageGuidance:
|
|
6300
|
+
qualityCriteria: z16.array(qualityCriterionSchema).max(50).optional().describe("Per-collection accept gate rules. 'required' rule hard-blocks accepts on empty fields; 'min_length'/'pattern' rules warn. Pass an empty array to clear all criteria."),
|
|
6301
|
+
usageGuidance: z16.string().max(2e4).optional().describe("Plain-text guidance shown to agents and users: when to use this collection, when not to, and what makes a good entry."),
|
|
7425
6302
|
// For label-*
|
|
7426
|
-
color:
|
|
7427
|
-
parentSlug:
|
|
7428
|
-
isGroup:
|
|
7429
|
-
order:
|
|
7430
|
-
entryId:
|
|
6303
|
+
color: z16.string().max(50).optional().describe("For label-create/label-update: hex color, e.g. '#ef4444'."),
|
|
6304
|
+
parentSlug: z16.string().max(200).optional().describe("For label-create: parent group slug for label hierarchy."),
|
|
6305
|
+
isGroup: z16.boolean().optional().describe("For label-create/label-update: true if this is a group container, not a taggable label."),
|
|
6306
|
+
order: z16.number().optional().describe("For label-create/label-update: sort order within its group."),
|
|
6307
|
+
entryId: z16.string().max(200).optional().describe("For label-apply/label-remove: entry ID.")
|
|
7431
6308
|
});
|
|
7432
|
-
var collectionsListVariant =
|
|
7433
|
-
var collectionsDescribeVariant =
|
|
7434
|
-
var collectionsUpdateVariant =
|
|
7435
|
-
action:
|
|
7436
|
-
slug:
|
|
7437
|
-
name:
|
|
7438
|
-
description:
|
|
7439
|
-
purpose:
|
|
7440
|
-
icon:
|
|
7441
|
-
navGroup:
|
|
7442
|
-
fields:
|
|
7443
|
-
axis:
|
|
7444
|
-
stageLabelMap:
|
|
6309
|
+
var collectionsListVariant = z16.object({ action: z16.literal("list") });
|
|
6310
|
+
var collectionsDescribeVariant = z16.object({ action: z16.literal("describe"), slug: z16.string().max(200) });
|
|
6311
|
+
var collectionsUpdateVariant = z16.object({
|
|
6312
|
+
action: z16.literal("update"),
|
|
6313
|
+
slug: z16.string().max(200),
|
|
6314
|
+
name: z16.string().max(500).optional(),
|
|
6315
|
+
description: z16.string().max(2e4).optional(),
|
|
6316
|
+
purpose: z16.string().max(2e3).optional(),
|
|
6317
|
+
icon: z16.string().max(50).optional(),
|
|
6318
|
+
navGroup: z16.enum(["daily", "strategic", "governance", "reference", "collections"]).optional(),
|
|
6319
|
+
fields: z16.array(fieldSchema).optional(),
|
|
6320
|
+
axis: z16.enum(["work", "none", "pending"]).optional(),
|
|
6321
|
+
stageLabelMap: z16.record(z16.string(), z16.enum(["open", "in_progress", "done", "stopped", "tag"])).optional(),
|
|
7445
6322
|
// WP-640 SWEEP (P1): axis/stageLabelMap repair legacy custom collections — see collections.ts's updateCollection.
|
|
7446
|
-
defaultCanonicalKey:
|
|
7447
|
-
defaultWorkflowStatus:
|
|
7448
|
-
validWorkflowStatuses:
|
|
7449
|
-
classificationCheck:
|
|
7450
|
-
classificationPriority:
|
|
7451
|
-
qualityCriteria:
|
|
7452
|
-
usageGuidance:
|
|
6323
|
+
defaultCanonicalKey: z16.string().max(200).optional(),
|
|
6324
|
+
defaultWorkflowStatus: z16.string().max(200).optional(),
|
|
6325
|
+
validWorkflowStatuses: z16.array(z16.string().max(200)).optional(),
|
|
6326
|
+
classificationCheck: z16.string().max(500).optional(),
|
|
6327
|
+
classificationPriority: z16.number().optional(),
|
|
6328
|
+
qualityCriteria: z16.array(qualityCriterionSchema).optional(),
|
|
6329
|
+
usageGuidance: z16.string().max(2e4).optional()
|
|
7453
6330
|
});
|
|
7454
|
-
var collectionsAuditVariant =
|
|
7455
|
-
var collectionsExportVariant =
|
|
7456
|
-
var collectionsLabelListVariant =
|
|
7457
|
-
var collectionsLabelCreateVariant =
|
|
7458
|
-
action:
|
|
7459
|
-
slug:
|
|
7460
|
-
name:
|
|
7461
|
-
color:
|
|
7462
|
-
description:
|
|
7463
|
-
parentSlug:
|
|
7464
|
-
isGroup:
|
|
7465
|
-
order:
|
|
6331
|
+
var collectionsAuditVariant = z16.object({ action: z16.literal("audit") });
|
|
6332
|
+
var collectionsExportVariant = z16.object({ action: z16.literal("export") });
|
|
6333
|
+
var collectionsLabelListVariant = z16.object({ action: z16.literal("label-list") });
|
|
6334
|
+
var collectionsLabelCreateVariant = z16.object({
|
|
6335
|
+
action: z16.literal("label-create"),
|
|
6336
|
+
slug: z16.string().max(200),
|
|
6337
|
+
name: z16.string().max(500),
|
|
6338
|
+
color: z16.string().max(50).optional(),
|
|
6339
|
+
description: z16.string().max(2e3).optional(),
|
|
6340
|
+
parentSlug: z16.string().max(200).optional(),
|
|
6341
|
+
isGroup: z16.boolean().optional(),
|
|
6342
|
+
order: z16.number().optional()
|
|
7466
6343
|
});
|
|
7467
|
-
var collectionsLabelUpdateVariant =
|
|
7468
|
-
action:
|
|
7469
|
-
slug:
|
|
7470
|
-
name:
|
|
7471
|
-
color:
|
|
7472
|
-
description:
|
|
7473
|
-
isGroup:
|
|
7474
|
-
order:
|
|
6344
|
+
var collectionsLabelUpdateVariant = z16.object({
|
|
6345
|
+
action: z16.literal("label-update"),
|
|
6346
|
+
slug: z16.string().max(200),
|
|
6347
|
+
name: z16.string().max(500).optional(),
|
|
6348
|
+
color: z16.string().max(50).optional(),
|
|
6349
|
+
description: z16.string().max(2e3).optional(),
|
|
6350
|
+
isGroup: z16.boolean().optional(),
|
|
6351
|
+
order: z16.number().optional()
|
|
7475
6352
|
});
|
|
7476
|
-
var collectionsLabelDeleteVariant =
|
|
7477
|
-
var collectionsLabelApplyVariant =
|
|
7478
|
-
var collectionsLabelRemoveVariant =
|
|
7479
|
-
var collectionsActionUnion =
|
|
6353
|
+
var collectionsLabelDeleteVariant = z16.object({ action: z16.literal("label-delete"), slug: z16.string().max(200) });
|
|
6354
|
+
var collectionsLabelApplyVariant = z16.object({ action: z16.literal("label-apply"), slug: z16.string().max(200), entryId: z16.string().max(200) });
|
|
6355
|
+
var collectionsLabelRemoveVariant = z16.object({ action: z16.literal("label-remove"), slug: z16.string().max(200), entryId: z16.string().max(200) });
|
|
6356
|
+
var collectionsActionUnion = z16.discriminatedUnion("action", [
|
|
7480
6357
|
collectionsListVariant,
|
|
7481
6358
|
collectionsDescribeVariant,
|
|
7482
6359
|
collectionsUpdateVariant,
|
|
@@ -7778,7 +6655,7 @@ async function handleExport() {
|
|
|
7778
6655
|
}
|
|
7779
6656
|
|
|
7780
6657
|
// src/tools/orient.ts
|
|
7781
|
-
import { z as
|
|
6658
|
+
import { z as z20 } from "zod/v3";
|
|
7782
6659
|
|
|
7783
6660
|
// src/tools/planned-work.ts
|
|
7784
6661
|
function buildPlannedWork(allEntries) {
|
|
@@ -8832,12 +7709,12 @@ function replaceVocabTokens(body, workspaceCtx, collectionCtxMap) {
|
|
|
8832
7709
|
}
|
|
8833
7710
|
|
|
8834
7711
|
// src/tools/start_pb.ts
|
|
8835
|
-
import { z as
|
|
7712
|
+
import { z as z18 } from "zod/v3";
|
|
8836
7713
|
|
|
8837
7714
|
// src/tools/skills.ts
|
|
8838
|
-
import { z as
|
|
8839
|
-
var skillsSchema =
|
|
8840
|
-
entryId:
|
|
7715
|
+
import { z as z17 } from "zod/v3";
|
|
7716
|
+
var skillsSchema = z17.object({
|
|
7717
|
+
entryId: z17.string().min(1).describe(
|
|
8841
7718
|
"Workspace-scoped skill entry id (e.g. 'SKILL-pb-setup'). The tool refuses non-skill entries (canonicalKey !== 'skill') with INVALID_KIND."
|
|
8842
7719
|
)
|
|
8843
7720
|
});
|
|
@@ -8978,8 +7855,8 @@ function rankActiveBets(entries) {
|
|
|
8978
7855
|
}
|
|
8979
7856
|
|
|
8980
7857
|
// src/tools/start_pb.ts
|
|
8981
|
-
var startPbSchema =
|
|
8982
|
-
task:
|
|
7858
|
+
var startPbSchema = z18.object({
|
|
7859
|
+
task: z18.string().max(2e3).optional().describe(
|
|
8983
7860
|
"What you're about to work on (e.g. 'implementing auth middleware'). Grounded/connected workspaces: filters governance to show relevant principles, standards, and business rules. Blank/seeded workspaces: ignored (setup flow takes over)."
|
|
8984
7861
|
)
|
|
8985
7862
|
// TEN-2431: no `scope` param — start_pb's governance matches orient's scope-BLIND RENDERED
|
|
@@ -9290,15 +8167,15 @@ ${FEEDBACK_SUBMIT_HINT}` }],
|
|
|
9290
8167
|
}
|
|
9291
8168
|
|
|
9292
8169
|
// src/tools/record_activation.ts
|
|
9293
|
-
import { z as
|
|
9294
|
-
var recordActivationSchema =
|
|
9295
|
-
confirmedEntryCount:
|
|
8170
|
+
import { z as z19 } from "zod/v3";
|
|
8171
|
+
var recordActivationSchema = z19.object({
|
|
8172
|
+
confirmedEntryCount: z19.number().int().min(0).describe(
|
|
9296
8173
|
"Confirmed-entry count from the Phase 4 capture loop. The mutation enforces >=10."
|
|
9297
8174
|
),
|
|
9298
|
-
entriesAcrossCollections:
|
|
8175
|
+
entriesAcrossCollections: z19.number().int().min(0).describe(
|
|
9299
8176
|
"Number of distinct collections those entries span. The mutation enforces >=2 (diversity soft-gate)."
|
|
9300
8177
|
),
|
|
9301
|
-
retrievalDemoConfirmed:
|
|
8178
|
+
retrievalDemoConfirmed: z19.boolean().describe(
|
|
9302
8179
|
"True if the retrieval round-trip ran successfully in Phase 4. The mutation rejects false."
|
|
9303
8180
|
)
|
|
9304
8181
|
});
|
|
@@ -9362,63 +8239,63 @@ async function markOrientedWithSnapshotFallback(agentSessionId, coherenceSnapsho
|
|
|
9362
8239
|
}
|
|
9363
8240
|
}
|
|
9364
8241
|
var ORIENT_ACTIONS = ["start", "task", "record-activation"];
|
|
9365
|
-
var orientSchema =
|
|
9366
|
-
action:
|
|
8242
|
+
var orientSchema = z20.object({
|
|
8243
|
+
action: z20.enum(ORIENT_ACTIONS).optional().default("task").describe(
|
|
9367
8244
|
"'start': universal session opener (absorbs start_pb) \u2014 stage-aware setup skill or standup briefing. 'task': task-grounded context loader \u2014 the original orient behavior. 'record-activation': chat-only activation receipt writer (absorbs record_activation)."
|
|
9368
8245
|
),
|
|
9369
|
-
mode:
|
|
9370
|
-
tier:
|
|
8246
|
+
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."),
|
|
8247
|
+
tier: z20.enum(["summary", "standard", "full"]).optional().describe(
|
|
9371
8248
|
"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."
|
|
9372
8249
|
),
|
|
9373
|
-
task:
|
|
8250
|
+
task: z20.string().max(2e3).optional().describe(
|
|
9374
8251
|
"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."
|
|
9375
8252
|
),
|
|
9376
8253
|
// D1d (WP-754/TASK-204): nested to match the server's StartupResolutionSignals shape, every
|
|
9377
8254
|
// field optional, sanitized server-side. Domain resolution (this envelope's original purpose)
|
|
9378
8255
|
// is deleted; the sole surviving consumer is `context.served` activation telemetry.
|
|
9379
|
-
startupSignals:
|
|
9380
|
-
changedPaths:
|
|
9381
|
-
reviewedArtifactRefs:
|
|
9382
|
-
branchName:
|
|
9383
|
-
worktreeName:
|
|
8256
|
+
startupSignals: z20.object({
|
|
8257
|
+
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)."),
|
|
8258
|
+
reviewedArtifactRefs: z20.array(z20.string()).max(25).optional().describe("Chain entry IDs the caller has already reviewed this session, if tracked."),
|
|
8259
|
+
branchName: z20.string().max(120).optional().describe("Current git branch name, if known."),
|
|
8260
|
+
worktreeName: z20.string().max(120).optional().describe("Current worktree/directory name, if known.")
|
|
9384
8261
|
}).optional().describe("For 'task': best-effort startup signals \u2014 changedPaths/reviewedArtifactRefs/branchName/worktreeName. All optional; omit fields you don't know."),
|
|
9385
|
-
invocationPath:
|
|
9386
|
-
confirmedEntryCount:
|
|
8262
|
+
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."),
|
|
8263
|
+
confirmedEntryCount: z20.number().int().min(0).optional().describe(
|
|
9387
8264
|
"For 'record-activation': confirmed-entry count from the Phase 4 capture loop. The mutation enforces >=10."
|
|
9388
8265
|
),
|
|
9389
|
-
entriesAcrossCollections:
|
|
8266
|
+
entriesAcrossCollections: z20.number().int().min(0).optional().describe(
|
|
9390
8267
|
"For 'record-activation': number of distinct collections those entries span. The mutation enforces >=2 (diversity soft-gate)."
|
|
9391
8268
|
),
|
|
9392
|
-
retrievalDemoConfirmed:
|
|
8269
|
+
retrievalDemoConfirmed: z20.boolean().optional().describe(
|
|
9393
8270
|
"For 'record-activation': true if the retrieval round-trip ran successfully in Phase 4. The mutation rejects false."
|
|
9394
8271
|
)
|
|
9395
8272
|
});
|
|
9396
|
-
var orientStartVariant =
|
|
9397
|
-
action:
|
|
9398
|
-
task:
|
|
8273
|
+
var orientStartVariant = z20.object({
|
|
8274
|
+
action: z20.literal("start"),
|
|
8275
|
+
task: z20.string().max(2e3).optional()
|
|
9399
8276
|
});
|
|
9400
|
-
var orientTaskVariant =
|
|
9401
|
-
action:
|
|
9402
|
-
mode:
|
|
9403
|
-
tier:
|
|
9404
|
-
task:
|
|
8277
|
+
var orientTaskVariant = z20.object({
|
|
8278
|
+
action: z20.literal("task"),
|
|
8279
|
+
mode: z20.enum(["full", "brief"]).optional().default("full"),
|
|
8280
|
+
tier: z20.enum(["summary", "standard", "full"]).optional(),
|
|
8281
|
+
task: z20.string().max(2e3).optional(),
|
|
9405
8282
|
// WP-486 Slice 1 (FEAT-1371) — mirrors orientSchema's top-level declaration above; see its
|
|
9406
8283
|
// doc comment for the shape rationale.
|
|
9407
|
-
startupSignals:
|
|
9408
|
-
changedPaths:
|
|
9409
|
-
reviewedArtifactRefs:
|
|
9410
|
-
branchName:
|
|
9411
|
-
worktreeName:
|
|
8284
|
+
startupSignals: z20.object({
|
|
8285
|
+
changedPaths: z20.array(z20.string()).max(25).optional(),
|
|
8286
|
+
reviewedArtifactRefs: z20.array(z20.string()).max(25).optional(),
|
|
8287
|
+
branchName: z20.string().max(120).optional(),
|
|
8288
|
+
worktreeName: z20.string().max(120).optional()
|
|
9412
8289
|
}).optional(),
|
|
9413
|
-
invocationPath:
|
|
8290
|
+
invocationPath: z20.enum(["session-start", "session-close", "manual-orient", "handshake", "unknown"]).optional()
|
|
9414
8291
|
});
|
|
9415
|
-
var orientRecordActivationVariant =
|
|
9416
|
-
action:
|
|
9417
|
-
confirmedEntryCount:
|
|
9418
|
-
entriesAcrossCollections:
|
|
9419
|
-
retrievalDemoConfirmed:
|
|
8292
|
+
var orientRecordActivationVariant = z20.object({
|
|
8293
|
+
action: z20.literal("record-activation"),
|
|
8294
|
+
confirmedEntryCount: z20.number().int().min(0),
|
|
8295
|
+
entriesAcrossCollections: z20.number().int().min(0),
|
|
8296
|
+
retrievalDemoConfirmed: z20.boolean()
|
|
9420
8297
|
});
|
|
9421
|
-
var orientActionUnion =
|
|
8298
|
+
var orientActionUnion = z20.discriminatedUnion("action", [
|
|
9422
8299
|
orientStartVariant,
|
|
9423
8300
|
orientTaskVariant,
|
|
9424
8301
|
orientRecordActivationVariant
|
|
@@ -10205,7 +9082,7 @@ async function _handleOrient({ mode = "full", tier, task, startupSignals, invoca
|
|
|
10205
9082
|
}
|
|
10206
9083
|
|
|
10207
9084
|
// src/tools/workflows.ts
|
|
10208
|
-
import { z as
|
|
9085
|
+
import { z as z21 } from "zod/v3";
|
|
10209
9086
|
|
|
10210
9087
|
// src/workflows/descriptor.ts
|
|
10211
9088
|
function cloneWorkflowQuestion(question) {
|
|
@@ -11046,75 +9923,75 @@ function workflowRunOutputToText(output) {
|
|
|
11046
9923
|
|
|
11047
9924
|
// src/tools/workflows.ts
|
|
11048
9925
|
var WORKFLOWS_ACTIONS = ["list", "start", "checkpoint", "get-run", "load-skill"];
|
|
11049
|
-
var jsonValueSchema =
|
|
11050
|
-
() =>
|
|
11051
|
-
|
|
11052
|
-
|
|
11053
|
-
|
|
11054
|
-
|
|
11055
|
-
|
|
11056
|
-
|
|
9926
|
+
var jsonValueSchema = z21.lazy(
|
|
9927
|
+
() => z21.union([
|
|
9928
|
+
z21.string(),
|
|
9929
|
+
z21.number(),
|
|
9930
|
+
z21.boolean(),
|
|
9931
|
+
z21.null(),
|
|
9932
|
+
z21.array(jsonValueSchema),
|
|
9933
|
+
z21.record(jsonValueSchema)
|
|
11057
9934
|
])
|
|
11058
9935
|
);
|
|
11059
|
-
var workflowRunOutputInputSchema =
|
|
11060
|
-
|
|
11061
|
-
format:
|
|
11062
|
-
value:
|
|
9936
|
+
var workflowRunOutputInputSchema = z21.union([
|
|
9937
|
+
z21.object({
|
|
9938
|
+
format: z21.literal("freetext"),
|
|
9939
|
+
value: z21.string()
|
|
11063
9940
|
}),
|
|
11064
|
-
|
|
11065
|
-
format:
|
|
11066
|
-
value:
|
|
9941
|
+
z21.object({
|
|
9942
|
+
format: z21.literal("list"),
|
|
9943
|
+
value: z21.array(z21.string())
|
|
11067
9944
|
}),
|
|
11068
|
-
|
|
11069
|
-
format:
|
|
11070
|
-
value:
|
|
9945
|
+
z21.object({
|
|
9946
|
+
format: z21.literal("choice"),
|
|
9947
|
+
value: z21.union([z21.string(), z21.array(z21.string())])
|
|
11071
9948
|
}),
|
|
11072
|
-
|
|
11073
|
-
format:
|
|
9949
|
+
z21.object({
|
|
9950
|
+
format: z21.literal("structured"),
|
|
11074
9951
|
value: jsonValueSchema
|
|
11075
9952
|
})
|
|
11076
9953
|
]);
|
|
11077
|
-
var workflowsSchema =
|
|
11078
|
-
action:
|
|
9954
|
+
var workflowsSchema = z21.object({
|
|
9955
|
+
action: z21.enum(WORKFLOWS_ACTIONS).describe(
|
|
11079
9956
|
"'list': browse available workflows. 'start': start or resume a workflow \u2014 returns first (or current) round and next-step checkpoint call. 'checkpoint': record round output or final summary. 'get-run': inspect a persisted workflow run. 'load-skill': load the markdown body of a SKILL-* entry from the workspace (absorbs the `skills` tool). Requires entryId."
|
|
11080
9957
|
),
|
|
11081
|
-
workflowId:
|
|
11082
|
-
runId:
|
|
11083
|
-
roundId:
|
|
11084
|
-
output:
|
|
11085
|
-
isFinal:
|
|
11086
|
-
restart:
|
|
11087
|
-
summaryName:
|
|
11088
|
-
summaryDescription:
|
|
11089
|
-
summaryEntryId:
|
|
11090
|
-
entryId:
|
|
9958
|
+
workflowId: z21.string().max(200).optional().describe("Workflow ID for start, checkpoint, or get-run, e.g. 'retro', 'implementation-review'"),
|
|
9959
|
+
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)."),
|
|
9960
|
+
roundId: z21.string().max(200).optional().describe("Round ID for checkpoint, e.g. 'what-went-well'"),
|
|
9961
|
+
output: z21.union([z21.string(), workflowRunOutputInputSchema]).optional().describe("The round's output \u2014 either legacy synthesized text or a typed workflow run payload."),
|
|
9962
|
+
isFinal: z21.boolean().optional().describe("If true, finalize an existing durable workflow run from its terminal round and create the summary chain entry."),
|
|
9963
|
+
restart: z21.boolean().optional().describe("If true, start a new durable run from the workflow's first round in the current session."),
|
|
9964
|
+
summaryName: z21.string().max(500).optional().describe("Optional name for final chain entry. If omitted, the workflow summary template is used."),
|
|
9965
|
+
summaryDescription: z21.string().max(2e4).optional().describe("Optional override for the final chain entry description. Defaults to the final round output text."),
|
|
9966
|
+
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."),
|
|
9967
|
+
entryId: z21.string().max(200).optional().describe("For 'load-skill': workspace-scoped skill entry id (e.g. 'SKILL-pb-setup'). Refuses non-skill entries (canonicalKey !== 'skill') with INVALID_KIND."),
|
|
11091
9968
|
// WP-513: team+role to create the finalize summary AS OWNER of (rung 2 only).
|
|
11092
|
-
ownerTeamEntryId:
|
|
11093
|
-
ownerRoleEntryId:
|
|
9969
|
+
ownerTeamEntryId: z21.string().max(200).optional().describe("For 'checkpoint' (isFinal): owning team (rung-2)."),
|
|
9970
|
+
ownerRoleEntryId: z21.string().max(200).optional().describe("For 'checkpoint' (isFinal): owning role (rung-2).")
|
|
11094
9971
|
});
|
|
11095
|
-
var workflowsListVariant =
|
|
11096
|
-
var workflowsGetRunVariant =
|
|
11097
|
-
action:
|
|
11098
|
-
runId:
|
|
11099
|
-
workflowId:
|
|
9972
|
+
var workflowsListVariant = z21.object({ action: z21.literal("list") });
|
|
9973
|
+
var workflowsGetRunVariant = z21.object({
|
|
9974
|
+
action: z21.literal("get-run"),
|
|
9975
|
+
runId: z21.string().max(200).optional(),
|
|
9976
|
+
workflowId: z21.string().max(200).optional()
|
|
11100
9977
|
});
|
|
11101
|
-
var workflowsStartVariant =
|
|
11102
|
-
var workflowsCheckpointVariant =
|
|
11103
|
-
action:
|
|
11104
|
-
workflowId:
|
|
11105
|
-
roundId:
|
|
11106
|
-
output:
|
|
11107
|
-
isFinal:
|
|
11108
|
-
restart:
|
|
11109
|
-
summaryName:
|
|
11110
|
-
summaryDescription:
|
|
11111
|
-
summaryEntryId:
|
|
11112
|
-
runId:
|
|
11113
|
-
ownerTeamEntryId:
|
|
11114
|
-
ownerRoleEntryId:
|
|
9978
|
+
var workflowsStartVariant = z21.object({ action: z21.literal("start"), workflowId: z21.string().max(200) });
|
|
9979
|
+
var workflowsCheckpointVariant = z21.object({
|
|
9980
|
+
action: z21.literal("checkpoint"),
|
|
9981
|
+
workflowId: z21.string().max(200),
|
|
9982
|
+
roundId: z21.string().max(200),
|
|
9983
|
+
output: z21.union([z21.string(), workflowRunOutputInputSchema]),
|
|
9984
|
+
isFinal: z21.boolean().optional(),
|
|
9985
|
+
restart: z21.boolean().optional(),
|
|
9986
|
+
summaryName: z21.string().max(500).optional(),
|
|
9987
|
+
summaryDescription: z21.string().max(2e4).optional(),
|
|
9988
|
+
summaryEntryId: z21.string().max(200).optional(),
|
|
9989
|
+
runId: z21.string().max(200).optional(),
|
|
9990
|
+
ownerTeamEntryId: z21.string().max(200).optional(),
|
|
9991
|
+
ownerRoleEntryId: z21.string().max(200).optional()
|
|
11115
9992
|
});
|
|
11116
|
-
var workflowsLoadSkillVariant =
|
|
11117
|
-
var workflowsActionUnion =
|
|
9993
|
+
var workflowsLoadSkillVariant = z21.object({ action: z21.literal("load-skill"), entryId: z21.string().max(200).min(1) });
|
|
9994
|
+
var workflowsActionUnion = z21.discriminatedUnion("action", [
|
|
11118
9995
|
workflowsListVariant,
|
|
11119
9996
|
workflowsGetRunVariant,
|
|
11120
9997
|
workflowsStartVariant,
|
|
@@ -11854,10 +10731,10 @@ function parseListOutput(output) {
|
|
|
11854
10731
|
}
|
|
11855
10732
|
|
|
11856
10733
|
// src/tools/quality.ts
|
|
11857
|
-
import { z as
|
|
10734
|
+
import { z as z23 } from "zod/v3";
|
|
11858
10735
|
|
|
11859
10736
|
// src/tools/audit.ts
|
|
11860
|
-
import { z as
|
|
10737
|
+
import { z as z22 } from "zod/v3";
|
|
11861
10738
|
var VOCAB_TTL_MS = 5 * 60 * 1e3;
|
|
11862
10739
|
var MAX_VOCAB_KEYS = 100;
|
|
11863
10740
|
var vocabCache = /* @__PURE__ */ new Map();
|
|
@@ -11887,12 +10764,12 @@ function evictVocabIfFull() {
|
|
|
11887
10764
|
}
|
|
11888
10765
|
}
|
|
11889
10766
|
var AUDIT_ACTIONS = ["run"];
|
|
11890
|
-
var auditSchema =
|
|
11891
|
-
action:
|
|
10767
|
+
var auditSchema = z22.object({
|
|
10768
|
+
action: z22.enum(AUDIT_ACTIONS).describe(
|
|
11892
10769
|
"'run': run the hygiene audit for a work package entry."
|
|
11893
10770
|
),
|
|
11894
|
-
entryId:
|
|
11895
|
-
phase:
|
|
10771
|
+
entryId: z22.string().describe("Work package entry ID to audit, e.g. '<PREFIX>-<n>'"),
|
|
10772
|
+
phase: z22.enum(["shaping", "handoff"]).default("shaping").optional().describe(
|
|
11896
10773
|
"'shaping': check shaping-phase fields only. 'handoff': check all required fields including buildContract/buildSequence/exclusions/risks. Default: shaping."
|
|
11897
10774
|
)
|
|
11898
10775
|
});
|
|
@@ -12169,44 +11046,44 @@ async function handleSpineCheck(story, refresh = false) {
|
|
|
12169
11046
|
|
|
12170
11047
|
// src/tools/quality.ts
|
|
12171
11048
|
var QUALITY_ACTIONS = ["check", "re-evaluate", "verify-chain", "audit", "spine-check"];
|
|
12172
|
-
var qualitySchema =
|
|
12173
|
-
action:
|
|
11049
|
+
var qualitySchema = z23.object({
|
|
11050
|
+
action: z23.enum(QUALITY_ACTIONS).describe(
|
|
12174
11051
|
"'check': read the entry's server quality verdict (tier + criteria). 're-evaluate': trigger fresh evaluation. 'verify-chain': verify entries against the codebase (codeMapping drift, cross-references) \u2014 absorbs `verify`. 'audit': hygiene audit for a work package entry \u2014 absorbs `audit`. 'spine-check': structural completeness of the purpose+vision+strategy spine \u2014 story:true also runs the on-demand one-story judgment."
|
|
12175
11052
|
),
|
|
12176
|
-
entryId:
|
|
12177
|
-
context:
|
|
12178
|
-
collection:
|
|
12179
|
-
mode:
|
|
12180
|
-
phase:
|
|
11053
|
+
entryId: z23.string().max(200).optional().describe("For 'check'/'re-evaluate'/'audit': entry ID, e.g. 'TEN-graph-db', '<PREFIX>-<n>'."),
|
|
11054
|
+
context: z23.enum(["capture", "commit", "review"]).default("review").optional().describe("For re-evaluate: evaluation context"),
|
|
11055
|
+
collection: z23.string().max(200).optional().describe("For 'verify-chain': collection slug to verify (default: glossary)."),
|
|
11056
|
+
mode: z23.enum(["report", "fix"]).optional().describe("For 'verify-chain': 'report' = read-only trust report (default). 'fix' = also update drifted codeMapping statuses."),
|
|
11057
|
+
phase: z23.enum(["shaping", "handoff"]).optional().describe(
|
|
12181
11058
|
"For 'audit': 'shaping' checks shaping-phase fields only (default). 'handoff' checks all required fields including buildContract/buildSequence/exclusions/risks."
|
|
12182
11059
|
),
|
|
12183
|
-
story:
|
|
12184
|
-
refresh:
|
|
11060
|
+
story: z23.boolean().optional().describe("For 'spine-check': also run the on-demand one-story LLM judgment (never scheduled; result labelled [unvalidated])."),
|
|
11061
|
+
refresh: z23.boolean().optional().describe(
|
|
12185
11062
|
"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."
|
|
12186
11063
|
)
|
|
12187
11064
|
});
|
|
12188
|
-
var qualityCheckVariant =
|
|
12189
|
-
var qualityReEvaluateVariant =
|
|
12190
|
-
action:
|
|
12191
|
-
entryId:
|
|
12192
|
-
context:
|
|
11065
|
+
var qualityCheckVariant = z23.object({ action: z23.literal("check"), entryId: z23.string().max(200) });
|
|
11066
|
+
var qualityReEvaluateVariant = z23.object({
|
|
11067
|
+
action: z23.literal("re-evaluate"),
|
|
11068
|
+
entryId: z23.string().max(200),
|
|
11069
|
+
context: z23.enum(["capture", "commit", "review"]).optional().default("review")
|
|
12193
11070
|
});
|
|
12194
|
-
var qualityVerifyChainVariant =
|
|
12195
|
-
action:
|
|
12196
|
-
collection:
|
|
12197
|
-
mode:
|
|
11071
|
+
var qualityVerifyChainVariant = z23.object({
|
|
11072
|
+
action: z23.literal("verify-chain"),
|
|
11073
|
+
collection: z23.string().max(200).optional().default("glossary"),
|
|
11074
|
+
mode: z23.enum(["report", "fix"]).optional().default("report")
|
|
12198
11075
|
});
|
|
12199
|
-
var qualityAuditVariant =
|
|
12200
|
-
action:
|
|
12201
|
-
entryId:
|
|
12202
|
-
phase:
|
|
11076
|
+
var qualityAuditVariant = z23.object({
|
|
11077
|
+
action: z23.literal("audit"),
|
|
11078
|
+
entryId: z23.string().max(200),
|
|
11079
|
+
phase: z23.enum(["shaping", "handoff"]).optional().default("shaping")
|
|
12203
11080
|
});
|
|
12204
|
-
var qualitySpineCheckVariant =
|
|
12205
|
-
action:
|
|
12206
|
-
story:
|
|
12207
|
-
refresh:
|
|
11081
|
+
var qualitySpineCheckVariant = z23.object({
|
|
11082
|
+
action: z23.literal("spine-check"),
|
|
11083
|
+
story: z23.boolean().optional().default(false),
|
|
11084
|
+
refresh: z23.boolean().optional().default(false)
|
|
12208
11085
|
});
|
|
12209
|
-
var qualityActionUnion =
|
|
11086
|
+
var qualityActionUnion = z23.discriminatedUnion("action", [
|
|
12210
11087
|
qualityCheckVariant,
|
|
12211
11088
|
qualityReEvaluateVariant,
|
|
12212
11089
|
qualityVerifyChainVariant,
|
|
@@ -12220,43 +11097,43 @@ var QUALITY_ACTION_SPECS = {
|
|
|
12220
11097
|
audit: { params: ["entryId", "phase"], description: "entryId is required." },
|
|
12221
11098
|
"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)." }
|
|
12222
11099
|
};
|
|
12223
|
-
var qualityCheckOutputSchema =
|
|
12224
|
-
entryId:
|
|
11100
|
+
var qualityCheckOutputSchema = z23.object({
|
|
11101
|
+
entryId: z23.string(),
|
|
12225
11102
|
/** WP-480 S1: false = the ID does not resolve to an entry (typo/deleted) — distinct from "no verdict yet". */
|
|
12226
|
-
entryFound:
|
|
12227
|
-
hasVerdict:
|
|
11103
|
+
entryFound: z23.boolean().optional(),
|
|
11104
|
+
hasVerdict: z23.boolean(),
|
|
12228
11105
|
/** WP-480 S1: the verdict was judged against content the entry no longer has — re-evaluate for a current one. */
|
|
12229
|
-
stale:
|
|
12230
|
-
tier:
|
|
12231
|
-
passed:
|
|
12232
|
-
criteria:
|
|
12233
|
-
id:
|
|
12234
|
-
passed:
|
|
12235
|
-
hint:
|
|
11106
|
+
stale: z23.boolean().optional(),
|
|
11107
|
+
tier: z23.string().optional(),
|
|
11108
|
+
passed: z23.boolean().optional(),
|
|
11109
|
+
criteria: z23.array(z23.object({
|
|
11110
|
+
id: z23.string(),
|
|
11111
|
+
passed: z23.boolean(),
|
|
11112
|
+
hint: z23.string().optional()
|
|
12236
11113
|
}))
|
|
12237
11114
|
});
|
|
12238
|
-
var qualityReevaluateOutputSchema =
|
|
12239
|
-
entryId:
|
|
12240
|
-
context:
|
|
12241
|
-
score:
|
|
12242
|
-
maxScore:
|
|
12243
|
-
improved:
|
|
11115
|
+
var qualityReevaluateOutputSchema = z23.object({
|
|
11116
|
+
entryId: z23.string(),
|
|
11117
|
+
context: z23.string(),
|
|
11118
|
+
score: z23.number(),
|
|
11119
|
+
maxScore: z23.number(),
|
|
11120
|
+
improved: z23.boolean()
|
|
12244
11121
|
});
|
|
12245
|
-
var qualitySpineCheckOutputSchema =
|
|
12246
|
-
hasVerdict:
|
|
12247
|
-
noSpineEntries:
|
|
12248
|
-
structuralPassed:
|
|
12249
|
-
storyPassed:
|
|
12250
|
-
stale:
|
|
11122
|
+
var qualitySpineCheckOutputSchema = z23.object({
|
|
11123
|
+
hasVerdict: z23.boolean(),
|
|
11124
|
+
noSpineEntries: z23.boolean().optional(),
|
|
11125
|
+
structuralPassed: z23.boolean().optional(),
|
|
11126
|
+
storyPassed: z23.boolean().nullable().optional(),
|
|
11127
|
+
stale: z23.boolean().optional(),
|
|
12251
11128
|
// TASK-156: a capped membership scan must stay distinguishable from a complete one, and a
|
|
12252
11129
|
// malformed verdict needs its own discriminator — both were silently stripped before this.
|
|
12253
|
-
staleMemberIds:
|
|
12254
|
-
membershipTruncated:
|
|
11130
|
+
staleMemberIds: z23.array(z23.string()).optional(),
|
|
11131
|
+
membershipTruncated: z23.boolean().optional(),
|
|
12255
11132
|
// PRRT_kwDORS4ils6i_PVS: a KNOWN relations-fingerprint mismatch, distinct from "unknown" —
|
|
12256
11133
|
// without this, a detected topology change and an unverifiable legacy fingerprint were
|
|
12257
11134
|
// indistinguishable in structured output.
|
|
12258
|
-
relationsChanged:
|
|
12259
|
-
malformed:
|
|
11135
|
+
relationsChanged: z23.boolean().optional(),
|
|
11136
|
+
malformed: z23.boolean().optional()
|
|
12260
11137
|
});
|
|
12261
11138
|
function registerQualityTools(server) {
|
|
12262
11139
|
const qualityHandlers = {
|
|
@@ -12438,10 +11315,10 @@ async function handleReEvaluate(entryId, context) {
|
|
|
12438
11315
|
}
|
|
12439
11316
|
|
|
12440
11317
|
// src/tools/session.ts
|
|
12441
|
-
import { z as
|
|
11318
|
+
import { z as z26 } from "zod/v3";
|
|
12442
11319
|
|
|
12443
11320
|
// src/tools/wrapup.ts
|
|
12444
|
-
import { z as
|
|
11321
|
+
import { z as z24 } from "zod/v3";
|
|
12445
11322
|
|
|
12446
11323
|
// src/lib/compose-wrapup-view.ts
|
|
12447
11324
|
function toComposed(e) {
|
|
@@ -12895,8 +11772,8 @@ async function runWrapupCommitAll(data, cachedSuggestions) {
|
|
|
12895
11772
|
overflowUnscanned
|
|
12896
11773
|
};
|
|
12897
11774
|
}
|
|
12898
|
-
var wrapupSchema =
|
|
12899
|
-
action:
|
|
11775
|
+
var wrapupSchema = z24.object({
|
|
11776
|
+
action: z24.enum(["review", "commit-all"]).optional().describe(
|
|
12900
11777
|
"Action to perform. 'review' (default) shows the wrapup summary. 'commit-all' accepts all uncommitted drafts and creates suggested links."
|
|
12901
11778
|
)
|
|
12902
11779
|
});
|
|
@@ -12997,26 +11874,26 @@ ${text}` : text;
|
|
|
12997
11874
|
}
|
|
12998
11875
|
|
|
12999
11876
|
// src/tools/facilitate.ts
|
|
13000
|
-
import { z as
|
|
11877
|
+
import { z as z25 } from "zod/v3";
|
|
13001
11878
|
var FACILITATE_ACTIONS = ["resume", "commit-constellation"];
|
|
13002
|
-
var coherencyAcknowledgementSchema =
|
|
13003
|
-
response:
|
|
13004
|
-
entryId:
|
|
13005
|
-
reason:
|
|
13006
|
-
subjectEntryId:
|
|
11879
|
+
var coherencyAcknowledgementSchema = z25.object({
|
|
11880
|
+
response: z25.string().max(200).describe("Acknowledgement response per offender: 'linked' | 'accepted-fix' | 'diverged'."),
|
|
11881
|
+
entryId: z25.string().max(200).optional().describe("Entry the acknowledgement links to (e.g. the strategic spine entry)."),
|
|
11882
|
+
reason: z25.string().max(2e3).optional().describe("Free-text justification, required for a 'diverged' response."),
|
|
11883
|
+
subjectEntryId: z25.string().max(200).optional().describe("The refused entry this acknowledgement answers.")
|
|
13007
11884
|
});
|
|
13008
|
-
var facilitateSchema =
|
|
13009
|
-
action:
|
|
11885
|
+
var facilitateSchema = z25.object({
|
|
11886
|
+
action: z25.enum(FACILITATE_ACTIONS).describe(
|
|
13010
11887
|
"'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."
|
|
13011
11888
|
),
|
|
13012
|
-
betEntryId:
|
|
13013
|
-
operationId:
|
|
11889
|
+
betEntryId: z25.string().max(200).optional().describe("Bet entry ID. Required for both actions."),
|
|
11890
|
+
operationId: z25.string().max(200).optional().describe("Optional idempotency key for commit-constellation retries."),
|
|
13014
11891
|
// WP-465 slice ⑤: coherency retry controls for a COHERENCY_REFUSED constellation hold.
|
|
13015
11892
|
// Forwarded verbatim to agentKnowledge.facilitateEnvelope (validation lives at the gate).
|
|
13016
|
-
coherencyAcknowledgements:
|
|
11893
|
+
coherencyAcknowledgements: z25.array(coherencyAcknowledgementSchema).max(20).optional().describe(
|
|
13017
11894
|
"Per-offender acknowledgements to retry a constellation held under standard/strict coherency mode. Each: {subjectEntryId, response: 'linked' | 'accepted-fix' | 'diverged', entryId?, reason?}."
|
|
13018
11895
|
),
|
|
13019
|
-
steeringOverrideReason:
|
|
11896
|
+
steeringOverrideReason: z25.string().max(2e3).optional().describe(
|
|
13020
11897
|
"Typed override reason (>= 12 chars) to push a constellation past a coherency hold instead of acknowledging."
|
|
13021
11898
|
)
|
|
13022
11899
|
});
|
|
@@ -13269,42 +12146,42 @@ var SESSION_ACTIONS = [
|
|
|
13269
12146
|
"resume",
|
|
13270
12147
|
"commit-constellation"
|
|
13271
12148
|
];
|
|
13272
|
-
var coherencyAcknowledgementFlatSchema2 =
|
|
13273
|
-
response:
|
|
13274
|
-
entryId:
|
|
13275
|
-
reason:
|
|
13276
|
-
subjectEntryId:
|
|
12149
|
+
var coherencyAcknowledgementFlatSchema2 = z26.object({
|
|
12150
|
+
response: z26.string().max(200).describe("Acknowledgement response per offender: 'linked' | 'accepted-fix' | 'diverged'."),
|
|
12151
|
+
entryId: z26.string().max(200).optional().describe("Entry the acknowledgement links to."),
|
|
12152
|
+
reason: z26.string().max(2e3).optional().describe("Free-text justification, required for a 'diverged' response."),
|
|
12153
|
+
subjectEntryId: z26.string().max(200).optional().describe("The refused entry this acknowledgement answers.")
|
|
13277
12154
|
});
|
|
13278
|
-
var sessionSchema =
|
|
13279
|
-
action:
|
|
12155
|
+
var sessionSchema = z26.object({
|
|
12156
|
+
action: z26.enum(SESSION_ACTIONS).describe(
|
|
13280
12157
|
"'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)."
|
|
13281
12158
|
),
|
|
13282
|
-
betEntryId:
|
|
13283
|
-
operationId:
|
|
13284
|
-
coherencyAcknowledgements:
|
|
12159
|
+
betEntryId: z26.string().max(200).optional().describe("For 'resume'/'commit-constellation': bet entry ID. Required for both."),
|
|
12160
|
+
operationId: z26.string().max(200).optional().describe("For 'commit-constellation': optional idempotency key for retries."),
|
|
12161
|
+
coherencyAcknowledgements: z26.array(coherencyAcknowledgementFlatSchema2).max(20).optional().describe(
|
|
13285
12162
|
"For 'commit-constellation': per-offender acknowledgements to retry a constellation held under standard/strict coherency mode."
|
|
13286
12163
|
),
|
|
13287
|
-
steeringOverrideReason:
|
|
12164
|
+
steeringOverrideReason: z26.string().max(2e3).optional().describe(
|
|
13288
12165
|
"For 'commit-constellation': typed override reason (>= 12 chars) to push past a coherency hold instead of acknowledging."
|
|
13289
12166
|
),
|
|
13290
12167
|
// DEC-1715 (WP-753 O1a)
|
|
13291
|
-
role:
|
|
12168
|
+
role: z26.string().max(200).optional().describe(
|
|
13292
12169
|
"For 'start': role to act as this session \u2014 only needed if you hold more than one; the error lists your roles if omitted."
|
|
13293
12170
|
)
|
|
13294
12171
|
});
|
|
13295
|
-
var sessionStartVariant =
|
|
13296
|
-
action:
|
|
12172
|
+
var sessionStartVariant = z26.object({
|
|
12173
|
+
action: z26.literal("start"),
|
|
13297
12174
|
// DEC-1715 (WP-753 O1a): the role to act as this session — only needed when the person holds
|
|
13298
12175
|
// more than one role; the server refuses and lists the choices when it's required and omitted.
|
|
13299
|
-
role:
|
|
12176
|
+
role: z26.string().max(200).optional().describe("Role to act as this session \u2014 only needed if you hold more than one; the error lists your roles if omitted.")
|
|
13300
12177
|
});
|
|
13301
|
-
var sessionCloseVariant =
|
|
13302
|
-
var sessionStatusVariant =
|
|
13303
|
-
var sessionWrapupReviewVariant =
|
|
13304
|
-
var sessionWrapupCommitVariant =
|
|
13305
|
-
var sessionResumeVariant = facilitateSchema.omit({ action: true }).extend({ action:
|
|
13306
|
-
var sessionCommitConstellationVariant = facilitateSchema.omit({ action: true }).extend({ action:
|
|
13307
|
-
var sessionActionUnion =
|
|
12178
|
+
var sessionCloseVariant = z26.object({ action: z26.literal("close") });
|
|
12179
|
+
var sessionStatusVariant = z26.object({ action: z26.literal("status") });
|
|
12180
|
+
var sessionWrapupReviewVariant = z26.object({ action: z26.literal("wrapup-review") });
|
|
12181
|
+
var sessionWrapupCommitVariant = z26.object({ action: z26.literal("wrapup-commit") });
|
|
12182
|
+
var sessionResumeVariant = facilitateSchema.omit({ action: true }).extend({ action: z26.literal("resume") });
|
|
12183
|
+
var sessionCommitConstellationVariant = facilitateSchema.omit({ action: true }).extend({ action: z26.literal("commit-constellation") });
|
|
12184
|
+
var sessionActionUnion = z26.discriminatedUnion("action", [
|
|
13308
12185
|
sessionStartVariant,
|
|
13309
12186
|
sessionCloseVariant,
|
|
13310
12187
|
sessionStatusVariant,
|
|
@@ -13549,7 +12426,7 @@ async function handleStatus() {
|
|
|
13549
12426
|
}
|
|
13550
12427
|
|
|
13551
12428
|
// src/tools/gitchain.ts
|
|
13552
|
-
import { z as
|
|
12429
|
+
import { z as z27 } from "zod/v3";
|
|
13553
12430
|
|
|
13554
12431
|
// src/lib/versionDisplay.ts
|
|
13555
12432
|
function toVersionDisplay(version) {
|
|
@@ -13558,51 +12435,51 @@ function toVersionDisplay(version) {
|
|
|
13558
12435
|
}
|
|
13559
12436
|
|
|
13560
12437
|
// src/tools/gitchain.ts
|
|
13561
|
-
var chainSchema =
|
|
13562
|
-
action:
|
|
13563
|
-
chainEntryId:
|
|
13564
|
-
title:
|
|
13565
|
-
chainTypeId:
|
|
13566
|
-
description:
|
|
13567
|
-
linkId:
|
|
13568
|
-
content:
|
|
13569
|
-
status:
|
|
13570
|
-
author:
|
|
12438
|
+
var chainSchema = z27.object({
|
|
12439
|
+
action: z27.enum(["create", "get", "list", "edit"]).describe("Action: create a process, get process details, list all processes, or edit a process link"),
|
|
12440
|
+
chainEntryId: z27.string().max(200).optional().describe("Chain entry ID (required for get/edit)"),
|
|
12441
|
+
title: z27.string().max(500).optional().describe("Process title (required for create)"),
|
|
12442
|
+
chainTypeId: z27.string().max(200).optional().default("strategy-coherence").describe("Process template slug for create: 'strategy-coherence', 'idm-proposal', or any custom template slug"),
|
|
12443
|
+
description: z27.string().max(2e4).optional().describe("Description (for create)"),
|
|
12444
|
+
linkId: z27.string().max(200).optional().describe("Link to edit (for edit action): problem, insight, choice, action, outcome"),
|
|
12445
|
+
content: z27.string().max(5e4).optional().describe("New content for the link (for edit action)"),
|
|
12446
|
+
status: z27.string().max(200).optional().describe("Filter by status for list: 'draft' or 'active'"),
|
|
12447
|
+
author: z27.string().max(200).optional().describe("Who is performing the action. Defaults to 'mcp'."),
|
|
13571
12448
|
// WP-513 review round 3 (P1): team+role to create AS OWNER of (rung 2 only) — entry ID or entryId (e.g. "TEAM-1").
|
|
13572
|
-
ownerTeamEntryId:
|
|
13573
|
-
ownerRoleEntryId:
|
|
12449
|
+
ownerTeamEntryId: z27.string().max(200).optional().describe("For 'create': owning team (rung-2 workspaces)."),
|
|
12450
|
+
ownerRoleEntryId: z27.string().max(200).optional().describe("For 'create': owning role (rung-2 workspaces).")
|
|
13574
12451
|
});
|
|
13575
|
-
var chainVersionSchema =
|
|
13576
|
-
action:
|
|
13577
|
-
chainEntryId:
|
|
13578
|
-
commitMessage:
|
|
13579
|
-
versionA:
|
|
13580
|
-
versionB:
|
|
13581
|
-
toVersion:
|
|
13582
|
-
author:
|
|
12452
|
+
var chainVersionSchema = z27.object({
|
|
12453
|
+
action: z27.enum(["commit", "list", "diff", "revert", "history"]).describe("Action: commit a snapshot, list commits, diff two versions, revert to a version, or view history"),
|
|
12454
|
+
chainEntryId: z27.string().max(200).describe("The chain's entry ID"),
|
|
12455
|
+
commitMessage: z27.string().max(2e3).optional().describe("Commit message (required for commit). Convention: type(link): description"),
|
|
12456
|
+
versionA: z27.number().optional().describe("Earlier version for diff"),
|
|
12457
|
+
versionB: z27.number().optional().describe("Later version for diff"),
|
|
12458
|
+
toVersion: z27.number().optional().describe("Version number to revert to"),
|
|
12459
|
+
author: z27.string().max(200).optional().describe("Who is performing the action. Defaults to 'mcp'.")
|
|
13583
12460
|
});
|
|
13584
|
-
var chainBranchSchema =
|
|
13585
|
-
action:
|
|
13586
|
-
chainEntryId:
|
|
13587
|
-
branchName:
|
|
13588
|
-
strategy:
|
|
13589
|
-
author:
|
|
12461
|
+
var chainBranchSchema = z27.object({
|
|
12462
|
+
action: z27.enum(["create", "list", "merge", "conflicts"]).describe("Action: create a branch, list branches, merge a branch, or check for conflicts"),
|
|
12463
|
+
chainEntryId: z27.string().max(200).describe("The chain's entry ID"),
|
|
12464
|
+
branchName: z27.string().max(200).optional().describe("Branch name (required for merge/conflicts, optional for create)"),
|
|
12465
|
+
strategy: z27.enum(["merge_commit", "squash"]).optional().describe("Merge strategy: 'merge_commit' (default) or 'squash'"),
|
|
12466
|
+
author: z27.string().max(200).optional().describe("Who is performing the action. Defaults to 'mcp'.")
|
|
13590
12467
|
});
|
|
13591
|
-
var chainReviewSchema =
|
|
13592
|
-
action:
|
|
12468
|
+
var chainReviewSchema = z27.object({
|
|
12469
|
+
action: z27.enum(["gate", "comment", "resolve-comment", "list-comments"]).describe("Action: run coherence gate, add a comment, resolve a comment, or list comments"),
|
|
13593
12470
|
// Finding #12: optional at the base (mirrors chainSchema's chainEntryId pattern at
|
|
13594
12471
|
// line ~690) — resolve-comment resolves purely by commentId (handleChainReview never
|
|
13595
12472
|
// reads chainEntryId in that branch) and the compound-tool's advertised schema
|
|
13596
12473
|
// (chainReviewCompoundSchema below) already documents it as optional for that action.
|
|
13597
12474
|
// Per-action variants that DO need it (gate/comment/list-comments) re-require it below,
|
|
13598
12475
|
// same pattern as chainGetVariant/chainEditVariant re-requiring over chainSchema's base.
|
|
13599
|
-
chainEntryId:
|
|
13600
|
-
commitMessage:
|
|
13601
|
-
versionNumber:
|
|
13602
|
-
linkId:
|
|
13603
|
-
body:
|
|
13604
|
-
commentId:
|
|
13605
|
-
author:
|
|
12476
|
+
chainEntryId: z27.string().max(200).optional().describe("The chain's entry ID. Required for every action except 'resolve-comment'."),
|
|
12477
|
+
commitMessage: z27.string().max(2e3).optional().describe("Commit message to lint (for gate action)"),
|
|
12478
|
+
versionNumber: z27.number().optional().describe("Version to comment on or list comments for"),
|
|
12479
|
+
linkId: z27.string().max(200).optional().describe("Link this comment targets (optional for comment)"),
|
|
12480
|
+
body: z27.string().max(2e4).optional().describe("Comment text (required for comment action)"),
|
|
12481
|
+
commentId: z27.string().max(200).optional().describe("Comment ID (required for resolve-comment)"),
|
|
12482
|
+
author: z27.string().max(200).optional().describe("Who is performing the action. Defaults to 'mcp'.")
|
|
13606
12483
|
});
|
|
13607
12484
|
function linkSummary(links) {
|
|
13608
12485
|
return Object.entries(links).map(([id, content]) => {
|
|
@@ -14110,57 +12987,57 @@ var CHAIN_REVIEW_ACTIONS = [
|
|
|
14110
12987
|
"branch.merge",
|
|
14111
12988
|
"branch.conflicts"
|
|
14112
12989
|
];
|
|
14113
|
-
var chainCompoundSchema =
|
|
14114
|
-
action:
|
|
12990
|
+
var chainCompoundSchema = z27.object({
|
|
12991
|
+
action: z27.enum(CHAIN_ACTIONS).describe(
|
|
14115
12992
|
"Unnamespaced: 'create'/'get'/'list'/'edit' \u2014 process CRUD (the original `chain` tool). 'version.*' (commit/list/diff/revert/history) \u2014 versioning, absorbs `chain-version`. Branching and review live on the sibling `chain-review` tool."
|
|
14116
12993
|
),
|
|
14117
|
-
chainEntryId:
|
|
14118
|
-
title:
|
|
14119
|
-
chainTypeId:
|
|
14120
|
-
description:
|
|
14121
|
-
linkId:
|
|
14122
|
-
content:
|
|
14123
|
-
status:
|
|
14124
|
-
author:
|
|
14125
|
-
commitMessage:
|
|
14126
|
-
versionA:
|
|
14127
|
-
versionB:
|
|
14128
|
-
toVersion:
|
|
12994
|
+
chainEntryId: z27.string().max(200).optional().describe("Chain entry ID. Required for get/edit and all version.* actions."),
|
|
12995
|
+
title: z27.string().max(500).optional().describe("For 'create': process title (required)."),
|
|
12996
|
+
chainTypeId: z27.string().max(200).optional().default("strategy-coherence").describe("For 'create'/'list': process template slug."),
|
|
12997
|
+
description: z27.string().max(2e4).optional().describe("For 'create': description."),
|
|
12998
|
+
linkId: z27.string().max(200).optional().describe("For 'edit': link to edit (required)."),
|
|
12999
|
+
content: z27.string().max(5e4).optional().describe("For 'edit': new content for the link (required)."),
|
|
13000
|
+
status: z27.string().max(200).optional().describe("For 'list': filter by status."),
|
|
13001
|
+
author: z27.string().max(200).optional().describe("Who is performing the action. Defaults to 'mcp'."),
|
|
13002
|
+
commitMessage: z27.string().max(2e3).optional().describe("For 'version.commit': commit message (required)."),
|
|
13003
|
+
versionA: z27.number().optional().describe("For 'version.diff': earlier version (required)."),
|
|
13004
|
+
versionB: z27.number().optional().describe("For 'version.diff': later version (required)."),
|
|
13005
|
+
toVersion: z27.number().optional().describe("For 'version.revert': version number to revert to (required)."),
|
|
14129
13006
|
// WP-513 review round 3 (P1): team+role to create AS OWNER of (rung 2 only).
|
|
14130
|
-
ownerTeamEntryId:
|
|
14131
|
-
ownerRoleEntryId:
|
|
13007
|
+
ownerTeamEntryId: z27.string().max(200).optional().describe("For 'create': owning team (rung-2 workspaces)."),
|
|
13008
|
+
ownerRoleEntryId: z27.string().max(200).optional().describe("For 'create': owning role (rung-2 workspaces).")
|
|
14132
13009
|
});
|
|
14133
|
-
var chainReviewCompoundSchema =
|
|
14134
|
-
action:
|
|
13010
|
+
var chainReviewCompoundSchema = z27.object({
|
|
13011
|
+
action: z27.enum(CHAIN_REVIEW_ACTIONS).describe(
|
|
14135
13012
|
"'gate'/'comment'/'resolve-comment'/'list-comments' \u2014 quality gate + comments (the original `chain-review` tool, unchanged call shape). 'branch.*' (create/list/merge/conflicts) \u2014 branching, absorbs `chain-branch`. Process CRUD and versioning live on the sibling `chain` tool."
|
|
14136
13013
|
),
|
|
14137
|
-
chainEntryId:
|
|
14138
|
-
commitMessage:
|
|
14139
|
-
versionNumber:
|
|
14140
|
-
linkId:
|
|
14141
|
-
body:
|
|
14142
|
-
commentId:
|
|
14143
|
-
branchName:
|
|
14144
|
-
strategy:
|
|
14145
|
-
author:
|
|
13014
|
+
chainEntryId: z27.string().max(200).optional().describe("Chain entry ID. Required for every action except 'resolve-comment'."),
|
|
13015
|
+
commitMessage: z27.string().max(2e3).optional().describe("For 'gate': commit message to lint."),
|
|
13016
|
+
versionNumber: z27.number().optional().describe("For 'comment'/'list-comments': version to comment on or list comments for."),
|
|
13017
|
+
linkId: z27.string().max(200).optional().describe("For 'comment': optional link this comment targets."),
|
|
13018
|
+
body: z27.string().max(2e4).optional().describe("For 'comment': comment text (required)."),
|
|
13019
|
+
commentId: z27.string().max(200).optional().describe("For 'resolve-comment': comment ID (required)."),
|
|
13020
|
+
branchName: z27.string().max(200).optional().describe("For 'branch.merge'/'branch.conflicts': required. For 'branch.create': optional."),
|
|
13021
|
+
strategy: z27.enum(["merge_commit", "squash"]).optional().describe("For 'branch.merge': merge strategy. Default 'merge_commit'."),
|
|
13022
|
+
author: z27.string().max(200).optional().describe("Who is performing the action. Defaults to 'mcp'.")
|
|
14146
13023
|
});
|
|
14147
|
-
var chainCreateVariant = chainSchema.omit({ action: true }).extend({ action:
|
|
14148
|
-
var chainGetVariant =
|
|
14149
|
-
var chainListVariant =
|
|
14150
|
-
var chainEditVariant =
|
|
14151
|
-
action:
|
|
14152
|
-
chainEntryId:
|
|
14153
|
-
linkId:
|
|
14154
|
-
content:
|
|
14155
|
-
author:
|
|
13024
|
+
var chainCreateVariant = chainSchema.omit({ action: true }).extend({ action: z27.literal("create") });
|
|
13025
|
+
var chainGetVariant = z27.object({ action: z27.literal("get"), chainEntryId: z27.string().max(200) });
|
|
13026
|
+
var chainListVariant = z27.object({ action: z27.literal("list"), chainTypeId: z27.string().max(200).optional(), status: z27.string().max(200).optional() });
|
|
13027
|
+
var chainEditVariant = z27.object({
|
|
13028
|
+
action: z27.literal("edit"),
|
|
13029
|
+
chainEntryId: z27.string().max(200),
|
|
13030
|
+
linkId: z27.string().max(200),
|
|
13031
|
+
content: z27.string().max(5e4),
|
|
13032
|
+
author: z27.string().max(200).optional()
|
|
14156
13033
|
});
|
|
14157
13034
|
var versionBase = chainVersionSchema.omit({ action: true });
|
|
14158
|
-
var chainVersionCommitVariant = versionBase.extend({ action:
|
|
14159
|
-
var chainVersionListVariant = versionBase.extend({ action:
|
|
14160
|
-
var chainVersionDiffVariant = versionBase.extend({ action:
|
|
14161
|
-
var chainVersionRevertVariant = versionBase.extend({ action:
|
|
14162
|
-
var chainVersionHistoryVariant = versionBase.extend({ action:
|
|
14163
|
-
var chainActionUnion =
|
|
13035
|
+
var chainVersionCommitVariant = versionBase.extend({ action: z27.literal("version.commit"), commitMessage: z27.string().max(2e3) });
|
|
13036
|
+
var chainVersionListVariant = versionBase.extend({ action: z27.literal("version.list") });
|
|
13037
|
+
var chainVersionDiffVariant = versionBase.extend({ action: z27.literal("version.diff"), versionA: z27.number(), versionB: z27.number() });
|
|
13038
|
+
var chainVersionRevertVariant = versionBase.extend({ action: z27.literal("version.revert"), toVersion: z27.number() });
|
|
13039
|
+
var chainVersionHistoryVariant = versionBase.extend({ action: z27.literal("version.history") });
|
|
13040
|
+
var chainActionUnion = z27.discriminatedUnion("action", [
|
|
14164
13041
|
chainCreateVariant,
|
|
14165
13042
|
chainGetVariant,
|
|
14166
13043
|
chainListVariant,
|
|
@@ -14172,16 +13049,16 @@ var chainActionUnion = z29.discriminatedUnion("action", [
|
|
|
14172
13049
|
chainVersionHistoryVariant
|
|
14173
13050
|
]);
|
|
14174
13051
|
var reviewBase = chainReviewSchema.omit({ action: true });
|
|
14175
|
-
var chainReviewGateVariant = reviewBase.extend({ action:
|
|
14176
|
-
var chainReviewCommentVariant = reviewBase.extend({ action:
|
|
14177
|
-
var chainReviewResolveCommentVariant = reviewBase.extend({ action:
|
|
14178
|
-
var chainReviewListCommentsVariant = reviewBase.extend({ action:
|
|
13052
|
+
var chainReviewGateVariant = reviewBase.extend({ action: z27.literal("gate"), chainEntryId: z27.string().max(200) });
|
|
13053
|
+
var chainReviewCommentVariant = reviewBase.extend({ action: z27.literal("comment"), chainEntryId: z27.string().max(200), versionNumber: z27.number(), body: z27.string().max(2e4) });
|
|
13054
|
+
var chainReviewResolveCommentVariant = reviewBase.extend({ action: z27.literal("resolve-comment"), commentId: z27.string().max(200) });
|
|
13055
|
+
var chainReviewListCommentsVariant = reviewBase.extend({ action: z27.literal("list-comments"), chainEntryId: z27.string().max(200) });
|
|
14179
13056
|
var branchBase = chainBranchSchema.omit({ action: true });
|
|
14180
|
-
var chainBranchCreateVariant = branchBase.extend({ action:
|
|
14181
|
-
var chainBranchListVariant = branchBase.extend({ action:
|
|
14182
|
-
var chainBranchMergeVariant = branchBase.extend({ action:
|
|
14183
|
-
var chainBranchConflictsVariant = branchBase.extend({ action:
|
|
14184
|
-
var chainReviewActionUnion =
|
|
13057
|
+
var chainBranchCreateVariant = branchBase.extend({ action: z27.literal("branch.create") });
|
|
13058
|
+
var chainBranchListVariant = branchBase.extend({ action: z27.literal("branch.list") });
|
|
13059
|
+
var chainBranchMergeVariant = branchBase.extend({ action: z27.literal("branch.merge"), branchName: z27.string().max(200) });
|
|
13060
|
+
var chainBranchConflictsVariant = branchBase.extend({ action: z27.literal("branch.conflicts"), branchName: z27.string().max(200) });
|
|
13061
|
+
var chainReviewActionUnion = z27.discriminatedUnion("action", [
|
|
14185
13062
|
chainReviewGateVariant,
|
|
14186
13063
|
chainReviewCommentVariant,
|
|
14187
13064
|
chainReviewResolveCommentVariant,
|
|
@@ -14273,10 +13150,10 @@ function registerGitChainTools(server) {
|
|
|
14273
13150
|
}
|
|
14274
13151
|
|
|
14275
13152
|
// src/tools/workspace.ts
|
|
14276
|
-
import { z as
|
|
13153
|
+
import { z as z30 } from "zod/v3";
|
|
14277
13154
|
|
|
14278
13155
|
// src/tools/health.ts
|
|
14279
|
-
import { z as
|
|
13156
|
+
import { z as z28 } from "zod/v3";
|
|
14280
13157
|
|
|
14281
13158
|
// src/lib/auditView.ts
|
|
14282
13159
|
async function buildTenantAuditView(limit) {
|
|
@@ -14636,61 +13513,61 @@ ${logLines.join("\n")}${seamSummaryText}` }],
|
|
|
14636
13513
|
};
|
|
14637
13514
|
}
|
|
14638
13515
|
var HEALTH_ACTIONS = ["check", "whoami", "status", "audit", "self-test"];
|
|
14639
|
-
var healthSchema =
|
|
14640
|
-
action:
|
|
13516
|
+
var healthSchema = z28.object({
|
|
13517
|
+
action: z28.enum(HEALTH_ACTIONS).describe(
|
|
14641
13518
|
"'check': connectivity and workspace stats. 'whoami': session identity. 'status': workspace readiness. 'audit': session audit log. 'self-test': validate all tool schemas."
|
|
14642
13519
|
),
|
|
14643
|
-
limit:
|
|
13520
|
+
limit: z28.number().min(1).max(50).default(20).optional().describe("For audit: how many recent calls to show (max 50)")
|
|
14644
13521
|
});
|
|
14645
|
-
var healthCheckOutputSchema =
|
|
14646
|
-
healthy:
|
|
14647
|
-
collections:
|
|
14648
|
-
entries:
|
|
14649
|
-
latencyMs:
|
|
14650
|
-
workspace:
|
|
13522
|
+
var healthCheckOutputSchema = z28.object({
|
|
13523
|
+
healthy: z28.boolean(),
|
|
13524
|
+
collections: z28.number(),
|
|
13525
|
+
entries: z28.number(),
|
|
13526
|
+
latencyMs: z28.number(),
|
|
13527
|
+
workspace: z28.string()
|
|
14651
13528
|
});
|
|
14652
|
-
var organisationHealthSchema =
|
|
14653
|
-
reviewed:
|
|
14654
|
-
agreements:
|
|
14655
|
-
disagreements:
|
|
14656
|
-
abstentions:
|
|
14657
|
-
agreementRate:
|
|
14658
|
-
flags:
|
|
13529
|
+
var organisationHealthSchema = z28.object({
|
|
13530
|
+
reviewed: z28.number(),
|
|
13531
|
+
agreements: z28.number(),
|
|
13532
|
+
disagreements: z28.number(),
|
|
13533
|
+
abstentions: z28.number(),
|
|
13534
|
+
agreementRate: z28.number(),
|
|
13535
|
+
flags: z28.array(z28.object({ collection: z28.string(), count: z28.number(), suggestedCollection: z28.string() }))
|
|
14659
13536
|
});
|
|
14660
|
-
var healthStatusOutputSchema =
|
|
14661
|
-
stage:
|
|
14662
|
-
sampleTruncated:
|
|
14663
|
-
activeEntries:
|
|
14664
|
-
totalRelations:
|
|
14665
|
-
orphanedEntries:
|
|
14666
|
-
checks:
|
|
14667
|
-
gaps:
|
|
13537
|
+
var healthStatusOutputSchema = z28.object({
|
|
13538
|
+
stage: z28.enum(["blank", "seeded", "grounded", "connected"]).optional().default("seeded"),
|
|
13539
|
+
sampleTruncated: z28.boolean().nullable().optional(),
|
|
13540
|
+
activeEntries: z28.number(),
|
|
13541
|
+
totalRelations: z28.number(),
|
|
13542
|
+
orphanedEntries: z28.number(),
|
|
13543
|
+
checks: z28.array(z28.object({ label: z28.string(), passed: z28.boolean(), current: z28.number(), required: z28.number() })),
|
|
13544
|
+
gaps: z28.array(z28.object({ id: z28.string(), label: z28.string(), guidance: z28.string() })),
|
|
14668
13545
|
organisationHealth: organisationHealthSchema.optional()
|
|
14669
13546
|
});
|
|
14670
|
-
var healthAuditOutputSchema =
|
|
14671
|
-
totalCalls:
|
|
14672
|
-
calls:
|
|
14673
|
-
tool:
|
|
14674
|
-
action:
|
|
14675
|
-
timestamp:
|
|
14676
|
-
durationMs:
|
|
13547
|
+
var healthAuditOutputSchema = z28.object({
|
|
13548
|
+
totalCalls: z28.number(),
|
|
13549
|
+
calls: z28.array(z28.object({
|
|
13550
|
+
tool: z28.string(),
|
|
13551
|
+
action: z28.string().optional(),
|
|
13552
|
+
timestamp: z28.string(),
|
|
13553
|
+
durationMs: z28.number().optional()
|
|
14677
13554
|
}))
|
|
14678
13555
|
});
|
|
14679
|
-
var healthWhoamiOutputSchema =
|
|
14680
|
-
workspaceId:
|
|
14681
|
-
workspaceName:
|
|
14682
|
-
scope:
|
|
14683
|
-
sessionId:
|
|
14684
|
-
oriented:
|
|
13556
|
+
var healthWhoamiOutputSchema = z28.object({
|
|
13557
|
+
workspaceId: z28.string(),
|
|
13558
|
+
workspaceName: z28.string(),
|
|
13559
|
+
scope: z28.string(),
|
|
13560
|
+
sessionId: z28.union([z28.string(), z28.null()]),
|
|
13561
|
+
oriented: z28.boolean()
|
|
14685
13562
|
});
|
|
14686
|
-
var selfTestOutputSchema =
|
|
14687
|
-
passed:
|
|
14688
|
-
failed:
|
|
14689
|
-
total:
|
|
14690
|
-
results:
|
|
14691
|
-
tool:
|
|
14692
|
-
valid:
|
|
14693
|
-
error:
|
|
13563
|
+
var selfTestOutputSchema = z28.object({
|
|
13564
|
+
passed: z28.number(),
|
|
13565
|
+
failed: z28.number(),
|
|
13566
|
+
total: z28.number(),
|
|
13567
|
+
results: z28.array(z28.object({
|
|
13568
|
+
tool: z28.string(),
|
|
13569
|
+
valid: z28.boolean(),
|
|
13570
|
+
error: z28.string().optional()
|
|
14694
13571
|
}))
|
|
14695
13572
|
});
|
|
14696
13573
|
function handleSelfTest(server) {
|
|
@@ -14741,9 +13618,9 @@ function handleSelfTest(server) {
|
|
|
14741
13618
|
}
|
|
14742
13619
|
|
|
14743
13620
|
// src/tools/usage.ts
|
|
14744
|
-
import { z as
|
|
14745
|
-
var usageSummarySchema =
|
|
14746
|
-
periodDays:
|
|
13621
|
+
import { z as z29 } from "zod/v3";
|
|
13622
|
+
var usageSummarySchema = z29.object({
|
|
13623
|
+
periodDays: z29.number().min(1).max(90).optional().describe("Number of days to look back (default 30, max 90)")
|
|
14747
13624
|
});
|
|
14748
13625
|
async function handleUsageSummary(periodDays) {
|
|
14749
13626
|
const ws = await getWorkspaceContext();
|
|
@@ -14915,35 +13792,35 @@ var WORKSPACE_ACTIONS = [
|
|
|
14915
13792
|
"proposals-respond",
|
|
14916
13793
|
"proposals-count"
|
|
14917
13794
|
];
|
|
14918
|
-
var workspaceSchema =
|
|
14919
|
-
action:
|
|
13795
|
+
var workspaceSchema = z30.object({
|
|
13796
|
+
action: z30.enum(WORKSPACE_ACTIONS).describe(
|
|
14920
13797
|
"'check': connectivity and workspace stats (absorbs health action=check). 'whoami': session identity (absorbs health action=whoami). 'status': workspace readiness (absorbs health action=status). 'audit': session audit log (absorbs health action=audit). 'self-test': validate all tool schemas (absorbs health action=self-test). 'usage': LLM usage and cost summary (absorbs get-usage-summary). 'proposals-list': list open consent proposals (absorbs governance-proposals action=list). 'proposals-respond': approve/reject a consent proposal (absorbs governance-proposals action=respond). 'proposals-count': count open consent proposals (absorbs governance-proposals action=count)."
|
|
14921
13798
|
),
|
|
14922
|
-
limit:
|
|
14923
|
-
periodDays:
|
|
14924
|
-
status:
|
|
14925
|
-
proposalId:
|
|
14926
|
-
verdict:
|
|
14927
|
-
reason:
|
|
13799
|
+
limit: z30.number().min(1).max(50).optional().describe("For 'audit': how many recent calls to show (max 50, default 20)."),
|
|
13800
|
+
periodDays: z30.number().min(1).max(90).optional().describe("For 'usage': number of days to look back (default 30, max 90)."),
|
|
13801
|
+
status: z30.enum(["open", "approved", "objected", "expired"]).optional().describe("For 'proposals-list': filter by status (default: open)."),
|
|
13802
|
+
proposalId: z30.string().max(200).optional().describe("For 'proposals-respond': proposal ID."),
|
|
13803
|
+
verdict: z30.enum(["approve", "reject"]).optional().describe("For 'proposals-respond': approve or reject."),
|
|
13804
|
+
reason: z30.string().max(2e3).optional().describe("For 'proposals-respond': reason for the verdict (required when rejecting).")
|
|
14928
13805
|
});
|
|
14929
|
-
var workspaceCheckVariant =
|
|
14930
|
-
var workspaceWhoamiVariant =
|
|
14931
|
-
var workspaceStatusVariant =
|
|
14932
|
-
var workspaceAuditVariant =
|
|
14933
|
-
var workspaceSelfTestVariant =
|
|
14934
|
-
var workspaceUsageVariant =
|
|
14935
|
-
var workspaceProposalsListVariant =
|
|
14936
|
-
action:
|
|
14937
|
-
status:
|
|
13806
|
+
var workspaceCheckVariant = z30.object({ action: z30.literal("check") });
|
|
13807
|
+
var workspaceWhoamiVariant = z30.object({ action: z30.literal("whoami") });
|
|
13808
|
+
var workspaceStatusVariant = z30.object({ action: z30.literal("status") });
|
|
13809
|
+
var workspaceAuditVariant = z30.object({ action: z30.literal("audit"), limit: z30.number().min(1).max(50).optional().default(20) });
|
|
13810
|
+
var workspaceSelfTestVariant = z30.object({ action: z30.literal("self-test") });
|
|
13811
|
+
var workspaceUsageVariant = z30.object({ action: z30.literal("usage"), periodDays: z30.number().min(1).max(90).optional() });
|
|
13812
|
+
var workspaceProposalsListVariant = z30.object({
|
|
13813
|
+
action: z30.literal("proposals-list"),
|
|
13814
|
+
status: z30.enum(["open", "approved", "objected", "expired"]).optional()
|
|
14938
13815
|
});
|
|
14939
|
-
var workspaceProposalsRespondVariant =
|
|
14940
|
-
action:
|
|
14941
|
-
proposalId:
|
|
14942
|
-
verdict:
|
|
14943
|
-
reason:
|
|
13816
|
+
var workspaceProposalsRespondVariant = z30.object({
|
|
13817
|
+
action: z30.literal("proposals-respond"),
|
|
13818
|
+
proposalId: z30.string().max(200),
|
|
13819
|
+
verdict: z30.enum(["approve", "reject"]),
|
|
13820
|
+
reason: z30.string().max(2e3).optional()
|
|
14944
13821
|
});
|
|
14945
|
-
var workspaceProposalsCountVariant =
|
|
14946
|
-
var workspaceActionUnion =
|
|
13822
|
+
var workspaceProposalsCountVariant = z30.object({ action: z30.literal("proposals-count") });
|
|
13823
|
+
var workspaceActionUnion = z30.discriminatedUnion("action", [
|
|
14947
13824
|
workspaceCheckVariant,
|
|
14948
13825
|
workspaceWhoamiVariant,
|
|
14949
13826
|
workspaceStatusVariant,
|
|
@@ -14999,7 +13876,7 @@ function registerWorkspaceTools(server) {
|
|
|
14999
13876
|
}
|
|
15000
13877
|
|
|
15001
13878
|
// src/tools/feedback.ts
|
|
15002
|
-
import { z as
|
|
13879
|
+
import { z as z31 } from "zod/v3";
|
|
15003
13880
|
|
|
15004
13881
|
// src/lib/productFeedbackConstants.ts
|
|
15005
13882
|
var PRODUCT_FEEDBACK_CATEGORIES = ["bug", "friction", "idea", "praise", "other"];
|
|
@@ -15010,9 +13887,9 @@ var VENDOR_SETTABLE_STATUSES = PRODUCT_FEEDBACK_STATUSES.filter(
|
|
|
15010
13887
|
|
|
15011
13888
|
// src/tools/feedback.ts
|
|
15012
13889
|
var actions = ["submit", "list", "queue", "note", "group", "status"];
|
|
15013
|
-
var category =
|
|
15014
|
-
var status =
|
|
15015
|
-
var vendorStatus =
|
|
13890
|
+
var category = z31.enum(PRODUCT_FEEDBACK_CATEGORIES);
|
|
13891
|
+
var status = z31.enum(PRODUCT_FEEDBACK_STATUSES);
|
|
13892
|
+
var vendorStatus = z31.enum(VENDOR_SETTABLE_STATUSES);
|
|
15016
13893
|
var GATEWAY_MAX_STRING_BYTES = 10240;
|
|
15017
13894
|
var utf8Bytes = (value) => new TextEncoder().encode(value).length;
|
|
15018
13895
|
var fitsGatewayBytes = (value) => utf8Bytes(value) <= GATEWAY_MAX_STRING_BYTES;
|
|
@@ -15021,32 +13898,32 @@ var byteLimitMessage = (field) => ({
|
|
|
15021
13898
|
});
|
|
15022
13899
|
var MESSAGE_DISPLAY_LIMIT = 1e3;
|
|
15023
13900
|
var FULL_MESSAGE_MAX_LIMIT = 5;
|
|
15024
|
-
var feedbackSchema =
|
|
15025
|
-
action:
|
|
15026
|
-
message:
|
|
13901
|
+
var feedbackSchema = z31.object({
|
|
13902
|
+
action: z31.enum(actions).describe("submit requires message; list returns your own workspace's feedback (all statuses); queue is the vendor triage queue (system admins only) and accepts filters; note requires feedbackId+note; group requires feedbackIds+groupId (null clears); status requires feedbackId+status."),
|
|
13903
|
+
message: z31.string().max(1e4).optional().describe("Required for submit: the product feedback text (max 10,000 chars and 10,240 UTF-8 bytes)."),
|
|
15027
13904
|
category: category.optional().describe("Submit/queue category; submit defaults to other."),
|
|
15028
|
-
command:
|
|
15029
|
-
route:
|
|
15030
|
-
client:
|
|
15031
|
-
feedbackId:
|
|
15032
|
-
feedbackIds:
|
|
15033
|
-
note:
|
|
13905
|
+
command: z31.string().max(1e3).optional().describe("Optional submit command context; argument values are scrubbed server-side."),
|
|
13906
|
+
route: z31.string().max(500).optional().describe("Optional submit route context."),
|
|
13907
|
+
client: z31.string().max(100).optional().describe("Optional submit client label."),
|
|
13908
|
+
feedbackId: z31.string().max(200).optional().describe("Required for note/status: target feedback ID."),
|
|
13909
|
+
feedbackIds: z31.array(z31.string().max(200)).max(100).optional().describe("Required for group: 1\u2013100 target feedback IDs."),
|
|
13910
|
+
note: z31.string().max(4e3).optional().describe("Required for note: replacement triage note (max 10,240 UTF-8 bytes)."),
|
|
15034
13911
|
status: status.optional().describe("list/queue filter (any status, including 'screening'); the status action's required target value excludes 'screening' (system-only)."),
|
|
15035
|
-
groupId:
|
|
15036
|
-
workspaceId:
|
|
15037
|
-
since:
|
|
15038
|
-
before:
|
|
15039
|
-
limit:
|
|
15040
|
-
cursor:
|
|
15041
|
-
full:
|
|
13912
|
+
groupId: z31.string().min(1).max(200).nullable().optional().describe("Group filter, or required group destination; null explicitly clears grouping."),
|
|
13913
|
+
workspaceId: z31.string().max(200).optional().describe("Queue-only filter (vendor cross-workspace triage); omitted means all workspaces. Has no effect on list \u2014 your own workspace is always injected server-side."),
|
|
13914
|
+
since: z31.number().optional().describe("Queue-only lower createdAt window bound (inclusive) in epoch milliseconds."),
|
|
13915
|
+
before: z31.number().optional().describe("Queue-only upper createdAt window bound (exclusive) in epoch milliseconds. A time-window FILTER, not the pager \u2014 use cursor to page."),
|
|
13916
|
+
limit: z31.number().int().min(1).max(100).optional().describe("list/queue row limit, default 50, maximum 100."),
|
|
13917
|
+
cursor: z31.string().max(2e3).optional().describe("Opaque pagination cursor from a previous list/queue response (continueCursor); omit for the first page."),
|
|
13918
|
+
full: z31.boolean().optional().describe(`list/queue only: return untruncated messages; allowed only when limit <= ${FULL_MESSAGE_MAX_LIMIT}.`)
|
|
15042
13919
|
});
|
|
15043
|
-
var union =
|
|
15044
|
-
|
|
15045
|
-
|
|
15046
|
-
|
|
15047
|
-
|
|
15048
|
-
|
|
15049
|
-
|
|
13920
|
+
var union = z31.discriminatedUnion("action", [
|
|
13921
|
+
z31.object({ action: z31.literal("submit"), message: z31.string().min(1).max(1e4).refine(fitsGatewayBytes, byteLimitMessage("message")), category: category.optional(), command: z31.string().max(1e3).optional(), route: z31.string().max(500).optional(), client: z31.string().max(100).optional() }),
|
|
13922
|
+
z31.object({ action: z31.literal("list"), status: status.optional(), limit: z31.number().int().min(1).max(100).optional(), cursor: z31.string().max(2e3).optional(), full: z31.boolean().optional() }),
|
|
13923
|
+
z31.object({ action: z31.literal("queue"), status: status.optional(), category: category.optional(), groupId: z31.string().min(1).max(200).optional(), workspaceId: z31.string().max(200).optional(), since: z31.number().optional(), before: z31.number().optional(), limit: z31.number().int().min(1).max(100).optional(), cursor: z31.string().max(2e3).optional(), full: z31.boolean().optional() }),
|
|
13924
|
+
z31.object({ action: z31.literal("note"), feedbackId: z31.string().min(1).max(200), note: z31.string().max(4e3).refine(fitsGatewayBytes, byteLimitMessage("note")) }),
|
|
13925
|
+
z31.object({ action: z31.literal("group"), feedbackIds: z31.array(z31.string().min(1).max(200)).min(1).max(100), groupId: z31.string().min(1).max(200).nullable() }),
|
|
13926
|
+
z31.object({ action: z31.literal("status"), feedbackId: z31.string().min(1).max(200), status: vendorStatus })
|
|
15050
13927
|
]);
|
|
15051
13928
|
var specs = {
|
|
15052
13929
|
submit: { params: ["message", "category", "command", "route", "client"], description: "message is required; category defaults to other." },
|
|
@@ -15173,34 +14050,34 @@ function registerFeedbackTool(server) {
|
|
|
15173
14050
|
}
|
|
15174
14051
|
|
|
15175
14052
|
// src/tools/shape.ts
|
|
15176
|
-
import { z as
|
|
14053
|
+
import { z as z32 } from "zod/v3";
|
|
15177
14054
|
var SHAPE_ACTIONS = ["list", "show", "agree", "dismiss"];
|
|
15178
14055
|
var LIST_DISPOSITIONS = ["pending", "agreed", "dismissed", "expired"];
|
|
15179
14056
|
var LIST_OUTCOMES = ["not_candidate", "atomic", "compound", "unavailable"];
|
|
15180
|
-
var shapeSchema =
|
|
15181
|
-
action:
|
|
14057
|
+
var shapeSchema = z32.object({
|
|
14058
|
+
action: z32.enum(SHAPE_ACTIONS).describe(
|
|
15182
14059
|
"'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."
|
|
15183
14060
|
),
|
|
15184
|
-
disposition:
|
|
14061
|
+
disposition: z32.enum(LIST_DISPOSITIONS).optional().describe(
|
|
15185
14062
|
"For 'list': filter by disposition. Omitting both disposition and outcome defaults to the actionable set (disposition:pending, outcome:compound)."
|
|
15186
14063
|
),
|
|
15187
|
-
outcome:
|
|
14064
|
+
outcome: z32.enum(LIST_OUTCOMES).optional().describe(
|
|
15188
14065
|
"For 'list': filter by outcome. Omitting both disposition and outcome defaults to the actionable set (disposition:pending, outcome:compound)."
|
|
15189
14066
|
),
|
|
15190
|
-
limit:
|
|
15191
|
-
rowId:
|
|
15192
|
-
reason:
|
|
14067
|
+
limit: z32.number().min(1).max(200).optional().describe("For 'list': max rows (default 50, max 200)."),
|
|
14068
|
+
rowId: z32.string().max(200).optional().describe("For 'show'/'agree'/'dismiss': the advisory row id."),
|
|
14069
|
+
reason: z32.string().max(1e3).optional().describe("For 'agree'/'dismiss': optional reason (capped at 1000 chars).")
|
|
15193
14070
|
});
|
|
15194
|
-
var shapeListVariant =
|
|
15195
|
-
action:
|
|
15196
|
-
disposition:
|
|
15197
|
-
outcome:
|
|
15198
|
-
limit:
|
|
14071
|
+
var shapeListVariant = z32.object({
|
|
14072
|
+
action: z32.literal("list"),
|
|
14073
|
+
disposition: z32.enum(LIST_DISPOSITIONS).optional(),
|
|
14074
|
+
outcome: z32.enum(LIST_OUTCOMES).optional(),
|
|
14075
|
+
limit: z32.number().min(1).max(200).optional()
|
|
15199
14076
|
});
|
|
15200
|
-
var shapeShowVariant =
|
|
15201
|
-
var shapeAgreeVariant =
|
|
15202
|
-
var shapeDismissVariant =
|
|
15203
|
-
var shapeActionUnion =
|
|
14077
|
+
var shapeShowVariant = z32.object({ action: z32.literal("show"), rowId: z32.string().max(200) });
|
|
14078
|
+
var shapeAgreeVariant = z32.object({ action: z32.literal("agree"), rowId: z32.string().max(200), reason: z32.string().max(1e3).optional() });
|
|
14079
|
+
var shapeDismissVariant = z32.object({ action: z32.literal("dismiss"), rowId: z32.string().max(200), reason: z32.string().max(1e3).optional() });
|
|
14080
|
+
var shapeActionUnion = z32.discriminatedUnion("action", [
|
|
15204
14081
|
shapeListVariant,
|
|
15205
14082
|
shapeShowVariant,
|
|
15206
14083
|
shapeAgreeVariant,
|
|
@@ -15347,31 +14224,31 @@ function registerShapeTools(server) {
|
|
|
15347
14224
|
}
|
|
15348
14225
|
|
|
15349
14226
|
// src/tools/question.ts
|
|
15350
|
-
import { z as
|
|
14227
|
+
import { z as z33 } from "zod/v3";
|
|
15351
14228
|
var QUESTION_ACTIONS = ["create", "adopt", "assign", "snooze", "decline", "answer", "force-close", "list"];
|
|
15352
|
-
var questionSchema =
|
|
15353
|
-
action:
|
|
14229
|
+
var questionSchema = z33.object({
|
|
14230
|
+
action: z33.enum(QUESTION_ACTIONS).describe(
|
|
15354
14231
|
"'create': create a new routed question from text (domains come from `pb question --help` / this tool's own refusal \u2014 never hardcode a slug). 'adopt': adopt attaches routing to an existing tension or repairs a facet-less question \u2014 create is the birth path. Without adopt, a tension captured via `pb capture \"TEN: ...\"` stays invisible to routing forever. 'assign': confirm ('take it', omit toRole/toPerson) or reassign (supply toRole and/or toPerson) ownership. 'snooze': defer a routed/escalated question (max 2, then it escalates). 'decline': pass on a suggested question, or (as owner/lead) decline an owned one \u2014 reason required. 'answer': close the loop \u2014 creates the answering entry itself unless --entry is given. 'force-close': Team-Lead-only escape hatch \u2014 reason required. 'list': the ack-gate read model \u2014 what you owe (or, with mine:true, every question you asked, including closed ones)."
|
|
15355
14232
|
),
|
|
15356
|
-
entryId:
|
|
15357
|
-
text:
|
|
15358
|
-
domain:
|
|
15359
|
-
blocks:
|
|
15360
|
-
toRole:
|
|
15361
|
-
toPerson:
|
|
15362
|
-
reason:
|
|
15363
|
-
answerEntryId:
|
|
15364
|
-
mine:
|
|
14233
|
+
entryId: z33.string().max(200).optional().describe("Target question's id (human TEN-nnn form or a raw entry id). Required for every action except 'create'/'list'."),
|
|
14234
|
+
text: z33.string().max(5e3).optional().describe("'create': the question text. 'answer': the answer text (mutually exclusive with answerEntryId, max 2000 chars)."),
|
|
14235
|
+
domain: z33.string().max(200).optional().describe("'create'/'adopt': the domain slug (see this tool's refusal for the live list)."),
|
|
14236
|
+
blocks: z33.array(z33.string().max(200)).max(50).optional().describe("'create'/'adopt': entry ids this question is blocking (repeatable)."),
|
|
14237
|
+
toRole: z33.string().max(200).optional().describe("'assign': reassign to this role (human ROL-nnn form or a raw entry id)."),
|
|
14238
|
+
toPerson: z33.string().max(200).optional().describe("'assign': reassign to this person (a raw person id)."),
|
|
14239
|
+
reason: z33.string().max(2e3).optional().describe("'decline'/'force-close': required reason."),
|
|
14240
|
+
answerEntryId: z33.string().max(200).optional().describe("'answer': point at an already-written entry instead of supplying text (mutually exclusive with text)."),
|
|
14241
|
+
mine: z33.boolean().optional().describe("'list': true for arm C (every question YOU asked, every status). Omit/false for the ack-gate view (what you owe).")
|
|
15365
14242
|
});
|
|
15366
|
-
var createVariant =
|
|
15367
|
-
var adoptVariant =
|
|
15368
|
-
var assignVariant =
|
|
15369
|
-
var snoozeVariant =
|
|
15370
|
-
var declineVariant =
|
|
15371
|
-
var answerVariant =
|
|
15372
|
-
var forceCloseVariant =
|
|
15373
|
-
var listVariant =
|
|
15374
|
-
var questionActionUnion =
|
|
14243
|
+
var createVariant = z33.object({ action: z33.literal("create"), text: z33.string().min(1).max(5e3), domain: z33.string().max(200).optional(), blocks: z33.array(z33.string().max(200)).max(50).optional() });
|
|
14244
|
+
var adoptVariant = z33.object({ action: z33.literal("adopt"), entryId: z33.string().max(200), domain: z33.string().max(200).optional(), blocks: z33.array(z33.string().max(200)).max(50).optional() });
|
|
14245
|
+
var assignVariant = z33.object({ action: z33.literal("assign"), entryId: z33.string().max(200), toRole: z33.string().max(200).optional(), toPerson: z33.string().max(200).optional() });
|
|
14246
|
+
var snoozeVariant = z33.object({ action: z33.literal("snooze"), entryId: z33.string().max(200) });
|
|
14247
|
+
var declineVariant = z33.object({ action: z33.literal("decline"), entryId: z33.string().max(200), reason: z33.string().min(1).max(2e3) });
|
|
14248
|
+
var answerVariant = z33.object({ action: z33.literal("answer"), entryId: z33.string().max(200), text: z33.string().max(2e3).optional(), answerEntryId: z33.string().max(200).optional() });
|
|
14249
|
+
var forceCloseVariant = z33.object({ action: z33.literal("force-close"), entryId: z33.string().max(200), reason: z33.string().min(1).max(2e3) });
|
|
14250
|
+
var listVariant = z33.object({ action: z33.literal("list"), mine: z33.boolean().optional() });
|
|
14251
|
+
var questionActionUnion = z33.discriminatedUnion("action", [
|
|
15375
14252
|
createVariant,
|
|
15376
14253
|
adoptVariant,
|
|
15377
14254
|
assignVariant,
|
|
@@ -15614,23 +14491,23 @@ function registerQuestionTools(server) {
|
|
|
15614
14491
|
}
|
|
15615
14492
|
|
|
15616
14493
|
// src/tools/role.ts
|
|
15617
|
-
import { z as
|
|
14494
|
+
import { z as z34 } from "zod/v3";
|
|
15618
14495
|
var ROLE_ACTIONS = ["accountable"];
|
|
15619
|
-
var roleSchema =
|
|
15620
|
-
action:
|
|
15621
|
-
roleId:
|
|
15622
|
-
canonicalKey:
|
|
15623
|
-
limit:
|
|
15624
|
-
cursor:
|
|
14496
|
+
var roleSchema = z34.object({
|
|
14497
|
+
action: z34.enum(ROLE_ACTIONS).describe("'accountable': what this role owns (explicit), reports on (reporting), and \u2014 not yet computed \u2014 inherits via Team-Lead vacancy coverage."),
|
|
14498
|
+
roleId: z34.string().max(200).optional().describe("The role, by the human chain id `chain.getEntry` or `pb get` would print for it, or a raw entry id. Required for 'accountable'."),
|
|
14499
|
+
canonicalKey: z34.string().max(200).optional().describe("'accountable': narrow to one kind (e.g. objective, key_result, tension)."),
|
|
14500
|
+
limit: z34.number().int().positive().max(200).optional().describe("'accountable': max explicit-list rows per page (default and maximum 200)."),
|
|
14501
|
+
cursor: z34.number().optional().describe("'accountable': continue the explicit list from an earlier truncated page's nextCursor.")
|
|
15625
14502
|
});
|
|
15626
|
-
var accountableVariant =
|
|
15627
|
-
action:
|
|
15628
|
-
roleId:
|
|
15629
|
-
canonicalKey:
|
|
15630
|
-
limit:
|
|
15631
|
-
cursor:
|
|
14503
|
+
var accountableVariant = z34.object({
|
|
14504
|
+
action: z34.literal("accountable"),
|
|
14505
|
+
roleId: z34.string().max(200),
|
|
14506
|
+
canonicalKey: z34.string().max(200).optional(),
|
|
14507
|
+
limit: z34.number().int().positive().max(200).optional(),
|
|
14508
|
+
cursor: z34.number().optional()
|
|
15632
14509
|
});
|
|
15633
|
-
var roleActionUnion =
|
|
14510
|
+
var roleActionUnion = z34.discriminatedUnion("action", [accountableVariant]);
|
|
15634
14511
|
var ROLE_ACTION_SPECS = {
|
|
15635
14512
|
accountable: { params: ["roleId", "canonicalKey", "limit", "cursor"], description: "roleId is required; canonicalKey/limit/cursor are optional." }
|
|
15636
14513
|
};
|
|
@@ -15703,49 +14580,49 @@ function registerRoleTools(server) {
|
|
|
15703
14580
|
}
|
|
15704
14581
|
|
|
15705
14582
|
// src/tools/outcome.ts
|
|
15706
|
-
import { z as
|
|
14583
|
+
import { z as z35 } from "zod/v3";
|
|
15707
14584
|
var OUTCOME_ACTIONS = ["record", "list", "show"];
|
|
15708
14585
|
var READING_KINDS = ["measurement", "estimate", "correction"];
|
|
15709
|
-
var outcomeSchema =
|
|
15710
|
-
action:
|
|
14586
|
+
var outcomeSchema = z35.object({
|
|
14587
|
+
action: z35.enum(OUTCOME_ACTIONS).describe(
|
|
15711
14588
|
"'record': record a reading (evidence, not a verdict). 'list': list readings, newest first. 'show': the derived view \u2014 current, progress, pace, staleness, recorded completion."
|
|
15712
14589
|
),
|
|
15713
|
-
entryId:
|
|
14590
|
+
entryId: z35.string().max(200).optional().describe("The key result (or other outcome-bearing) entry, by its chain id. Required for all three actions."),
|
|
15714
14591
|
// PR #858 review round 3 (Codex P2, PRRT_kwDORS4ils6gXHj9): a JSON number that overflows to
|
|
15715
14592
|
// `Infinity` (e.g. `1e400`) parses fine in JS and passes a plain `z.number()`, but
|
|
15716
14593
|
// `callGateway()` serializes it with `JSON.stringify`, which turns `Infinity` into `null` —
|
|
15717
14594
|
// the backend's `v.number()` validator then rejects a call this tool's own schema accepted.
|
|
15718
14595
|
// `.finite()` rejects it here, matching the explicit finite-value checks the CLI/other outcome
|
|
15719
14596
|
// entry surfaces already use.
|
|
15720
|
-
value:
|
|
15721
|
-
valueText:
|
|
15722
|
-
asOf:
|
|
15723
|
-
kind:
|
|
15724
|
-
correctsReadingId:
|
|
15725
|
-
recordedByRoleId:
|
|
15726
|
-
note:
|
|
15727
|
-
source:
|
|
15728
|
-
limit:
|
|
14597
|
+
value: z35.number().finite().optional().describe("'record': the measured value. Required for 'record'."),
|
|
14598
|
+
valueText: z35.string().max(500).optional().describe("'record': verbatim as-reported form when the source was not clean, e.g. '~62%'. Display only."),
|
|
14599
|
+
asOf: z35.string().max(64).optional().describe("'record': when the world was in this state, as a parseable date (default: now). Back-dating a backfill is legitimate \u2014 it shows up as asOf earlier than recordedAt."),
|
|
14600
|
+
kind: z35.enum(READING_KINDS).optional().describe("'record': measurement | estimate | correction (default: measurement)."),
|
|
14601
|
+
correctsReadingId: z35.string().max(200).optional().describe("'record': required with kind='correction' \u2014 the reading id this replaces. Refused if that row is already superseded."),
|
|
14602
|
+
recordedByRoleId: z35.string().max(200).optional().describe("'record': the accountable role (default: the entry's reporterRoleId, then its owning role)."),
|
|
14603
|
+
note: z35.string().max(2e3).optional().describe("'record': free-text note recorded with the reading."),
|
|
14604
|
+
source: z35.string().max(500).optional().describe("'record': where the number came from \u2014 a dashboard name, a query, a URL."),
|
|
14605
|
+
limit: z35.number().int().positive().max(200).optional().describe("'list': max rows to return (default and maximum 200).")
|
|
15729
14606
|
});
|
|
15730
|
-
var recordVariant =
|
|
15731
|
-
action:
|
|
15732
|
-
entryId:
|
|
15733
|
-
value:
|
|
15734
|
-
valueText:
|
|
15735
|
-
asOf:
|
|
15736
|
-
kind:
|
|
15737
|
-
correctsReadingId:
|
|
15738
|
-
recordedByRoleId:
|
|
15739
|
-
note:
|
|
15740
|
-
source:
|
|
14607
|
+
var recordVariant = z35.object({
|
|
14608
|
+
action: z35.literal("record"),
|
|
14609
|
+
entryId: z35.string().max(200),
|
|
14610
|
+
value: z35.number().finite(),
|
|
14611
|
+
valueText: z35.string().max(500).optional(),
|
|
14612
|
+
asOf: z35.string().max(64).optional(),
|
|
14613
|
+
kind: z35.enum(READING_KINDS).optional(),
|
|
14614
|
+
correctsReadingId: z35.string().max(200).optional(),
|
|
14615
|
+
recordedByRoleId: z35.string().max(200).optional(),
|
|
14616
|
+
note: z35.string().max(2e3).optional(),
|
|
14617
|
+
source: z35.string().max(500).optional()
|
|
15741
14618
|
});
|
|
15742
|
-
var listVariant2 =
|
|
15743
|
-
action:
|
|
15744
|
-
entryId:
|
|
15745
|
-
limit:
|
|
14619
|
+
var listVariant2 = z35.object({
|
|
14620
|
+
action: z35.literal("list"),
|
|
14621
|
+
entryId: z35.string().max(200),
|
|
14622
|
+
limit: z35.number().int().positive().max(200).optional()
|
|
15746
14623
|
});
|
|
15747
|
-
var showVariant =
|
|
15748
|
-
var outcomeActionUnion =
|
|
14624
|
+
var showVariant = z35.object({ action: z35.literal("show"), entryId: z35.string().max(200) });
|
|
14625
|
+
var outcomeActionUnion = z35.discriminatedUnion("action", [recordVariant, listVariant2, showVariant]);
|
|
15749
14626
|
var OUTCOME_ACTION_SPECS = {
|
|
15750
14627
|
record: {
|
|
15751
14628
|
params: ["entryId", "value", "valueText", "asOf", "kind", "correctsReadingId", "recordedByRoleId", "note", "source"],
|
|
@@ -15955,7 +14832,7 @@ var AGENT_CHEATSHEET = `# Product Brain \u2014 Agent Cheatsheet
|
|
|
15955
14832
|
| Tool | Purpose | Actions |
|
|
15956
14833
|
|---|---|---|
|
|
15957
14834
|
| \`orient\` | Workspace context, governance, active work packages, session start | \`action\`: start, task, record-activation |
|
|
15958
|
-
| \`capture\` | Create entry | \`action\`: capture
|
|
14835
|
+
| \`capture\` | Create entry | \`action\`: capture |
|
|
15959
14836
|
| \`entries\` | Read and write entries | \`action\`: list, get, batch, search, update, commit, history, move, verify, preflight |
|
|
15960
14837
|
| \`relations\` | Link entries, dismiss suggestions and delete links, find and suggest | \`action\`: create, batch-create, dismiss, delete, find, suggest |
|
|
15961
14838
|
| \`context\` | Gather related knowledge, last-verified brief | \`action\`: gather, build, neighborhood, changes, chain, cross-cut, incremental, brief, last-verified-brief |
|
|
@@ -16457,12 +15334,12 @@ ${entry.labels.map((l) => `- ${l.name ?? l.slug}`).join("\n")}`);
|
|
|
16457
15334
|
}
|
|
16458
15335
|
|
|
16459
15336
|
// src/prompts/index.ts
|
|
16460
|
-
import { z as
|
|
15337
|
+
import { z as z36 } from "zod/v3";
|
|
16461
15338
|
function registerPrompts(server) {
|
|
16462
15339
|
server.prompt(
|
|
16463
15340
|
"review-against-rules",
|
|
16464
15341
|
"Review code or a design decision against all business rules for a given domain. Fetches the rules and asks you to do a structured compliance review.",
|
|
16465
|
-
{ domain:
|
|
15342
|
+
{ domain: z36.string().describe("Business rule domain (e.g. 'Identity & Access', 'Governance & Decision-Making')") },
|
|
16466
15343
|
async ({ domain }) => {
|
|
16467
15344
|
const entries = await kernelQuery("chain.listEntries", { collectionSlug: "business-rules" });
|
|
16468
15345
|
const rules = entries.filter((e) => e.data?.domain === domain);
|
|
@@ -16515,7 +15392,7 @@ Provide a structured review with a compliance status for each rule (COMPLIANT /
|
|
|
16515
15392
|
server.prompt(
|
|
16516
15393
|
"name-check",
|
|
16517
15394
|
"Check variable names, field names, or API names against the glossary for terminology alignment. Flags drift from canonical terms.",
|
|
16518
|
-
{ names:
|
|
15395
|
+
{ names: z36.string().describe("Comma-separated list of names to check (e.g. 'vendor_id, compliance_level, formulator_type')") },
|
|
16519
15396
|
async ({ names }) => {
|
|
16520
15397
|
const terms = await kernelQuery("chain.listEntries", { collectionSlug: "glossary" });
|
|
16521
15398
|
const glossaryContext = terms.map(
|
|
@@ -16551,7 +15428,7 @@ Format as a table: Name | Status | Canonical Form | Action Needed`
|
|
|
16551
15428
|
server.prompt(
|
|
16552
15429
|
"draft-decision-record",
|
|
16553
15430
|
"Draft a structured decision record from a description of what was decided. Includes context from recent decisions and relevant rules.",
|
|
16554
|
-
{ context:
|
|
15431
|
+
{ context: z36.string().describe("Description of the decision (e.g. 'We decided to use MRSL v3.1 as the conformance baseline because...')") },
|
|
16555
15432
|
async ({ context }) => {
|
|
16556
15433
|
const recentDecisions = await kernelQuery("chain.listEntries", { collectionSlug: "decisions" });
|
|
16557
15434
|
const sorted = [...recentDecisions].sort((a, b) => (b.data?.date ?? "") > (a.data?.date ?? "") ? 1 : -1).slice(0, 5);
|
|
@@ -16589,8 +15466,8 @@ After drafting, I can log it using the capture tool with collection "decisions".
|
|
|
16589
15466
|
"draft-rule-from-context",
|
|
16590
15467
|
"Draft a new business rule from an observation or discovery made while coding. Fetches existing rules for the domain to ensure consistency.",
|
|
16591
15468
|
{
|
|
16592
|
-
observation:
|
|
16593
|
-
domain:
|
|
15469
|
+
observation: z36.string().describe("What you observed or discovered (e.g. 'Suppliers can have multiple org types in Gateway')"),
|
|
15470
|
+
domain: z36.string().describe("Which domain this rule belongs to (e.g. 'Governance & Decision-Making')")
|
|
16594
15471
|
},
|
|
16595
15472
|
async ({ observation, domain }) => {
|
|
16596
15473
|
const allRules = await kernelQuery("chain.listEntries", { collectionSlug: "business-rules" });
|
|
@@ -16753,4 +15630,4 @@ export {
|
|
|
16753
15630
|
createProductBrainServer,
|
|
16754
15631
|
initFeatureFlags
|
|
16755
15632
|
};
|
|
16756
|
-
//# sourceMappingURL=chunk-
|
|
15633
|
+
//# sourceMappingURL=chunk-YSYVDNEK.js.map
|