@productbrain/mcp 0.0.1-beta.11155 → 0.0.1-beta.11157
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.
|
@@ -2363,6 +2363,8 @@ var updateEntrySchema = z6.object({
|
|
|
2363
2363
|
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."),
|
|
2364
2364
|
// WP-465 slice ⑤ — relay-only (TEN-2233): validation/min-length/recording live in Convex.
|
|
2365
2365
|
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."),
|
|
2366
|
+
qualityOverrideReason: z6.string().optional().describe("Why (\u226512 chars) to keep an accepted spine text its quality checklist failed \u2014 recorded as an override with who wrote it."),
|
|
2367
|
+
// TASK-954
|
|
2366
2368
|
coherencyAcknowledgement: z6.object({
|
|
2367
2369
|
response: z6.enum(["linked", "accepted-fix", "diverged"]).describe("Explicit response to an acknowledge-required coherency challenge."),
|
|
2368
2370
|
entryId: z6.string().optional().describe("Authorizing entry being linked/accepted (required for 'linked' and 'accepted-fix')."),
|
|
@@ -2375,24 +2377,22 @@ var commitEntrySchema = z6.object({
|
|
|
2375
2377
|
preview: z6.boolean().optional().describe("If true, validates the accept without writing. Returns what would happen. Default false."),
|
|
2376
2378
|
// WP-465 slice ⑤ — relay-only (TEN-2233): validation/recording live in Convex.
|
|
2377
2379
|
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."),
|
|
2380
|
+
qualityOverrideReason: z6.string().optional().describe("Why (\u226512 chars) to accept over a failing quality checklist \u2014 recorded as an override with who wrote it."),
|
|
2381
|
+
// TASK-954
|
|
2378
2382
|
coherencyAcknowledgement: z6.object({
|
|
2379
2383
|
response: z6.enum(["linked", "accepted-fix", "diverged"]).describe("Explicit response to an acknowledge-required coherency challenge."),
|
|
2380
2384
|
entryId: z6.string().optional().describe("Authorizing entry being linked/accepted (required for 'linked' and 'accepted-fix')."),
|
|
2381
2385
|
reason: z6.string().optional().describe("Divergence rationale (required for 'diverged', \u226512 chars).")
|
|
2382
2386
|
}).optional().describe("Explicit response to a coherency challenge (standard/strict workspace modes).")
|
|
2383
2387
|
});
|
|
2384
|
-
async function handleUpdateEntry({ entryId, name, status: rawStatus, workflowStatus: rawWorkflowStatus, data, order, canonicalKey, autoPublish, changeNote, changeReason, sourceRef, sourceExcerpt, steeringOverrideReason, coherencyAcknowledgement }, toolName = "entries") {
|
|
2388
|
+
async function handleUpdateEntry({ entryId, name, status: rawStatus, workflowStatus: rawWorkflowStatus, data, order, canonicalKey, autoPublish, changeNote, changeReason, sourceRef, sourceExcerpt, steeringOverrideReason, qualityOverrideReason, coherencyAcknowledgement }, toolName = "entries") {
|
|
2385
2389
|
requireWriteAccess();
|
|
2386
2390
|
const fieldsProvided = [];
|
|
2387
|
-
|
|
2388
|
-
if (rawStatus !== void 0) fieldsProvided.push("status");
|
|
2389
|
-
if (rawWorkflowStatus !== void 0) fieldsProvided.push("workflowStatus");
|
|
2390
|
-
if (data !== void 0) fieldsProvided.push("data");
|
|
2391
|
-
if (order !== void 0) fieldsProvided.push("order");
|
|
2391
|
+
for (const [k, v] of [["name", name], ["status", rawStatus], ["workflowStatus", rawWorkflowStatus], ["data", data], ["order", order]]) if (v !== void 0) fieldsProvided.push(k);
|
|
2392
2392
|
for (const [k, v] of [["canonicalKey", canonicalKey], ["sourceRef", sourceRef], ["sourceExcerpt", sourceExcerpt]]) if (v !== void 0) fieldsProvided.push(k);
|
|
2393
2393
|
const status2 = rawStatus;
|
|
2394
2394
|
const workflowStatus = rawWorkflowStatus;
|
|
2395
|
-
const
|
|
2395
|
+
const send = () => kernelMutation("chain.updateEntry", {
|
|
2396
2396
|
entryId,
|
|
2397
2397
|
name,
|
|
2398
2398
|
status: status2,
|
|
@@ -2407,16 +2407,31 @@ async function handleUpdateEntry({ entryId, name, status: rawStatus, workflowSta
|
|
|
2407
2407
|
...sourceRef !== void 0 ? { sourceRef } : {},
|
|
2408
2408
|
...sourceExcerpt !== void 0 ? { sourceExcerpt } : {},
|
|
2409
2409
|
...steeringOverrideReason ? { steeringOverrideReason } : {},
|
|
2410
|
+
...qualityOverrideReason ? { qualityOverrideReason } : {},
|
|
2410
2411
|
...coherencyAcknowledgement ? { coherencyAcknowledgement } : {}
|
|
2411
2412
|
});
|
|
2413
|
+
let updateResult = await send();
|
|
2414
|
+
const held = updateResult.refusal;
|
|
2415
|
+
if (held?.code === "QUALITY_HELD" && held.state === "judging") {
|
|
2416
|
+
await settleVerdictBeforeAccept(async () => ({ judgeInFlight: true }), async () => {
|
|
2417
|
+
const read = await kernelQuery("quality.getLatestVerdictForEntry", { entryId, textHash: held.textHash });
|
|
2418
|
+
return read?.verdict && !read.stale ? read : { verdict: { llmStatus: "pending" } };
|
|
2419
|
+
});
|
|
2420
|
+
updateResult = await send();
|
|
2421
|
+
}
|
|
2412
2422
|
const maybeRefused = updateResult;
|
|
2413
2423
|
if (maybeRefused.outcome === "refused" && maybeRefused.refusal) {
|
|
2424
|
+
const mcp = maybeRefused.refusal.mcp;
|
|
2425
|
+
if (mcp) return failureResult(`# ${entryId} not saved
|
|
2426
|
+
|
|
2427
|
+
${mcp}`, "QUALITY_HELD", mcp.split("\n")[0] ?? mcp, mcp.split("\n")[1] ?? mcp, void 0, { entryId, refusal: maybeRefused.refusal });
|
|
2414
2428
|
return updateRefusedResult(toolName, entryId, maybeRefused.refusal);
|
|
2415
2429
|
}
|
|
2416
|
-
const
|
|
2430
|
+
const applied = updateResult;
|
|
2431
|
+
const id = applied.id;
|
|
2417
2432
|
const fieldArgs = { name, status: rawStatus, workflowStatus: rawWorkflowStatus, order, canonicalKey, sourceRef, sourceExcerpt };
|
|
2418
|
-
const revertedByServer =
|
|
2419
|
-
const { appliedFields, rejectedDataFields, revertedFields } = computeUpdateEntryAppliedFields(fieldArgs,
|
|
2433
|
+
const revertedByServer = applied.revertedFields ?? [];
|
|
2434
|
+
const { appliedFields, rejectedDataFields, revertedFields } = computeUpdateEntryAppliedFields(fieldArgs, applied.normalization, applied.provenanceApplied, revertedByServer);
|
|
2420
2435
|
const totalFailure = buildFieldsRejectedFailure(entryId, fieldsProvided, appliedFields, rejectedDataFields, revertedFields);
|
|
2421
2436
|
if (totalFailure) return totalFailure;
|
|
2422
2437
|
await recordSessionActivity({ entryModified: id });
|
|
@@ -2427,29 +2442,28 @@ async function handleUpdateEntry({ entryId, name, status: rawStatus, workflowSta
|
|
|
2427
2442
|
const responseLines = [
|
|
2428
2443
|
`# Entry Updated`,
|
|
2429
2444
|
``,
|
|
2430
|
-
|
|
2445
|
+
applied.receipt ?? `**${entryId}** \u2014 ${versionMode}.`,
|
|
2431
2446
|
// TASK-773: a draft team's discard names the drafts it took
|
|
2432
|
-
...
|
|
2447
|
+
...applied.qualityOverride ? [applied.qualityOverride] : [],
|
|
2448
|
+
// TASK-954: the recorded line, never a silent clear
|
|
2449
|
+
...applied.restsOnCount !== void 0 ? [restsOnCountLine(applied.restsOnCount, applied.restsOnBounded === true)] : [],
|
|
2433
2450
|
``,
|
|
2434
2451
|
// TASK-935
|
|
2435
2452
|
`Internal ID: ${id}`,
|
|
2436
2453
|
`**Workspace:** ${wsCtx.workspaceSlug} (${wsCtx.workspaceId})`
|
|
2437
2454
|
];
|
|
2438
2455
|
pushAppliedFieldsLines(responseLines, fieldsProvided, appliedFields, rejectedDataFields, revertedFields);
|
|
2439
|
-
const warnings =
|
|
2456
|
+
const warnings = applied.normalizationWarnings ?? [];
|
|
2440
2457
|
if (warnings.length > 0) {
|
|
2441
2458
|
responseLines.push("");
|
|
2442
2459
|
responseLines.push("\u26A0\uFE0F **Normalization warnings:**");
|
|
2443
2460
|
for (const warning of warnings) responseLines.push(` - ${warning}`);
|
|
2444
2461
|
}
|
|
2445
|
-
if ((
|
|
2446
|
-
responseLines.push("");
|
|
2447
|
-
responseLines.push(
|
|
2448
|
-
for (const warning of updateResult.validationWarnings ?? []) {
|
|
2449
|
-
responseLines.push(` - ${warning}`);
|
|
2450
|
-
}
|
|
2462
|
+
if ((applied.validationWarnings ?? []).length > 0) {
|
|
2463
|
+
responseLines.push("", "\u26A0\uFE0F **Validation warnings:**");
|
|
2464
|
+
for (const warning of applied.validationWarnings ?? []) responseLines.push(` - ${warning}`);
|
|
2451
2465
|
}
|
|
2452
|
-
const summary =
|
|
2466
|
+
const summary = [applied.receipt ?? `Updated ${entryId} \u2014 ${versionMode}. Fields: ${appliedFields.join(", ") || "none"}.`, applied.qualityOverride].filter(Boolean).join(" ");
|
|
2453
2467
|
const next = [
|
|
2454
2468
|
{ tool: "context", description: "View updated entry", parameters: { action: "get", entryId } },
|
|
2455
2469
|
// DEC-1894: reads live on context
|
|
@@ -2463,26 +2477,26 @@ async function handleUpdateEntry({ entryId, name, status: rawStatus, workflowSta
|
|
|
2463
2477
|
fieldsApplied: appliedFields,
|
|
2464
2478
|
// PR B: renamed from fieldsProvided (caller intent) — this is the server's verdict, matching the text above
|
|
2465
2479
|
// BET-192: normalization breakdown in structuredContent — symmetric with capture tool
|
|
2466
|
-
...
|
|
2480
|
+
...applied.normalization && (Object.keys(applied.normalization.remapped).length > 0 || applied.normalization.rejected.length > 0) && {
|
|
2467
2481
|
normalization: {
|
|
2468
|
-
remapped:
|
|
2469
|
-
rejected:
|
|
2482
|
+
remapped: applied.normalization.remapped,
|
|
2483
|
+
rejected: applied.normalization.rejected
|
|
2470
2484
|
}
|
|
2471
2485
|
},
|
|
2472
|
-
...(
|
|
2473
|
-
normalizationWarnings:
|
|
2486
|
+
...(applied.normalizationWarnings ?? []).length > 0 && {
|
|
2487
|
+
normalizationWarnings: applied.normalizationWarnings
|
|
2474
2488
|
},
|
|
2475
|
-
...(
|
|
2476
|
-
validationWarnings:
|
|
2489
|
+
...(applied.validationWarnings ?? []).length > 0 && {
|
|
2490
|
+
validationWarnings: applied.validationWarnings
|
|
2477
2491
|
},
|
|
2478
2492
|
...revertedFields.length > 0 && { revertedFields },
|
|
2479
2493
|
// #1026 R2: symmetric with the text above
|
|
2480
|
-
...
|
|
2494
|
+
...applied.restsOnCount !== void 0 ? { restsOnCount: applied.restsOnCount, restsOnBounded: applied.restsOnBounded } : {}
|
|
2481
2495
|
// TASK-935
|
|
2482
2496
|
}, next)
|
|
2483
2497
|
};
|
|
2484
2498
|
}
|
|
2485
|
-
async function handleCommitEntry({ entryId, preview, steeringOverrideReason, coherencyAcknowledgement }, toolName = "entries") {
|
|
2499
|
+
async function handleCommitEntry({ entryId, preview, steeringOverrideReason, qualityOverrideReason, coherencyAcknowledgement }, toolName = "entries") {
|
|
2486
2500
|
requireWriteAccess();
|
|
2487
2501
|
const entry = await kernelQuery("chain.getEntry", { entryId });
|
|
2488
2502
|
if (!entry) {
|
|
@@ -2524,6 +2538,8 @@ async function handleCommitEntry({ entryId, preview, steeringOverrideReason, coh
|
|
|
2524
2538
|
sessionId: getAgentSessionId() ?? void 0,
|
|
2525
2539
|
...preview ? { preview: true } : {},
|
|
2526
2540
|
...steeringOverrideReason ? { steeringOverrideReason } : {},
|
|
2541
|
+
...qualityOverrideReason ? { qualityOverrideReason } : {},
|
|
2542
|
+
// TASK-954
|
|
2527
2543
|
...coherencyAcknowledgement ? { coherencyAcknowledgement } : {},
|
|
2528
2544
|
...conflictEvidence.length > 0 ? { conflicts: conflictEvidence } : {}
|
|
2529
2545
|
});
|
|
@@ -3268,6 +3284,9 @@ var entriesSchema = z10.object({
|
|
|
3268
3284
|
steeringOverrideReason: z10.string().max(2e3).optional().describe(
|
|
3269
3285
|
"For 'update'/'commit': typed override (\u226512 chars) that clears a steering coherency block."
|
|
3270
3286
|
),
|
|
3287
|
+
qualityOverrideReason: z10.string().max(2e3).optional().describe(
|
|
3288
|
+
"For 'update'/'commit': why (\u226512 chars) to keep a spine text its quality checklist failed; recorded as an override with who wrote it."
|
|
3289
|
+
),
|
|
3271
3290
|
coherencyAcknowledgement: coherencyAcknowledgementFlatSchema.optional().describe(
|
|
3272
3291
|
"For 'update'/'commit': explicit response to a coherency challenge (standard/strict workspace modes)."
|
|
3273
3292
|
),
|
|
@@ -3297,8 +3316,8 @@ var entriesActionUnion = z10.discriminatedUnion("action", [
|
|
|
3297
3316
|
]);
|
|
3298
3317
|
var ENTRIES_ACTION_SPECS = {
|
|
3299
3318
|
preflight: { params: ["collection", "canonicalKey", "links"], description: "Inspect structure before composition; no writes or permission grant." },
|
|
3300
|
-
update: { params: ["entryId", "name", "status", "workflowStatus", "data", "order", "canonicalKey", "autoPublish", "changeNote", "changeReason", "sourceRef", "sourceExcerpt", "steeringOverrideReason", "coherencyAcknowledgement"], description: "entryId is required; every other field is optional." },
|
|
3301
|
-
commit: { params: ["entryId", "preview", "steeringOverrideReason", "coherencyAcknowledgement"], description: "entryId is required." },
|
|
3319
|
+
update: { params: ["entryId", "name", "status", "workflowStatus", "data", "order", "canonicalKey", "autoPublish", "changeNote", "changeReason", "sourceRef", "sourceExcerpt", "steeringOverrideReason", "qualityOverrideReason", "coherencyAcknowledgement"], description: "entryId is required; every other field is optional." },
|
|
3320
|
+
commit: { params: ["entryId", "preview", "steeringOverrideReason", "qualityOverrideReason", "coherencyAcknowledgement"], description: "entryId is required." },
|
|
3302
3321
|
move: { params: ["entryId", "toCollection", "canonicalKey"], description: "entryId and toCollection are required; canonicalKey is optional (atomic move+retype)." },
|
|
3303
3322
|
verify: { params: ["entryId"], description: "entryId is required." },
|
|
3304
3323
|
"still-true": { params: ["entryId"], description: "entryId is required. Allowed for the holder of the owning role; if that role is empty, the nearest seated Team Lead up the team tree." }
|
|
@@ -3505,7 +3524,7 @@ async function handleGet(entryId) {
|
|
|
3505
3524
|
if (e.sourceExcerpt) lines.push(`**Source excerpt:** ${e.sourceExcerpt}`);
|
|
3506
3525
|
const parsedOwner = parseOwnerOutput(e.owner);
|
|
3507
3526
|
if (parsedOwner) lines.push(formatOwnerLine2(parsedOwner));
|
|
3508
|
-
|
|
3527
|
+
for (const line of [e.pendingMove, e.qualityOverride]) if (typeof line === "string") lines.push(sanitizeSingleLineField(line));
|
|
3509
3528
|
const restsOnChanged = Array.isArray(e.restsOnChanged) ? e.restsOnChanged : [];
|
|
3510
3529
|
for (const item of restsOnChanged) lines.push(sanitizeSingleLineField(restsOnLine(item)));
|
|
3511
3530
|
if (epistemic) lines.push(formatEpistemicLine(epistemic));
|
|
@@ -3553,7 +3572,8 @@ async function handleGet(entryId) {
|
|
|
3553
3572
|
...e.sourceRef ? { sourceRef: String(e.sourceRef) } : {},
|
|
3554
3573
|
...e.sourceExcerpt ? { sourceExcerpt: String(e.sourceExcerpt) } : {},
|
|
3555
3574
|
...parsedOwner ? { owner: parsedOwner } : {},
|
|
3556
|
-
...typeof e
|
|
3575
|
+
...Object.fromEntries(["pendingMove", "qualityOverride"].filter((k) => typeof e[k] === "string").map((k) => [k, e[k]])),
|
|
3576
|
+
// TASK-954
|
|
3557
3577
|
...restsOnChanged.length > 0 ? { restsOnChanged } : {},
|
|
3558
3578
|
// TEN-2191: surface the WHY and its quality in the structured payload too.
|
|
3559
3579
|
...why.length > 0 ? { why } : {},
|
|
@@ -12890,4 +12910,4 @@ export {
|
|
|
12890
12910
|
createProductBrainServer,
|
|
12891
12911
|
initFeatureFlags
|
|
12892
12912
|
};
|
|
12893
|
-
//# sourceMappingURL=chunk-
|
|
12913
|
+
//# sourceMappingURL=chunk-HOGSWOSY.js.map
|